PythonにおけるHTTP接続のためのライブラリであるurllibの基本的な使い方を解説します。
Contents
urllibモジュール
urllibは、HTTP接続に関する機能を提供するPythonの標準モジュールです。urllibは、インターネット上のデータを扱うための機能を多く備えており、URLの解析やデータのダウンロードなど、HTTP接続を簡単に行うことができます。
本記事では、HTTPリクエストを作成してやり取りする簡単な例を使用してurllibの基本的な使い方を紹介します。
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クライアントのライブラリ、フレームワークのテストなどに広く使用されています。
urllibの基本的な使い方
以降では、urllibを使用して基本的なGET/POST/PUT/DELETEのメソッドのHTTPリクエストを作成しサーバーとやり取りする方法を説明します。
リソースの取得をサーバーに要求する GET
データを取得する
サーバーからリソースの取得をする場合には、以下のようにGETメソッドのHTTPリクエストを生成して送信することでデータを取得します。
import json import urllib.request # URLを指定 url = "http://httpbin.org/get" with urllib.request.urlopen(url) as response: # レスポンスからデータを取得 data = json.loads(response.read().decode("utf-8")) print(data)
【実行結果】 {'args': {}, 'headers': {'Accept-Encoding': 'identity', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.10', 'X-Amzn-Trace-Id': 'Root=xxxxx'}, 'origin': 'xxx.xxx.xxx.xxx', 'url': 'http://httpbin.org/get'}
必要なモジュールとして、urllib.request
をインポートします。また、JSON形式で情報のやり取りをするためjson
モジュールもインポートしておきます。
データを取得するためにはURLを指定する必要があります。「http://httpbin.org」が今回通信のテストで使用するサーバーですが、当該サーバーのGETリクエストテストのエンドポイントを「http://httpbin.org/get」という形で文字列url
を作成します。
URLを開くためには、urllib.request.urlopen
の引数としてurl
を指定します。リソースが適切に開放されるようにwith
句を使用しています。response
からデータを取得する際にはread
を使用し、decode
でデコードして取り出します。レスポンスはJSON形式のため、後々扱いやすいようにjson.loads
を使ってPython辞書に変換しています。
このようにすることでWebサーバーからGETメソッドで簡単にデータを取得することが可能です。
上記では扱いやすいようにjson.loads
でPython辞書に変換していますが、レスポンスは以下のようなJSON形式になっています。
import urllib.request # URLを指定 url = "http://httpbin.org/get" with urllib.request.urlopen(url) as response: # レスポンスからデータを取得 data = response.read().decode("utf-8") print(data)
【実行結果】 { "args": {}, "headers": { "Accept-Encoding": "identity", "Host": "httpbin.org", "User-Agent": "Python-urllib/3.10", "X-Amzn-Trace-Id": "Root=xxxxx" }, "origin": "xxx.xxx.xxx.xxx", "url": "http://httpbin.org/get" }
クエリパラメータを含めてリクエストを送信する
GETリクエスト時にサーバーに対して条件や情報を指定する際には、クエリパラメータを使用します。これらのパラメータは、URLの末尾に追加され、キーと値のペアで構成されます。
クエリパラメータを含めてリクエストを送信したい場合には以下のようにします。
import json import urllib.parse import urllib.request # クエリパラメータを定義 params = {"key1": "value1", "key2": "value2"} # クエリ文字列を作成する query_string = urllib.parse.urlencode(params) # クエリパラメータを含めたURLを作成 url = f"http://httpbin.org/get?{query_string}" print(url, "\n") with urllib.request.urlopen(url) as response: # レスポンスからデータを取得 data = json.loads(response.read().decode("utf-8")) print(data)
【実行結果】 http://httpbin.org/get?key1=value1&key2=value2 {'args': {'key1': 'value1', 'key2': 'value2'}, 'headers': {'Accept-Encoding': 'identity', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.10', 'X-Amzn-Trace-Id': 'Root=xxxxx'}, 'origin': 'xxx.xxx.xxx.xxx', 'url': 'http://httpbin.org/get?key1=value1&key2=value2'}
クエリ文字列を生成するには、urllib.parse.urlencode
を使用して、引数にクエリパラメータ情報の辞書を指定します。上記例では、"key1"
と"key2"
がクエリのキーであり、"value1"
と"value2"
が対応する値となっています。
クエリパラメータを含めたURLを作成する場合には「?
」でサーバーのURLとクエリパラメータをつなげて「http://httpbin.org/get?key1=value1&key2=value2
」というようにします。
このURLを使ってGETリクエストを送ることで、データを取得することが可能です。
新しいリソースを作成する POST
サーバーに新しいリソースを作成する、つまりはデータを登録する場合には、以下のようにPOSTメソッドのHTTPリクエストを生成して送信することでデータを登録します。
import json import urllib.request # URLを指定 url = "http://httpbin.org/post" # 登録データの作成 data = {"name": "Taro", "age": 30} data = json.dumps(data).encode("utf-8") # ヘッダーの設定 headers = {"Content-Type": "application/json"} # リクエストの作成 request = urllib.request.Request( url, data=data, headers=headers, method="POST" ) with urllib.request.urlopen(request) as response: # レスポンスからデータを取得 result = json.loads(response.read().decode("utf-8")) print(result)
【実行結果】 {'args': {}, 'data': '{"name": "Taro", "age": 30}', 'files': {}, 'form': {}, 'headers': {'Accept-Encoding': 'identity', 'Content-Length': '27', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.10', 'X-Amzn-Trace-Id': 'Root=xxxxx'}, 'json': {'age': 30, 'name': 'Taro'}, 'origin': 'xxx.xxx.xxx.xxx', 'url': 'http://httpbin.org/post'}
登録したいデータの情報は、辞書で作成し、json.dumps
でJSON形式に変換したうえでUTF-8にエンコードしておきます。また、JSON形式でデータを送るのでヘッダーの"Content-Type"
に"application/json"
を設定して用意しておきます。
URLとしては、POSTリクエストテストのエンドポイントとして「http://httpbin.org/post」という形で文字列url
を作成します。
POSTでは、データをHTTPリクエストのボディに含めて送信する必要がありますが、リクエストの生成にはurllib.request.Request
を使用します。引数にurl
を指定するとともにdata
にPOSTするデータ、headers
にヘッダー、method
に"POST"
を指定します。
リクエストを送信する際には、urllib.request.urlopen
に生成したrequest
を指定します。返却値としてのresponse
から結果を取得することができます。
指定されたリソースを更新する PUT
指定されたリソースを更新する場合には、以下のようにPUTメソッドのHTTPリクエストを生成して送信することでデータを更新します。
import json import urllib.request # URLを指定 url = "http://httpbin.org/put" # 更新データの作成 data = {"name": "Miki", "age": 25} data = json.dumps(data).encode("utf-8") # ヘッダーの設定 headers = {"Content-Type": "application/json"} # リクエストの作成 request = urllib.request.Request(url, data=data, headers=headers, method="PUT") with urllib.request.urlopen(request) as response: # レスポンスからデータを取得 result = json.loads(response.read().decode("utf-8")) print(result)
【実行結果】 {'args': {}, 'data': '{"name": "Miki", "age": 25}', 'files': {}, 'form': {}, 'headers': {'Accept-Encoding': 'identity', 'Content-Length': '27', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.10', 'X-Amzn-Trace-Id': 'Root=xxxxx'}, 'json': {'age': 25, 'name': 'Miki'}, 'origin': 'xxx.xxx.xxx.xxx', 'url': 'http://httpbin.org/put'}
更新したいデータの情報は、辞書で作成し、json.dumps
でJSON形式に変換したうえでUTF-8にエンコードしておきます。また、JSON形式でデータを送るのでヘッダーの"Content-Type"
に"application/json"
を設定して用意しておきます。
URLとしては、PUTリクエストテストのエンドポイントとして「http://httpbin.org/put」という形で文字列url
を作成します。
PUTでは、データをHTTPリクエストのボディに含めて送信する必要がありますが、リクエストの生成にはurllib.request.Request
を使用します。引数にurl
を指定するとともに、data
にPUTするデータ、headers
にヘッダー、method
に"PUT"
を指定します。
リクエストを送信する際には、urllib.request.urlopen
に生成したrequest
を指定します。返却値としてのresponse
から結果を取得することができます。
指定されたリソースをサーバーから削除する DELETE
指定されたリソースをサーバーから削除する場合には、以下のようにDELETEメソッドのHTTPリクエストを生成して送信することでデータを削除します。
import json import urllib.request # URLを指定 url = "http://httpbin.org/delete" # 削除データの指定 data = {"id": 123} data = json.dumps(data).encode("utf-8") # ヘッダーの設定 headers = {"Content-Type": "application/json"} # リクエストの作成 request = urllib.request.Request( url, data=data, headers=headers, method="DELETE" ) with urllib.request.urlopen(request) as response: # レスポンスからデータを取得 result = json.loads(response.read().decode("utf-8")) print(result)
【実行結果】 {'args': {}, 'data': '{"id": 123}', 'files': {}, 'form': {}, 'headers': {'Accept-Encoding': 'identity', 'Content-Length': '11', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.10', 'X-Amzn-Trace-Id': 'Root=xxxxx'}, 'json': {'id': 123}, 'origin': 'xxx.xxx.xxx.xxx', 'url': 'http://httpbin.org/delete'}
削除したいデータは、辞書で作成し、json.dumps
でJSON形式に変換したうえでUTF-8にエンコードしておきます。データを特定するid
などを指定することが多いかと思います。また、JSON形式でデータを送るのでヘッダーの"Content-Type"
に"application/json"
を設定して用意しておきます。
URLとしては、DELETEリクエストテストのエンドポイントとして「http://httpbin.org/delete」という形で文字列url
を作成します。
リクエストの生成には、POSTやPUTと同様でurllib.request.Request
を使用します。引数にurlを指定するとともに、data
にDELETEするデータ、headers
にヘッダー、method
に"DELETE"
を指定します。
リクエストを送信する際には、urllib.request.urlopen
に生成したrequest
を指定します。返却値としてのresponse
から結果を取得することができます。
まとめ
PythonにおけるHTTP接続のためのライブラリであるurllibの基本的な使い方を解説しました。
urllibを使用して基本的なGET/POST/PUT/DELETEのメソッドのHTTPリクエストを作成しサーバーとやり取りする方法を例を使って紹介しています。
WEB関連開発においてHTTPリクエストとレスポンスの扱いについては基本的なものです。是非、使い方の基本を理解してもらえたらと思います。
上記で紹介しているソースコードについてはgithubにて公開しています。参考にしていただければと思います。