requests

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

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

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

requestsモジュール

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

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

なお、urllibはPython標準ライブラリであるため外部ライブラリに依存したくない場合には非常に有用です。urllibの使い方は「urllibの基本的な使い方」でまとめていますので興味があれば参考にしてください。

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

HTTPリクエスト

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

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

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

テスト用サービス httpbin.org

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

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

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

requestsの基本的な使い方

以降では、requestsを使用して基本的なGET/POST/PUT/DELETEのメソッドのHTTPリクエストを作成しサーバーとやり取りする方法を説明します。

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

データを取得する

サーバーからリソースの取得をする場合には、以下のようにGETメソッドのHTTPリクエストを送信します。requestsモジュールでは、GETに該当するget関数が用意されているため、簡単にデータ取得を実行できます。

import requests

# URLを指定
url = "http://httpbin.org/get"

# データを取得する
r = requests.get(url)

# 応答の生データ(バイナリ)
print(f"content:\n {r.content}")
# ステータスコード
print(f"status_code:\n {r.status_code}")
# ヘッダー
print(f"headers:\n {r.headers}")
# 応答の文字列
print(f"text:\n {r.text}")
# 応答のJSON形式
print(f"json:\n {r.json()}")
【実行結果】
content:
 b'{\n  "args": {}, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.31.0", \n    "X-Amzn-Trace-Id": "Root=xxxxx"\n  }, \n  "origin": "xxx.xxx.xxx.xxx", \n  "url": "http://httpbin.org/get"\n}\n'
status_code:
 200
headers:
 {'Date': 'Thu, 04 Jan 2024 23:06:02 GMT', 'Content-Type': 'application/json', 'Content-Length': '308', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}
text:
 {
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.31.0", 
    "X-Amzn-Trace-Id": "Root=xxxxx"
  }, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/get"
}

json:
 {'args': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.31.0', 'X-Amzn-Trace-Id': 'Root=xxxxx'}, 'origin': 'xxx.xxx.xxx.xxx', 'url': 'http://httpbin.org/get'}

get関数には、データを取得するためのURLを指定します。「http://httpbin.org」が今回通信のテストで使用するサーバーですが、当該サーバーのGETリクエストテストのエンドポイントを「http://httpbin.org/get」という形で文字列urlを作成し、get関数の引数に指定します。

Webサーバーからの応答の生データは、contentプロパティで確認できます。contentは生のバイナリデータとなっていますが、応答の文字列のためのtextプロパティが用意されているため簡単に文字列を取得できます。

また、ステータスコード(status_code)、ヘッダー(headers)といった属性にもアクセスできます。JSON形式の情報を取得したい場合は、jsonメソッドを使用することで取得することが可能です。

このようにすることでWebサーバーからGETメソッドで簡単にデータを取得することが可能です。

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

GETリクエスト時にサーバーに対して条件や情報を指定する際には、クエリパラメータを使用します。クエリパラメータを含めてリクエストを送信したい場合には以下のようにします。

import requests

# URLを指定
url = "http://httpbin.org/get"

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

r = requests.get(url, params=params)

# 応答結果の表示
print(f"text:\n {r.text}")
【実行結果】
text:
 {
  "args": {
    "key1": "value1", 
    "key2": "value2"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.31.0", 
    "X-Amzn-Trace-Id": "Root=xxxxx"
  }, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/get?key1=value1&key2=value2"
}

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

クエリパラメータを指定する場合には、get関数のparam引数で作成した辞書を指定します。

このようにすることでクエリパラメータを含めたGETリクエストにより、データを取得することが可能です。

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

サーバーに新しいリソースを作成する、つまりはデータを登録する場合には、以下のようにPOSTメソッドのHTTPリクエストを送信します。requestsモジュールでは、POSTに該当するpost関数が用意されているため、簡単にデータ登録を実行できます。

import requests

# URLを指定
url = "http://httpbin.org/post"

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

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

# 応答結果の表示
print(f"text:\n {r.text}")
【実行結果】
text:
 {
  "args": {}, 
  "data": "{\"name\": \"Taro\", \"age\": 30}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "27", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.31.0", 
    "X-Amzn-Trace-Id": "Root=xxxxx"
  }, 
  "json": {
    "age": 30, 
    "name": "Taro"
  }, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/post"
}

登録したいデータの情報は、辞書で作成しておきます。リクエスト時には、json引数で当該データを指定することで登録データをサーバーへ送信することが可能です。なお、URLとしては、POSTリクエストテストのエンドポイントとして「http://httpbin.org/post」という形で文字列urlを作成して使用します。

現代のウェブアプリケーションやAPIではJSON形式でのデータのやり取りが非常に一般的です。そのため、Pythonのrequestsライブラリを使用する際には、json引数が使用されることが多いかと思います。

ただし、HTMLフォームからのデータ送信に一般的に使用されるapplication/x-www-form-urlencoded形式としてキーと値のペアが&で区切られるような形で送信したい場合には、以下のようにdata引数を使用します。

import requests

# URLを指定
url = "http://httpbin.org/post"

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

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

# 応答結果の表示
print(f"text:\n {r.text}")
【実行結果】
text:
 {
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "age": "30", 
    "name": "Taro"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "16", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.31.0", 
    "X-Amzn-Trace-Id": "Root=xxxxx"
  }, 
  "json": null, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/post"
}

サーバー側の実装によっては、どちらの形式も受け入れることがありますが、一般的には APIのドキュメントで指定された形式に従うのがベストプラクティスです。例えば、あるAPI がJSON形式のデータのみを受け入れる場合、json引数を使用する必要があります。逆に、フォーム形式のデータを期待する古いシステムや特定のエンドポイントでは、data引数を使用します。

常に、WebサーバーまたはAPIの要件やドキュメントを確認し、適切なデータ形式でリクエストを行うことが重要です。

以降のPUT, DELETEの例ではjson引数での例となっていますが、同様にdata引数も使用できます。

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

指定されたリソースを更新する場合には、以下のようにPUTメソッドのHTTPリクエストを送信します。requestsモジュールでは、PUTに該当するput関数が用意されているため、簡単にデータ更新を実行できます。

import requests

# URLを指定
url = "http://httpbin.org/put"

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

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

# 応答結果の表示
print(f"text:\n {r.text}")
【実行結果】
text:
 {
  "args": {}, 
  "data": "{\"name\": \"Miki\", \"age\": 25}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "27", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.31.0", 
    "X-Amzn-Trace-Id": "Root=xxxxx"
  }, 
  "json": {
    "age": 25, 
    "name": "Miki"
  }, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/put"
}

更新したいデータの情報は、辞書で作成しておきます。リクエスト時には、json引数で当該データを指定することで更新データをサーバーへ送信することが可能です。なお、URLとしては、PUTリクエストテストのエンドポイントとして「http://httpbin.org/put」という形で文字列urlを作成して使用します。

POSTの例で紹介したようにWebサーバーの要件次第では、data引数を使用することも可能です。

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

指定されたリソースをサーバーから削除する場合には、以下のようにDELETEメソッドのHTTPリクエストを送信します。requestsモジュールでは、DELETEに該当するdelete関数が用意されているため、簡単にデータ削除を実行できます。

import requests

# URLを指定
url = "http://httpbin.org/delete"

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

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

# 応答結果の表示
print(f"text:\n {r.text}")
【実行結果】
text:
 {
  "args": {}, 
  "data": "{\"id\": 123}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "11", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.31.0", 
    "X-Amzn-Trace-Id": "Root=xxxxx"
  }, 
  "json": {
    "id": 123
  }, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/delete"
}

削除したいデータを指定する情報は、辞書で作成しておきます。リクエスト時には、json引数で当該データを指定することで削除するデータの情報をサーバーへ送信することが可能です。なお、URLとしては、DELETEリクエストテストのエンドポイントとして「http://httpbin.org/delete」という形で文字列urlを作成して使用します。

POSTの例で紹介したようにWebサーバーの要件次第では、data引数を使用することも可能です。

例外処理とタイムアウト設定

Webサーバーでは、サーバーからの応答がエラーステータスコード(通常400以上)が発生する場合があります。そのような場合には、例外処理を実装することが重要です。また、Webサーバーでは、リクエストが大量にくると処理が遅くなる場合があります。このような場合には、タイムアウトを設定して一定の時間を経過してもレスポンスがない場合は別の処理を実装する必要があります。

リクエストに対する例外処理を実装する場合は以下のようにします。なお、タイムアウトについては、timeout引数で設定します。※以下の例はgetを使った例ですが、postputdeleteでも同様に使用可能です。

import requests
from requests.exceptions import HTTPError, Timeout

# URLを指定
url = "http://httpbin.org/get"
# # URL 400 Bad Requestのステータスコード
# url = "http://httpbin.org/status/400"

try:
    # URLからデータを取得する (タイムアウト)
    r = requests.get(url, timeout=1)
    r.raise_for_status()
    # 応答結果の表示
    print(f"text:\n {r.text}")

except HTTPError as http_err:
    print(f"HTTPエラー発生: {http_err}")
except Timeout as timeout_err:
    print(f"タイムアウトエラー発生: {timeout_err}")
except Exception as err:
    print(f"エラー発生: {err}")

例外の確認をする場合には、リクエストを実行した後にraise_for_statusを実行します。例外に対する処理はexceptでキャッチして処理をしています。

例えば、上記例でtimeout=0.01とわざと非常に短い時間を指定するとタイムアウトエラー(Timeout)が発生します。

また、コメントアウトしてあるurl = "http://httpbin.org/status/400"のコメントアウトを削除して実行するとHTTPエラー(HTTPError)が発生します。httpbin.orgは、特定のステータスコードのエンドポイントを用意しています。上記例では400番の応答が返ってくる接続先にリクエストを送信して試しています。

実際のrequestsの適用例では、上記のように適切に例外処理やタイムアウト設定をして実装をすることが重要です。

まとめ

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

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

WEB関連開発においてHTTPリクエストとレスポンスの扱いについては基本的なものです。是非、使い方の基本を理解してもらえたらと思います。