たった数行で作るWebサーバー【Python x HTTPServer】

たった数行で作るWebサーバー【Python x HTTPServer】
たった数行で作るWebサーバー【Python x HTTPServer】

Pythonで簡易的なWebサーバーをたてられる HTTPServer の使い方・プログラミングを解説していきます(Python 3.9.4で動かします)。

Webサーバーを作る最小限のプログラム

simplest_server.py
from http.server import HTTPServer, SimpleHTTPRequestHandler

ip = "0.0.0.0"
port = 8887

httpd = HTTPServer(('', port), SimpleHTTPRequestHandler)
httpd.serve_forever()

はい、とても簡単ですね。 http://0.0.0.0:8887 へブラウザからアクセスできます。

ですが、このままだと httpd.serve_forever() で止まってしまい、それ移行のプログラムは実行されません。そこでPythonのスレッドをつかってサーバーを実行してみます。

PythonでHTTPサーバーをスレッドで動かす

こんな感じです。

server_with_thread.py
import threading
from http.server import HTTPServer, SimpleHTTPRequestHandler

html_root = "../html" # HTMLが格納されているディレクトリ

class Handler(SimpleHTTPRequestHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, directory=html_root, **kwargs)

    def log_message(self, format, *args):
        pass # ログ出力を無視

def begin_dummy_server():
    ip = "0.0.0.0"
    port = 8887

    httpd = HTTPServer(('', port), Handler)
    print('HTTPServer began -> http://{}:{}'.format(ip, port))
#    httpd.serve_forever()
    server_thread = threading.Thread(target=httpd.serve_forever) # スレッドで動かす
#    server_thread.daemon = True
    server_thread.start()

if __name__ == "__main__":

    begin_dummy_server()
    print("hoge")

次の部分でスレッド登録させてます。

py
server_thread = threading.Thread(target=httpd.serve_forever)
server_thread.start()

threadingをインポートして、対象となる関数を target に登録&スタートさせればOKです。

HTMLディレクトリを指定したい

SimpleHTTPRequestHandlerを継承したハンドラーを使うことでHTMLファイルが格納されているディレクトリを指定できます。SimpleHTTPRequestHandlerのコンストラクターで、directory=引数にディレクトリを指定します。

ログを非表示にしたい

サーバーへアクセスするとターミナルにいちいちログが出力されますが、ログを出力したくない場合は上のプログラムのとおり、 log_message をオーバーライドして pass させます。

自分のLAN IPアドレスを取得する

HTTPServer とは直接関係ありませんが、LAN内の端末からWebサーバーへアクセスしたい場合にIPアドレスを表示できると便利です。macOS上で実行するPythonでは、次のようにするとLAN内の自分のIPアドレスを取得できます。
get_my_ip.py
import socket

host_list = socket.gethostbyname_ex(socket.gethostname())
lan_address = host_list[2][1]

ただし、PCにファイアーウォールがかかってるとアクセスできませんのでご注意ください。

リクエストされたヘッダーを表示したい

リクエストヘッダーを詳細に見たい場合があります。そんな時は do_GET をオーバライドして、 logging で標準出力させます。POSTデータの場合は do_POST も同様に追加してください。

capturing_header_server.py
from http.server import HTTPServer, SimpleHTTPRequestHandler
import socket
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

host_list = socket.gethostbyname_ex(socket.gethostname())
lan_address = host_list[2][1]

ip = "0.0.0.0"
port = 8887

class Handler(SimpleHTTPRequestHandler):

    def do_GET(self):
        logger.info(self.headers)
        SimpleHTTPRequestHandler.do_GET(self)

httpd = HTTPServer(('', port), Handler)
print('HTTPServer began -> http://{}:{}'.format(lan_address, port))
httpd.serve_forever()

関連記事

最後までご覧いただきありがとうございます!

▼ 記事に関するご質問やお仕事のご相談は以下よりお願いいたします。
お問い合わせフォーム

Python学習にオススメの本をご紹介!
Pandasでデータサイエンスはじめよう!
スクレイピングにオススメの書籍

▼ Beautiful Soup4を使ったWebクローリングをはじめ、表データをpandasやOpenPyXL、matplotでデータ解析、グラフ表示などのスクレイピングのやり方が分かりやすく説明されてます。図解が多いのでPython初心者の方でも読み進められる内容となってます。