PythonにおけるHTTP接続のためのライブラリであるrequests
の基本的な使い方を解説します。
Contents
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
を使った例ですが、post
、put
、delete
でも同様に使用可能です。
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
の適用例では、上記のように適切に例外処理やタイムアウト設定をして実装をすることが重要です。
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にて公開しています。参考にしていただければと思います。