PythonでAPIを呼び出すには複数の方法があり、それぞれに特徴があります。この記事では、代表的な4つの方法(requests、urllib、PyCurl、aiohttp)を比較し、適切な方法を選択し、利用できるよう解説していきます。
1. requests モジュール
requestsモジュールは、PythonでHTTPリクエストを送信するためのライブラリです。APIの呼び出しにおいて最もよく使われます。
- 外部ライブラリ(
pip install requestsでインストールが必要) - シンプルで直感的なAPI
- 使いやすさから最も人気のあるライブラリ
- 同期処理
コード例
import requests url = "https://api.example.com/get_data" params = {'param1': 'value1', 'param2': 'value2'} headers = {'Authorization': 'Bearer my_token'} # 認証が必要な場合 try: response = requests.get(url, params=params, headers=headers, timeout=10) # タイムアウト設定 response.raise_for_status() # ステータスコードが200番台以外の場合に例外を発生 data = response.json() # レスポンスボディをJSONとして解析 # dataを使った処理... print(data) except requests.exceptions.RequestException as e: print(f"Error: {e}")
上記の例では、requests.get()メソッドを使用してAPI呼び出しを行っています。url変数にAPIのエンドポイントのURLを、params変数にAPIに送信するパラメータを、headers変数には認証トークンなどのヘッダー情報を設定しています。
response変数には、APIからのレスポンスが格納されます。status_code属性を使って、レスポンスのステータスコードを確認することができます。200番台のステータスコードであれば、正常にAPI呼び出しを行ったことがわかります。レスポンスの内容は、response.json() の中身を確認します。
実装時には、response.raise_for_status() でステータスコードが200番台以外の場合に例外を発生させ、エラーハンドリングを行います。
2. urllib モジュール
urllibモジュールは、Pythonに標準で備わっているHTTPリクエストを送信するためのライブラリです。requestsモジュールと比較すると、少し書き方が複雑になりますが、Pythonに標準で備わっているため、インストールが不要なのがメリットです。
- Python標準ライブラリ(インストール不要)
- requestsに比べて記述が冗長になりやすい
- 同期処理
コード例
import urllib.request import urllib.parse import json url = "https://api.example.com/get_data" params = {'param1': 'value1', 'param2': 'value2'} headers = {'Authorization': 'Bearer my_token'} # URLエンコードとバイト列への変換 data = urllib.parse.urlencode(params).encode('utf-8') req = urllib.request.Request(url, data=data, headers=headers, method='GET') #methodでHTTPメソッドを指定 try: with urllib.request.urlopen(req, timeout=10) as res: body = res.read().decode('utf-8') if res.status == 200: #ステータスが正常な時 data = json.loads(body) # dataを使った処理... print(data) else: print("Error: ", res.status) except urllib.error.URLError as e: print(f"Error: {e}")
上記の例では、urllib.request.urlopen()メソッドを使用してAPI呼び出しを行っています。変数paramsには、APIに送信するパラメータを格納します。headers変数には認証トークンなどのヘッダー情報を設定しています。呼び出し時には、urllib.parse.urlencode() でパラメータをURLエンコードし、.encode('utf-8') でバイト列に変換する必要があります。
Request()関数を使って、リクエストを作成し、urlopen()メソッドを使ってリクエストを送信しています。withステートメントを使って、レスポンスを受け取り、read()メソッドを使ってレスポンスボディを取得しています。最後にdecode()メソッドを使って、バイト列を文字列に変換します。
レスポンスのステータスコードを確認し、200番台のステータスコードであれば、json.loads()メソッドを使ってレスポンスボディをJSONオブジェクトに変換します。これにより、データを加工するなどの処理を行うことができます。例外は、URLErrorをキャッチしてエラーハンドリングを行います。
3. PyCurl モジュール
PyCurlモジュールは、PythonでHTTPリクエストを送信するための多機能なライブラリです。requestsやurllibよりも高速に動作することが特徴です。
- 外部ライブラリ (
pip install pycurlでインストールが必要) - libcurlのPythonバインディング
- 高速で多機能(HTTP/HTTPS、FTP、ファイルアップロードなど)
- requestsやurllibより低レベルなAPI
- 同期処理
コード例
import pycurl import io import json url = "https://api.example.com/get_data" params = {'param1': 'value1', 'param2': 'value2'} headers = ['Authorization: Bearer my_token'] # レスポンスボディを格納するバッファ buffer = io.BytesIO() c = pycurl.Curl() c.setopt(pycurl.URL, url) c.setopt(pycurl.HTTPHEADER, headers) #GETパラメータ―を設定 c.setopt(pycurl.URL, url + '?' + urllib.parse.urlencode(params)) # レスポンスボディを受け取る関数を設定 c.setopt(pycurl.WRITEFUNCTION, buffer.write) c.setopt(pycurl.TIMEOUT, 10) try: c.perform() response_code = c.getinfo(pycurl.RESPONSE_CODE) if response_code == 200: response_body = buffer.getvalue().decode('utf-8') data = json.loads(response_body) # dataを使った処理... print(data) else: print(f"Error: {response_code}") except pycurl.error as e: print(f"Error: {e}") finally: c.close()
上記の例では、pycurl.Curl()オブジェクトを作成し、setopt()メソッドを使って、API呼び出しに必要な情報を設定しています。URLでURL、HTTPHEADERでヘッダー、WRITEFUNCTIONでレスポンスボディを受け取る関数(ここではバッファに書き込む)、TIMEOUTでタイムアウト時間を設定します。
perform() でリクエストを実行し、getinfo(pycurl.RESPONSE_CODE) でステータスコードを取得します。buffer.getvalue().decode('utf-8')でレスポンスボディを取得します。エラーハンドリングはpycurl.error をキャッチすることで行い、最後にfinally ブロックで c.close() を実行し、リソースを解放します。PyCurlの利用方法については、下記でも詳しく解説しています。
4. aiohttp モジュール
aiohttpモジュールは、Python 3.5以降で利用可能な非同期HTTPクライアントおよびサーバーライブラリです。非同期I/Oを使用するため、リクエストの処理が高速に行われることが特徴です。
- 外部ライブラリ (
pip install aiohttpでインストールが必要) - 非同期処理 (async/await) に対応
- 多数のリクエストを並行して処理するのに適している
- WebSocketsもサポート
コード例
import aiohttp import asyncio import json async def fetch(session, url, params, headers): try: async with session.get(url, params=params, headers=headers, timeout=10) as response: response.raise_for_status() return await response.json() except aiohttp.ClientError as e: print(f"Error: {e}") return None async def main(): url = "https://api.example.com/get_data" params = {'param1': 'value1', 'param2': 'value2'} headers = {'Authorization': 'Bearer my_token'} async with aiohttp.ClientSession() as session: data = await fetch(session, url, params, headers) if data: # dataを使った処理... print(data) if __name__ == "__main__": asyncio.run(main())
aiohttp.ClientSession() でセッションを作成します。async with でセッションを管理します。fetch() 関数では、async with session.get(...) で非同期リクエストを送信し、timeout でタイムアウト時間を設定します。await response.json() でレスポンスボディを非同期にJSONとして解析します。response.raise_for_status()でステータスコードを確認し、aiohttp.ClientErrorをキャッチしてエラーハンドリングを行います。
まとめと使い分け
| ライブラリ | 特徴 | 向いているケース |
|---|---|---|
requests |
シンプル、使いやすい、同期処理 | 初心者、小規模なスクリプト、APIのテスト、同期処理で十分な場合 |
urllib |
Python標準ライブラリ、同期処理 | 外部ライブラリをインストールできない環境、シンプルなAPI呼び出し |
PyCurl |
高速、多機能、同期処理、libcurlベース | パフォーマンスが重要な場合、HTTP/HTTPS以外のプロトコルも扱う場合、libcurlの機能をフル活用したい場合 |
aiohttp |
非同期処理、多数のリクエストを並行処理、WebSocketsサポート | 大量のAPIリクエストを高速に処理したい場合、リアルタイム性の高いアプリケーション、WebSocketsを使いたい場合 |
基本的なAPIの呼び出しであればrequestsモジュールで十分な場合が多いです。標準ライブラリのみを使用したい場合はurllibモジュールを使用します。パフォーマンスが重要な場合や、より詳細な設定が必要な場合は、Pycurlの使用を検討します。多くのリクエストを並行して処理したい場合はaiohttpの使用を推奨します。
最後にPythonの学習に利用できるUdemy
のサイトを紹介します。ぜひ活用ください。
[PR]