requests

【Python】requestsの基本的な使い方

【Python】requestsの基本的な使い方
naoki-hn

Python における HTTP 接続のためのライブラリである requests の基本的な使い方を解説します。

requests モジュール

requests は、HTTP 接続に関する機能を提供するサードパーティ製の Python ライブラリです。requests は、インターネット上のデータを扱うための機能を多く備えており、HTTP 接続を簡単に行うことができます。

Python の標準ライブラリとしては、urllib が存在しますが、requests の方が使いやすく直感的な API を使用していることから requests の方が広く使用されており、デファクトスタンダードとみなされています。

この記事では、HTTP リクエストを作成して通信する簡単な例を使用して requests の基本的な使い方を紹介します。

urllib は Python 標準ライブラリであるため外部ライブラリに依存したくない場合に有用です。urllib の使い方は「urllibの基本的な使い方」を参考にしてください。

HTTP リクエスト

Web システムで、サーバーとクライアントがやり取りするには、クライアントがサーバーに対して特定の操作を行うための HTTP リクエストを送信します。HTTP リクエストには、いくつかのメソッドがあり、代表的なものは以下です。

メソッド概要
GETリソースの取得をサーバーに要求します。データ取得するための最も一般的に使用されるメソッドで、URL にクエリパラメータを含めてリクエストを送信し、サーバーからの応答を受け取ります。
POST新しいリソースを作成するためにサーバーにデータを送信します。例えば、フォーム送信や DB へのデータ追加に使用します。POST は、データを HTTP リクエストのボディに含めて送信します。
PUT指定されたリソースを更新するために使用します。PUT は、既存のリソースを置き換えるために使用され、HTTP リクエストのボディに更新データを含めて送信します。
DELETE指定されたリソースをサーバーから削除するために使用します。

他にも HTTP リクエストで使用できるメソッドはありますが、上記が最も代表的なものです。GET はデータ取得、POST はデータ登録、PUT はデータ更新、DELETEはデータ削除といった操作に使用されます。

テスト用サービス httpbin.org

HTTP リクエストとレスポンスをテストする

HTTP リクエストとレスポンスのテストをするためには、API を提供するサーバーが必要になります。今回は「httpbin.org」を使用します。

httpbin.org は、HTTP リクエストとレスポンスのテストに使用される人気のオンラインサービスで、開発者が HTTP リクエストを送信し、そのレスポンスを確認できるように設計されています。

様々な種類の HTTP リクエストをシミュレートしてレスポンスデータを分析することで、Web 開発者は自分のコードが予期したとおりに動作するかをテストすることが可能です。httpbin.org は、WebAPI の開発や HTTP クライアントのライブラリ、フレームワークのテストなどに広く使用されています。

Docker 環境の利用

httpbin.org は、通信したタイミングによってサービスが不安定であることがあります。httpbin.org のサービスは、Docker 環境が用意されているため、Docker 環境が手元にある場合には、以下のコマンドでローカル実行してテストする方が安定的に動作確認ができます。

docker run --rm -p 8080:80 kennethreitz/httpbin

上記コマンドを実行すると「kennethreitz/httpbin」というコンテナ環境をインストールして起動します。--rm オプションは、サービスを切ったタイミングでコンテナを削除するコマンドで、-p 8080:80 はポートの接続設定であり、ローカル環境からは 8080 ポートを使用してコンテナのサービスにアクセスできます。

なお、httpbin.org にアクセスする場合は、https で SSL 通信ができますが、ローカルの Docker 環境では SSL 通信は対応していないので http でアクセスする必要があります

以降のプログラム例では Docker 環境への接続を使用していますが、httpbin.org への URL もコメントアウトしているため、httpbin.org へ直接つないで試す場合は、コメントアウトを切り替えて試してみてください。

requests の基本的な使い方

requests を使用して基本的な GET / POST / PUT / DELETE の HTTP リクエストを作成し、サーバーとやり取りする方法を紹介します。

リソースの取得をサーバーに要求する get

データを取得する

サーバーからリソースの取得をするには、GET メソッドの HTTP リクエストを送信します。requests モジュールでは、GET に該当する get 関数が用意されています。

import requests

# httpbin へアクセスする場合は以下を有効化
# url = "https://httpbin.org/get"

# Docker 環境で実行する場合は以下を有効化
url = "http://localhost:8080/get"

# データ取得リクエスト
r = requests.get(url)

# ステータスコード
print(f"[status_code]:\n{r.status_code} {r.reason}\n")
# ヘッダー
print(f"[headers]:\n{r.headers}\n")
# 応答の生データ(バイナリ)
print(f"[content]:\n{r.content}\n")
# 応答の文字列形式
print(f"[text]:\n{r.text}\n")
# 応答のJSON形式
print(f"[json]:\n{r.json()}\n")
[status_code]:
200 OK

[headers]:
{'Server': 'gunicorn/19.9.0', 'Date': 'Wed, 17 Dec 2025 21:08:38 GMT', 'Connection': 'keep-alive', 'Content-Type': 'application/json', 'Content-Length': '274', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}

[content]:
b'{\n  "args": {}, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Connection": "keep-alive", \n    "Host": "localhost:8080", \n    "User-Agent": "python-requests/2.32.5"\n  }, \n  "origin": "xxx.xxx.xxx.xxx", \n  "url": "http://localhost:8080/get"\n}\n'

[text]:
{
  "args": {}, 
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "keep-alive",
    "Host": "localhost:8080",
    "User-Agent": "python-requests/2.32.5"
  },
  "origin": "xxx.xxx.xxx.xxx",
  "url": "http://localhost:8080/get"
}

[json]:
{'args': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'keep-alive', 'Host': 'localhost:8080', 'User-Agent': 'python-requests/2.32.5'}, 'origin': 'xxx.xxx.xxx.xxx', 'url': 'http://localhost:8080/get'}

get 関数には、データを取得するための URL を指定します。

今回は「http://localhost:8080/get」として Docker のローカル環境を指定しています。直接 httpbin へアクセスする場合は「http://httpbin.org/get」の方のコメントアウトを外して、Docker の方をコメントアウトして切り替えて試してください。(以降の例も同様です。)

HTTP 通信では、通信結果をステータスコードで確認できます。ステータスコードは status_code、内容は reason プロパティにより確認できます。サーバーからの応答のヘッダーは headers プロパティ、生データは content プロパティで取得できます。

content は生のバイナリデータとなっていますが、応答の文字列を取得するための text プロパティが用意されているため簡単に文字列として取り出せます。また、JSON 形式として取得したい場合は、json メソッドを使用します。

なお、応答が JSON でない場合には、r.json() の部分で requests.exceptions.JSONDecodeError が発生するため例外処理をするか、事前に r.headers.get("Content-Type", "")application/json が含まれるかをチェックするなどしてください。httpbin は JSON が返ってくることが分かっているため、例では簡単のため処理を省略します。

クエリパラメータを含めてリクエストを送信する

GET リクエスト時にサーバーに対して条件を指定する際には、クエリパラメータを使用します。クエリパラメータを指定するには、get 関数の params 引数で指定します。

import requests

# httpbin へアクセスする場合は以下を有効化
# url = "https://httpbin.org/get"

# Docker 環境で実行する場合は以下を有効化
url = "http://localhost:8080/get"

# クエリパラメータを定義
params = {"key1": "value1", "key2": "value2"}

# データ取得リクエスト (クエリパラメータ付き)
r = requests.get(url, params=params)

# ステータスコード
print(f"[status_code]:\n{r.status_code} {r.reason}\n")
# ヘッダー
print(f"[headers]:\n{r.headers}\n")
# 応答の生データ(バイナリ)
print(f"[content]:\n{r.content}\n")
# 応答の文字列形式
print(f"[text]:\n{r.text}\n")
# 応答のJSON形式
print(f"[json]:\n{r.json()}\n")
【実行結果】(text部分のみ表示)
[text]:
{
  "args": {
    "key1": "value1",
    "key2": "value2"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "keep-alive",
    "Host": "localhost:8080",
    "User-Agent": "python-requests/2.32.5"
  },
  "origin": "xxx.xxx.xxx.xxx",
  "url": "http://localhost:8080/get?key1=value1&key2=value2"
}

クエリパラメータを含めてリクエストを送信するには、クエリパラメータを辞書で用意します。例では、"key1""key2" がクエリのキーであり、"value1""value2" が対応する値となります。

新しいリソースを作成する post

サーバーに新しいリソースを作成するには、POST メソッドの HTTP リクエストを送信します。requests モジュールでは、POSTに該当する post 関数が用意されています。

import requests

# httpbin へアクセスする場合は以下を有効化
# url = "https://httpbin.org/post"

# Docker 環境で実行する場合は以下を有効化
url = "http://localhost:8080/post"

# 登録データの作成
payload = {"name": "Taro", "age": 30}

# データ登録リクエスト (json引数)
r = requests.post(url, json=payload)

# ステータスコード
print(f"[status_code]:\n{r.status_code} {r.reason}\n")
# ヘッダー
print(f"[headers]:\n{r.headers}\n")
# 応答の生データ(バイナリ)
print(f"[content]:\n{r.content}\n")
# 応答の文字列形式
print(f"[text]:\n{r.text}\n")
# 応答のJSON形式
print(f"[json]:\n{r.json()}\n")
【実行結果】(text部分のみ表示)
[text]:
{
  "args": {},
  "data": "{\"name\": \"Taro\", \"age\": 30}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "keep-alive",
    "Content-Length": "27",
    "Content-Type": "application/json",
    "Host": "localhost:8080",
    "User-Agent": "python-requests/2.32.5"
  },
  "json": {
    "age": 30,
    "name": "Taro"
  },
  "origin": "xxx.xxx.xxx.xxx",
  "url": "http://localhost:8080/post"
}

登録するデータは、辞書で作成します。リクエスト時には、json 引数で当該データを指定することで登録データをサーバーへ送信します。なお、URL としては、POST リクエストのエンドポイントとして「http://localhost:8080/post」を指定します。

近年のウェブアプリケーションや API では JSON 形式でのデータのやり取りが一般的です。そのため、requests ライブラリでは、json 引数が使用されることが多いです。

ただし、HTML フォームからのデータ送信に使用される application/x-www-form-urlencoded 形式としてデータを送信したい場合は、data 引数を使用します。

import requests

# httpbin へアクセスする場合は以下を有効化
# url = "https://httpbin.org/post"

# Docker 環境で実行する場合は以下を有効化
url = "http://localhost:8080/post"

# 登録データの作成
payload = {"name": "Taro", "age": 30}

# データ登録リクエスト (data引数)
r = requests.post(url, data=payload)

# ステータスコード
print(f"[status_code]:\n{r.status_code} {r.reason}\n")
# ヘッダー
print(f"[headers]:\n{r.headers}\n")
# 応答の生データ(バイナリ)
print(f"[content]:\n{r.content}\n")
# 応答の文字列形式
print(f"[text]:\n{r.text}\n")
# 応答のJSON形式
print(f"[json]:\n{r.json()}\n")
【実行結果】(text部分のみ表示)
[text]:
{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "age": "30",
    "name": "Taro"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "keep-alive",
    "Content-Length": "16",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "localhost:8080",
    "User-Agent": "python-requests/2.32.5"
  },
  "json": null,
  "origin": "xxx.xxx.xxx.xxx",
  "url": "http://localhost:8080/post"
}

サーバー側の実装によってどちらの形式も受け入れることがありますが、API のドキュメントで指定された形式に従うのがベストプラクティスです。API のドキュメントを確認し、適切なデータ形式でリクエストを行うようにしましょう。

以降の PUTDELETE の例では json 引数を使用しますが、data 引数も使用可能です。

指定されたリソースを更新する put

指定されたリソースを更新するには、PUT メソッドの HTTP リクエストを送信します。requests モジュールでは、PUT に該当する put 関数が用意されています。

import requests

# httpbin へアクセスする場合は以下を有効化
# url = "https://httpbin.org/put"

# Docker 環境で実行する場合は以下を有効化
url = "http://localhost:8080/put"

# 更新データの作成
payload = {"name": "Miki", "age": 25}

# データ更新リクエスト
r = requests.put(url, json=payload)

# ステータスコード
print(f"[status_code]:\n{r.status_code} {r.reason}\n")
# ヘッダー
print(f"[headers]:\n{r.headers}\n")
# 応答の生データ(バイナリ)
print(f"[content]:\n{r.content}\n")
# 応答の文字列形式
print(f"[text]:\n{r.text}\n")
# 応答のJSON形式
print(f"[json]:\n{r.json()}\n")
【実行結果】(text部分のみ表示)
[text]:
{
  "args": {},
  "data": "{\"name\": \"Miki\", \"age\": 25}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "keep-alive",
    "Content-Length": "27",
    "Content-Type": "application/json",
    "Host": "localhost:8080",
    "User-Agent": "python-requests/2.32.5"
  },
  "json": {
    "age": 25,
    "name": "Miki"
  },
  "origin": "xxx.xxx.xxxx.xxx",
  "url": "http://localhost:8080/put"
}

更新したいデータは、辞書で作成します。リクエスト時には、json 引数で当該データを指定することで更新データをサーバーへ送信します。なお、URL としては、PUT リクエストのエンドポイントとして「http://localhost:8080/put」を指定します。

指定されたリソースをサーバーから削除する delete

指定されたリソースをサーバーから削除するには、DELETE メソッドの HTTP リクエストを送信します。requests モジュールでは、DELETE に該当する delete 関数が用意されています。

import requests

# httpbin へアクセスする場合は以下を有効化
# url = "https://httpbin.org/delete"

# Docker 環境で実行する場合は以下を有効化
url = "http://localhost:8080/delete"

# 削除データの指定
payload = {"id": 123}

# データ削除リクエスト
r = requests.delete(url, json=payload)

# ステータスコード
print(f"[status_code]:\n{r.status_code} {r.reason}\n")
# ヘッダー
print(f"[headers]:\n{r.headers}\n")
# 応答の生データ(バイナリ)
print(f"[content]:\n{r.content}\n")
# 応答の文字列形式
print(f"[text]:\n{r.text}\n")
# 応答のJSON形式
print(f"[json]:\n{r.json()}\n")
【実行結果】(text部分のみ表示)
[text]:
{
  "args": {},
  "data": "{\"id\": 123}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "keep-alive",
    "Content-Length": "11",
    "Content-Type": "application/json",
    "Host": "localhost:8080",
    "User-Agent": "python-requests/2.32.5"
  },
  "json": {
    "id": 123
  },
  "origin": "xxx.xxx.xxx.xxx",
  "url": "http://localhost:8080/delete"
}

例では、DELETE リクエストのエンドポイントで「http://localhost:8080/delete」を指定し、削除データは json 引数で対象の id を指定しています。

ただし、URL パスとして削除対象を指定する API や、DELETE でボディを受け付けないサーバーもありえます。API の仕様をよく確認して使用してください。

汎用的にリクエストを送信する request

上記の例では、GET / POST / PUT / DELETE それぞれに対応する関数を使用してきましたが、より汎用的な関数として request 関数があります。

import requests

# ===== URLを指定 (GET)
# url = "http://httpbin.org/get"
url = "http://localhost:8080/get"

# データ取得リクエスト
r = requests.request("GET", url)
# ステータスコード
print(f"[GET] {r.status_code} {r.reason}")

# ===== URLを指定 (POST)
# url = "http://httpbin.org/post"
url = "http://localhost:8080/post"

# 登録データの作成
payload = {"name": "Taro", "age": 30}
# データ登録リクエスト
r = requests.request("POST", url, json=payload)
# ステータスコード
print(f"[POST] {r.status_code} {r.reason}")

# ===== URLを指定 (PUT)
# url = "http://httpbin.org/put"
url = "http://localhost:8080/put"

# 更新データの作成
payload = {"name": "Miki", "age": 25}
# データ更新リクエスト
r = requests.request("PUT", url, json=payload)
# ステータスコード
print(f"[PUT] {r.status_code} {r.reason}")

# ===== URLを指定 (DELETE)
# url = "http://httpbin.org/delete"
url = "http://localhost:8080/delete"

# 削除データの指定
payload = {"id": 123}
# データ削除リクエスト
r = requests.request("DELETE", url, json=payload)
# ステータスコード
print(f"[DELETE] {r.status_code} {r.reason}")
【実行結果】
[GET] 200 OK
[POST] 200 OK
[PUT] 200 OK
[DELETE] 200 OK

request 関数には、"GET" などの HTTP メソッドを文字列で指定し、その後で urlparams などを指定します。get 関数などの個別の関数は、内部では以下のように request 関数を呼び出しています。

def get(url, params=None, **kwargs):
    r"""Sends a GET request.

    :param url: URL for the new :class:`Request` object.
    :param params: (optional) Dictionary, list of tuples or bytes to send
        in the query string for the :class:`Request`.
    :param \*\*kwargs: Optional arguments that ``request`` takes.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
    """

    return request("get", url, params=params, **kwargs)

例では、ステータスコードのみ表示していますが、各種情報へのアクセス方法はこれまで紹介した方法と同様です。

個別の関数と request 関数のどちらを使うべきかというところに悩むかもしれませんが、可読性を考慮するのであれば get 関数などの個別の関数を呼び出す方がよいと思います。一方で、汎用的な HTTP アクセス用のクラスを作る場合などでは、request 関数を使うことがおすすめです。

エラーステータスコードの場合に例外を発生させる

Web サービスでは、サーバーからの応答がエラーステータスコード(通常 400 以上)となる場合があります。そのような場合のために、例外処理の実装が重要です。

リクエストの際にエラーステータスコードの場合に例外を発生させるには、raise_for_status を使用します。

import requests
from requests.exceptions import HTTPError, RequestException

# httpbin へアクセスする場合は以下を有効化
# url = "https://httpbin.org/status/400"

# Docker 環境で実行する場合は以下を有効化
url = "http://localhost:8080/status/400"

try:
    # URLからデータを取得する
    r = requests.get(url)
    # HTTPエラーが発生した場合、例外を発生させる
    r.raise_for_status()

    # 応答結果の表示
    print(f"text:\n {r.text}")

except HTTPError as e:
    print(f"HTTPエラー: {e}")
except RequestException as e:
    print(f"通信エラー: {e}")
【実行結果】
HTTPエラー: 400 Client Error: BAD REQUEST for url: http://localhost:8080/status/400

httpbin.org では、特定のステータスコードのエンドポイントが用意されています。例では 400 番の応答が返ってくる接続先にリクエストを送信しています。

raise_for_status は、4xx5xx のエラーステータスコードの場合に HTTPError の例外を発生させます。例外は except でキャッチして処理します。

なお、例外クラスは他にもありますが RequestExceptionrequests が送出する例外の基底クラスであるため、最後にその他の通信の例外をまとめて捕捉しています。

タイムアウトを設定する

Web サービスでは、リクエストが大量にくると処理が遅くなる場合があります。このような場合のために、タイムアウトを設定して一定時間を経過してもレスポンスがない場合は、タイムアウトとして処理をします。

タイムアウトの指定は、timeout 引数で設定します。

import requests
from requests.exceptions import Timeout, RequestException

# httpbin へアクセスする場合は以下を有効化
# url = "https://httpbin.org/get"

# Docker 環境で実行する場合は以下を有効化
url = "http://localhost:8080/get"

try:
    # URLからデータを取得する
    # タプルで指定する場合は (接続タイムアウト, 読み取りタイムアウト)を指定
    # timeout=5.0 のようにすると、接続・読み取りともに5秒のタイムアウト設定となる
    r = requests.get(url, timeout=(3.0, 5.0))

    # 応答結果の表示
    print(f"text:\n {r.text}")

except Timeout as e:
    print(f"タイムアウトエラー: {e}")
except RequestException as e:
    print(f"通信エラー: {e}")
【実行結果】
タイムアウトエラー: HTTPConnectionPool(host='localhost', port=8080): Read timed out. (read timeout=1e-06)

タイムアウトが発生した場合は、Timeout の例外が発生します。timeout はタプルで (接続タイムアウト, 読み取りタイムアウト) という形式で秒単位で指定できます。また、「timeout=5.0」のように指定すると、接続・読み取りともに同じ値でのタイムアウト設定となります。

例では、タイムアウト設定を非常に小さな値にしてみるとタイムアウトの発生を確認できます。なお、Docker 環境の場合はローカル環境で非常に応答が速いため、非常に小さい値に設定しないとタイムアウトエラーが発生しない場合があります。

requests の利用例

requests モジュールを使用すると公開されている便利な API を使うこともできて非常に便利です。利用例を紹介します。

OpenWeather の API

OpenWeather は、グローバルな気象データサービスを提供する会社です。OpenWeather サービスは、世界中の天気予報、歴史的気象データ、気象条件のリアルタイムデータ、衛星画像、気象アラート および その他の気象関連情報を提供します。

requests モジュールを使って OpenWeather の API を使う方法については「OpenWeatherのAPI使用方法」で紹介しているので参考にしてください。

まとめ

Python における HTTP 接続のためのライブラリである requests の基本的な使い方を解説しました。

requests を使用して基本的な GET / POST / PUT / DELETE メソッドの HTTP リクエストを作成しサーバーとやり取りする方法を例を使って紹介しました。また、HTTP エラーやタイムアウトに関する例外処理の方法についても説明しています。

Web 開発において HTTP リクエストとレスポンスの扱いについては基本的なものです。使い方の基本をしっかり理解してもらえたらと思います。

ソースコード

上記で紹介しているソースコードについては GitHub にて公開しています。参考にしていただければと思います。

あわせて読みたい
【Python Tech】プログラミングガイド
【Python Tech】プログラミングガイド

ABOUT ME
ホッシー
ホッシー
システムエンジニア
はじめまして。当サイトをご覧いただきありがとうございます。 私は製造業のメーカーで、DX推進や業務システムの設計・開発・導入を担当しているシステムエンジニアです。これまでに転職も経験しており、以前は大手電機メーカーでシステム開発に携わっていました。

プログラミング言語はこれまでC、C++、JAVA等を扱ってきましたが、最近では特に機械学習等の分析でも注目されているPythonについてとても興味をもって取り組んでいます。これまでの経験をもとに、Pythonに興味を持つ方のお役に立てるような情報を発信していきたいと思います。どうぞよろしくお願いいたします。

※キャラクターデザイン:ゼイルン様
記事URLをコピーしました