閉じる

【Python】HTTPのGETとPOSTの違いを完全図解|初心者がまず読む記事

PythonでWebサービスやAPIと連携するには、HTTPの理解が欠かせません。

本記事ではHTTPのGETとPOSTの違いを、Pythonのrequestsライブラリを使いながら、図解たっぷりで丁寧に解説します。

初心者でも「なぜそう書くのか」が腑に落ちるように、URLとボディの違い、セキュリティの注意点、実践的なサンプルコードまで一気に学んでいきます。

PythonでHTTP通信を学ぶメリット

Python初心者がHTTPを理解すべき理由

Pythonを学び始めた方にとって、文法や基本的なデータ構造に続いて理解しておきたいのがHTTP通信です。

Pythonは次のような場面で頻繁にHTTPを使います。

  • Web APIと連携してデータを取得する
  • Webサイトから情報を取得するスクレイピングツールを作る
  • DjangoやFastAPIなどでWebアプリケーションを開発する

これらはどれも、裏側ではHTTPリクエストとHTTPレスポンスが行き交っています。

PythonのコードからAPIを呼び出すとき、単にサンプルをコピーするのではなく、「なぜここでGETなのか」「なぜここはPOSTなのか」が理解できると、トラブルにも強くなります。

特にGETとPOSTの違いは、HTTPを学ぶうえでの最初のハードルであり、かつ最重要ポイントです。

ここをきちんと押さえることで、今後のPythonでのWeb開発やデータ取得の理解がぐっと楽になります。

Web APIとPythonの基本的な関係

Web APIとは、インターネット越しにデータや機能を提供してくれる仕組みです。

PythonからWeb APIを呼び出すとき、一般的にはrequestsライブラリを使ってHTTPリクエストを送信します。

このとき、Pythonのコードは次のような情報をAPIサーバに送ります。

  • メソッド(GET・POSTなど)
  • URL(どのAPIを呼ぶか)
  • ヘッダ(認証情報や送信データの形式など)
  • ボディ(必要に応じて送信するデータ)

そして、サーバからはステータスコードやJSON形式のデータなどが返ってきます。

この「メソッド」にあたる部分で最もよく使われるのがGETとPOSTであり、両者の違いを理解することが、API連携の第一歩になります。

HTTPメソッドの基本

HTTPとは何かをPython目線で整理

HTTP(HyperText Transfer Protocol)は、Webでデータをやり取りするためのルールです。

ブラウザもPythonスクリプトも、このHTTPという共通ルールに従ってサーバと会話しています。

Pythonから見たHTTPのポイントは次の通りです。

  • PythonはHTTPを「リクエストを送るための手段」として使う
  • HTTPリクエストにはメソッド・URL・ヘッダ・ボディなどが含まれる
  • サーバはそれに対してステータスコード・ヘッダ・ボディを返す

Pythonのrequestsライブラリは、このHTTPの細かい部分を隠して、シンプルなメソッド(cst-code>getやpost)として提供してくれます。

ですから、HTTPの概念を押さえたうえでrequestsを使うと、「黒魔術」ではなく「意味の分かるコード」になっていきます。

GETとPOSTの位置づけと役割

HTTPには複数のメソッドがありますが、PythonでAPIを触るとき最も頻繁に登場するのがGETとPOSTです。

簡単に言うと、役割は次のように整理できます。

  • GET: データを取得するためのメソッド
  • POST: データを送信して新しいリソースを作ったり、処理を依頼するメソッド

他にもPUTやDELETEなどがありますが、まずはGETとPOSTさえ区別できれば、多くのAPIを扱えるようになります。

実際のAPIドキュメントでも「このエンドポイントはGETで呼び出してください」「このエンドポイントはPOSTです」と書かれているので、メソッドを間違えると、そもそもAPIが動かないということもよくあります。

GETメソッドとは

GETの基本的な仕組み

GETメソッドは、サーバから情報を取り出すために使うメソッドです。

特徴を整理すると、次のようになります。

  • 主な用途は「読み取り」「検索」
  • URLにクエリパラメータとして条件を付ける
  • 一般的にサーバ側の状態を変更しない(副作用がないことが期待される)

たとえば、次のようなURLを想像してみてください。

  • https://api.example.com/users?name=taro&limit=10

このURLでは、「ユーザ一覧のうち、name=taroに一致するものをlimit=10件まで返してほしい」という意味になります。

GETでは、このように取得条件をURLの一部として書くのが基本的な考え方です。

Python(requests)でのGETリクエスト例

PythonでGETリクエストを送るには、requests.getを使います。

見やすさのため、公共API(例: httpbin)を使ったシンプルな例を示します。

Python
import requests

# ベースとなるURL
url = "https://httpbin.org/get"

# クエリパラメータを辞書で指定
params = {
    "name": "taro",
    "limit": 10
}

# GETリクエストを送信
response = requests.get(url, params=params)

# ステータスコードを確認
print("ステータスコード:", response.status_code)

# レスポンスボディ(JSON)を表示
print("レスポンスJSON:")
print(response.json())
実行結果
ステータスコード: 200
レスポンスJSON:
{'args': {'limit': '10', 'name': 'taro'}, 'headers': {...}, 'url': 'https://httpbin.org/get?name=taro&limit=10', ...}

この例では、params引数に辞書を渡すと、自動的にURLのクエリパラメータとして付与されます。

コード中でURL文字列を自分で結合する必要がないため、安全で読みやすい書き方になります。

クエリパラメータの使い方と注意点

GETで条件を指定する際に使うのがクエリパラメータです。

Pythonではparams引数に辞書で指定するのが基本ですが、使う際にはいくつか注意点があります。

まず、URLには実質的な長さ制限があるという点です。

ブラウザやサーバによって許容される最大長は異なりますが、非常に長いクエリパラメータを付けるとエラーになることがあります。

そのため、大量のデータや長文テキストを送る用途にはGETは向きません。

また、クエリパラメータはURLにそのまま表示されるため、ログやブラウザの履歴、ブックマークなどに残りやすいです。

パスワードやクレジットカード番号など、機密性の高い情報をクエリパラメータに含めるのは避けなければなりません。

これについては後ほどセキュリティの章で詳しく説明します。

POSTメソッドとは

POSTの基本的な仕組み

POSTメソッドは、サーバにデータを送信し、何らかの処理やリソース作成を依頼するメソッドです。

特徴としては次のようなポイントがあります。

  • 主な用途は「新規作成」「処理の実行」
  • URLではなく、ボディにデータを入れて送信する
  • サーバ側の状態が変化する(副作用があることが多い)

たとえばユーザ登録フォームを考えると、nameemailなどの情報を送って、新しいユーザを作ってもらうことになります。

このような「何かを登録する・変更する」場面では、GETではなくPOSTが使われます。

Python(requests)でのPOSTリクエスト例

PythonでPOSTリクエストを送るには、requests.postを使います。

フォーム送信に近い形(アプリケーション/x-www-form-urlencoded)のサンプルを示します。

Python
import requests

url = "https://httpbin.org/post"

# 送信するデータ(フォーム形式)
data = {
    "name": "taro",
    "age": 20
}

# POSTリクエストを送信
response = requests.post(url, data=data)

print("ステータスコード:", response.status_code)
print("レスポンスJSON:")
print(response.json())
実行結果
ステータスコード: 200
レスポンスJSON:
{'form': {'age': '20', 'name': 'taro'}, 'json': None, 'url': 'https://httpbin.org/post', ...}

ここで渡しているdata引数は、HTTPリクエストのボディ部分として送信されます。

GETの場合はparamsでしたが、POSTではdatajsonといった引数を使い分けます。

ボディにデータを送る意味と用途

POSTではボディにデータを入れて送ると説明しましたが、これは次のような意味を持ちます。

まず、ボディはURLよりも自由度が高く、データ量の制約も比較的緩やかです。

そのため、長文テキスト、複数フィールドを持つフォームデータ、JSON形式の複雑なオブジェクトなどを送るのに適しています。

さらに、URLに比べてボディは直接目に触れにくいため、ログや履歴への露出も限定的になります(もちろん、サーバ側やプロキシでログされる可能性はありますが、URLよりはコントロールしやすいです)。

具体的な用途としては次のようなものがあります。

  • ユーザ登録やログインフォームの送信
  • 注文情報や決済情報の送信
  • 検索条件が非常に複雑な場合の検索リクエスト
  • JSON APIに対して、複雑なパラメータを渡す処理

このように、「何かを依頼する」「状態を変える」処理にはPOSTというイメージを持つと覚えやすくなります。

GETとPOSTの違いを図解で理解

URLとボディの違いを図で比較

GETとPOSTの実際の違いは、「どこにデータを載せるか」に集約されます。

表形式で整理するとイメージしやすくなります。

項目GETPOST
主な用途データ取得データ送信・作成・処理
パラメータの場所URLのクエリパラメータリクエストボディ
ブラウザの操作ブックマークしやすいブックマークには向かない
一般的な期待状態を変えない(参照のみ)状態が変わる(更新・作成など)

同じ内容のパラメータでも、GETではURLに、POSTではボディに載るという違いを押さえておくと、APIドキュメントを読むときも混乱しにくくなります。

可視性(見える情報)とセキュリティの違い

GETとPOSTの大きな違いとして、どこまで情報が「見える」かという点があります。

GETのクエリパラメータはURLに含まれるため、次の場所に残りやすいです。

  • ブラウザのアドレスバー
  • ブラウザの履歴
  • ブックマーク
  • Webサーバやプロキシのアクセスログ

一方で、POSTのボディはアドレスバーには表示されません。

開発者ツールを開けば確認できますし、サーバ側のログにも残ることはありますが、URLほどあちこちにコピーされにくいという違いがあります。

ただし、「POSTだから安全」というわけではありません

後述するように、HTTPSで暗号化されていない場合、GETもPOSTも通信経路上では丸見えです。

この点を誤解していると危険ですので、「可視性」と「暗号化」は分けて考える必要があります。

キャッシュやブックマークの挙動の違い

ブラウザやプロキシは、一般的にGETリクエストの結果をキャッシュしやすいという特徴があります。

同じURLに対して再度アクセスすると、場合によってはサーバに問い合わせずにキャッシュから結果を返します。

一方、POSTリクエストはサーバ側の状態を変える可能性があるため、ブラウザは安易にキャッシュしません。

フォーム送信後にページを再読み込みすると、「フォームの再送信になりますがよろしいですか?」といった警告が出るのはこのためです。

この違いは、PythonでAPIを叩くときにも影響します。

例えば、同じ条件で何度も結果を取得したいだけならGETを使うのが自然ですし、毎回新しいデータを登録する処理ならPOSTを使うべきです。

GETとPOSTの使い分け方

いつGETを使うべきか

GETを使うのは、「データを読むだけで、サーバ側の状態を変えない処理」が基本です。

Pythonでの具体的な場面としては、次のようなものが挙げられます。

  • 商品一覧を取得するAPI呼び出し
  • ニュース記事の一覧・詳細を取得する
  • 天気情報や株価などの最新データを取得する
  • 画像やPDFファイルなどの静的ファイルをダウンロードする

また、URLで結果を共有したい場合もGETが向いています。

例えば、検索条件をURLに含めておけば、そのURLを他人に送ったりブックマークしたりするだけで、同じ検索結果を再現できます。

いつPOSTを使うべきか

POSTを使うのは、「サーバに何かを依頼し、その結果としてサーバ側の状態が変わる処理」です。

Pythonでの典型的なケースは次の通りです。

  • ユーザ登録やログイン情報の送信
  • 商品の注文や予約データの送信
  • 問い合わせフォームの送信
  • 機械学習APIに画像やテキストを送り、分類・分析結果をもらう

クライアントから見れば「データを送って結果をもらう」という点ではGETと似ているように見えますが、サーバ側に新しい記録が追加されたり、既存のデータが変化する場合はPOSTを選ぶべきです。

よくある誤用とアンチパターン

実務で見かけるよくある誤用も押さえておきます。

1つ目は、副作用のある処理にGETを使ってしまうことです。

例えば、次のようなURLを想像してください。

  • https://example.com/delete_user?id=123

これをGETで実行すると、「URLを踏むだけでユーザが削除される」という危険な状態になります。

検索エンジンのクローラがアクセスしただけでデータが消える、といった事故にもつながりかねません。

このような処理にはPOST(あるいはDELETE)を使うのが望ましいです。

2つ目は、パスワードやトークンをクエリパラメータに載せてしまうことです。

URLに含めると、ログや履歴に残りやすく、情報漏えいのリスクが高くなります。

認証情報や機密データは、ヘッダ(例: Authorizationヘッダ)やボディに載せるのが適切です。

セキュリティとGET・POST

パスワード送信にGETを使ってはいけない理由

パスワードやトークンなどの機密情報をGETで送ると、次のような問題が発生します。

  • URLとしてブラウザ履歴に保存される
  • ブックマークされる可能性がある
  • Webサーバやプロキシのアクセスログにそのまま残る
  • 画面共有やスクリーンショットで簡単に漏えいする

「URLはあちこちにコピーされやすい」という特性があるため、そこに秘密情報を載せてはいけません。

パスワード送信には必ずPOSTを利用し、さらにHTTPSで暗号化することが必須です。

HTTPSとGET・POSTの関係

ここで誤解しがちなポイントを整理します。

GETだから危険でPOSTだから安全、ということはありません

安全性を左右するのは、HTTPかHTTPSかという点です。

  • HTTP(GET/POST問わず): 通信内容が暗号化されず、第三者に丸見え
  • HTTPS(GET/POST問わず): 通信内容が暗号化され、途中で盗み見られても中身は読めない

つまり、パスワードをPOSTで送っていても、HTTPのままだと盗聴可能です。

一方、HTTPSであれば、GETのクエリパラメータも含めて丸ごと暗号化されます。

ただし、HTTPSでもURLの一部はブラウザ履歴やサーバログには残るので、クエリパラメータに機密情報を入れないという原則は変わりません。

ログ・履歴に残る情報への注意点

セキュリティを考えるうえで重要なのは、どこに情報が残りうるかを理解しておくことです。

GETのクエリパラメータは、次の場所に残りやすいです。

  • ブラウザ履歴・ブックマーク
  • Webサーバのアクセスログ
  • 途中のプロキシサーバのログ

POSTのボディは通常、ブラウザ履歴やブックマークには残りませんが、サーバ側でアプリケーションログとして記録される場合があります。

また、デバッグ用にPython側でログ出力してしまったりすると、ローカルマシン上に平文のパスワードが残ることもあります。

そのため、PythonでHTTP通信を書くときにも、ログに何を出力するかには注意が必要です。

デバッグ中にprint(response.request.body)のようなコードを追加する場合でも、本番環境に残さないよう気を付けましょう。

Pythonでの実践パターン集

PythonでAPIを呼び出すGETの具体例

ここからは、Pythonでの具体的なコードパターンを見ていきます。

まずは、典型的なGETの例として、架空の天気APIを呼び出すコード例を示します。

Python
import requests

# 架空の天気APIのエンドポイント
BASE_URL = "https://api.example.com/weather"

def get_weather(city: str, api_key: str) -> dict:
    """
    指定した都市の天気情報を取得する関数です。
    GETメソッドを使い、都市名とAPIキーをクエリパラメータとして送信します。
    """
    params = {
        "city": city,
        "apikey": api_key,
        "units": "metric"  # 摂氏を指定
    }

    # GETリクエストの送信
    response = requests.get(BASE_URL, params=params)
    response.raise_for_status()  # エラーがあれば例外を発生させる

    return response.json()

if __name__ == "__main__":
    # 実際にはAPIキーは環境変数などから読むのが望ましいです
    api_key = "YOUR_API_KEY"
    city = "Tokyo"

    weather = get_weather(city, api_key)
    print(f"{city}の現在の天気情報:")
    print(weather)
実行結果
Tokyoの現在の天気情報:
{'temp': 23.4, 'humidity': 60, 'description': 'Cloudy', ...}

このパターンでは、paramsに条件やAPIキーをまとめて指定し、読み取り専用の情報取得としてGETを使っています。

Pythonでフォーム送信を再現するPOSTの具体例

次に、問い合わせフォームの送信をPythonから再現するPOSTの例を見てみましょう。

Python
import requests

CONTACT_URL = "https://example.com/api/contact"

def send_contact(name: str, email: str, message: str) -> bool:
    """
    問い合わせフォームを送信する関数です。
    ブラウザからのフォーム送信と同様に、POSTメソッドでデータを送ります。
    """
    data = {
        "name": name,
        "email": email,
        "message": message
    }

    # フォームデータとして送信
    response = requests.post(CONTACT_URL, data=data)

    # ステータスコード200台であれば成功とみなす
    return response.ok

if __name__ == "__main__":
    result = send_contact(
        name="山田太郎",
        email="taro@example.com",
        message="資料請求をお願いします。"
    )
    if result:
        print("問い合わせを送信しました。")
    else:
        print("問い合わせの送信に失敗しました。")
実行結果
問い合わせを送信しました。

この例では、data引数を使って、フォームと同じ形式でデータを送信しています。

サーバ側が想定する形式に合わせて、フォームデータかJSONかを選ぶことが重要です。

JSONとフォームデータの違いと送信方法

POSTでボディを送るとき、Pythonのrequestsでは主に次の2通りの送り方があります。

1つはフォームデータ(application/x-www-form-urlencoded)として送る方法で、先ほどのdata=...がそれに当たります。

ブラウザのフォーム送信と互換性があり、古いAPIやWebアプリでよく使われます。

もう1つはJSON(application/json)として送る方法で、json=...引数を使います。

モダンなWeb APIでは、こちらが推奨されることが多いです。

実際のコード例を比較してみます。

Python
import requests

url = "https://httpbin.org/post"

# フォームデータとして送る場合
form_data = {
    "name": "taro",
    "age": 20
}
response_form = requests.post(url, data=form_data)

# JSONとして送る場合
json_data = {
    "name": "taro",
    "age": 20
}
response_json = requests.post(url, json=json_data)

print("フォームデータとして送信した場合のレスポンス:")
print(response_form.json()["form"])   # 'form'キーにデータが入る

print("JSONとして送信した場合のレスポンス:")
print(response_json.json()["json"])   # 'json'キーにデータが入る
実行結果
フォームデータとして送信した場合のレスポンス:
{'age': '20', 'name': 'taro'}
JSONとして送信した場合のレスポンス:
{'age': 20, 'name': 'taro'}

このように、送信形式によって、サーバ側の受け取り方やパース方法が変わってきます。

APIドキュメントにContent-Type: application/jsonと書かれている場合はjson=...を、そうでなければdata=...を使う、というのが1つの目安です。

まとめ

GETとPOSTはどちらもHTTPメソッドですが、「何の目的で」「どこにデータを載せるか」が明確に異なります。

Pythonのrequestsでは、取得専用の処理にはget(..., params=...)を、データ送信や処理依頼にはpost(..., data=... / json=...)を使い分けることが基本です。

また、セキュリティの観点からは、機密情報をクエリパラメータに入れないこと、HTTPSを必ず利用することが重要です。

この記事の図解とサンプルコードを参考にしながら、自分でも小さなスクリプトを書いて試してみると、GETとPOSTの違いがより実感として理解できるようになります。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!