3. GETリクエストの詳細

更新日: 2026.02.24

サーバへ送られる文字列

クライアントが GETリクエストする時、サーバに送られる文字列は 「リクエストライン」と「リクエストヘッダ」の2つです。

GET /index.html?name=taro HTTP/1.1 Host: localhost:8080 Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,... Accept-Encoding: gzip, deflate, br Accept-Language: ja,en-US;q=0.9,en;q=0.8 (空行)

リクエストライン(1行目)

  • メソッド (GET): リソースの取得を要求
  • リクエストターゲット (/index.html?name=taro):
    • /index.html: サーバ上のファイルの場所
    • ?name=taro: クエリパラメータ。サーバ側のプログラムに渡す引数
  • HTTP/1.1: 使用するHTTPプロトコルのバージョンです。

リクエストヘッダ(2行目以降)

  • Host: アクセス先のドメイン名(例: example.com)。
  • User-Agent: 使用しているブラウザやOSの情報。
  • Accept: ブラウザが理解できるファイル形式(text/html など)。
  • Accept-Language: 希望する言語(ja など)。

例えばURLが http://localhost:8080/search/result.html?q=python の場合

  • リクエストターゲット: /search/result.html?q=python
  • パス部分: /search/result.html
  • クエリ部分: ?q=python ー> キーワード "q" の情報は”python”という意味

このクエリのデータを元にサーバはクライアントの要求に対応して行きます

リクエストラインからのデータの取り出し

Pythonにはリクエストラインからデータを取り出す為の関数が幾つか用意されています。

  • self.path:リクエストラインからデータを取り出す
    • 主なリクエストラインと self.pathの例
    • リクエストライン内容self.path の値
      http://localhost:8080/サーバアクセス/
      http://localhost:8080/images/cat.png画像データ要求/images/cat.png
      http://localhost:8080/search?q=pythonデータ送信 q=python/search?q=python
  • urlparse(self.path):文字列が以下の6つの要素を持つオブジェクトに変換される
      属性名内容
      pathパス/search
      queryパラメータ部分q=python
      scheme通信プロトコルhttp
      netlocネットワークの場所localhost:8080
      paramsセミコロンで区切られたパラメータ通常は空
      fragmentページ内のアンカーsection1 など
  • parse_qs(parsed.query):「クエリ文字列」を「辞書形式」に変換する
    • "q=python" -> {'q': ['python']} に変換される。
  • a=next(iter(params))
    • iter(params):辞書を「反復可能な状態(イテレータ)」に変換。
      • 辞書をイテレータにすると、その「キー(Key)」を順番に取り出せる。
    • next(...):
      • イテレータから次の要素を1つ取り出す。
      • 一度取り出すと、その要素は「消費」された状態になる。
    • なぜこの形式を使うのか
      • クエリが辞書型に変換された時サーバは辞書の最初のキーが分からない
      • この方法だとキーが分からなくても要素を取り出せる。

動作確認

動作確認の為、index.html、hello.css、hello.pyを用意。これを同じフォルダに保存します。

index.html

<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="stylesheet" href="./hello.css"> <title>http-server 1.0</title> </head> <body> <div class="t_font b_frame"> <center> <p>HTTP-Server 1.0</p> <form method='get'> <button type='submit' name='button' value='a' >On</button> </form> </center> </div> </body> </html>
hello.css
@charset "UTF-8"; .t_font { font-size: 32px; font-weight: bold; font-style: italic; color: #ff0000; } .b_frame { width: 400px; background: #363636; padding: 15px; border-radius: 10px; margin-top: -30px; margin-right: 10px; } button { display: block; margin: 10px; line-height: 50px; cursor: pointer; color: #fff; background: #228b22; border-radius: 10px; font-size: 24px; width: 120px; }
hello.py
hello.py python
from http.server import HTTPServer, SimpleHTTPRequestHandler from urllib.parse import urlparse,parse_qs class MyHandler(SimpleHTTPRequestHandler): def do_GET(self): if self.path == "/?button=a" : parsed = urlparse(self.path) params = parse_qs(parsed.query) a=next(iter(params)) #----- Button -------------- if a == "button": print("ボタンが押されました") else : print("無効はデータ") f = open("index.html",'rb') self.send_response(200) self.send_header('Content-type', "text/html") self.end_headers() self.wfile.write(f.read()) f.close() else : super().do_GET() host = '' port = 8080 httpd = HTTPServer((host, port), MyHandler) print('serving at port', port) httpd.serve_forever()

hello.pyを実行しブラウザにアクセスすると下記が表示されます。

Control Panel

"hello.py"の説明

  • クライアントが "raspberrypi.local:8080" とサーバにアクセスすると self.path に ”/” が入ります
    • 8行目のIF分でFailとなり27行目に飛ぶ
    • super().do_GET()により”index.html”が送信される。
  • index.html内のCSSファイル要求時はself.path は”/hello.css"となる
    • これも8行目の判別で27行に飛ぶ
    • super().do_GET()に処理される。
  • ボタンを押した場合、self.path は”/?button=a"となる
    • HTMLのコード”name" が”?”の次に。”value"が”=”の次に入ります。
    • 8行目のIF分でTrue。10,11,12行と進みデータを取得
    • 取得したデータが”button"なので"ボタンが押されました"を表示
    • その後、クライアントにリクエストを受信した事を返答
    • index.htmlを送信して処理終了

次回は

GETリクエストの仕組みが分かって来ました。次回はサーバのHPを 自作製品のコントロール画面に使用する例について説明したいと思います。

SINCE 2026