2017/08/24更新

[Python] requestsモジュールを使って楽々HTTP(s)通信を行う

このエントリーをはてなブックマークに追加            

こんにちは、@yoheiMuneです。
Pythonのお仕事では必ずと言っていいほどお世話になるrequestsモジュールについて、使い方をブログに書きたいと思います。
画像

目次




requestsモジュールとは

requestsモジュールは、HTTP(s)通信を行うためのライブラリで、標準であるurllibよりもかなり使い勝手良く、HTTPリクエストを発行することができます。かなり便利なので、僕はPythonの案件ではよく利用しています。



インストール

インストールは、pipコマンドからインストールすることができます。
$ pip install requests



requestsモジュールの基本的な使い方

例えばGet通信を行う場合には、以下のように使うことができます。
# requestsモジュールの読み込み
import requests

# Basic認証(user/pass)でGET通信を行う例
r = requests.get('https://api.github.com/user', auth=('user', 'pass'))

# レスポンスのステータスコードの確認
print(r.status_code)  # 200

# レスポンスヘッダーの確認
print(r.headers['content-type']) # 'application/json; charset=utf8'

# レスポンスのエンコードを確認
print(r.encoding) #  'utf-8'

# レスポンス内容をテキストで取得
print(r.text)  # '{"type":"User"...'

# レスポンス内容をJSONで取得
print(r.json()) # {'private_gists': 419, 'total_private_repos': 77, ...}

# レスポンス内容をバイナリーで取得
print(r.content) # b'{"type":"User"...'
このように、HTTP通信で必要となる要素を簡単に設定/取得することができるので、とても便利に使うことができます。

以降では、もう少し詳細にユースケース別にみてみたいと思います。



ユースケース別のrequestsの使い方

ここからは、ユースケース別にrequestsモジュールの使い方を見てみたいと思います。基本的にはここに載っている内容をコピペして、お仕事への効率化に役立てられたらと思います。


GET通信を行う

GET通信はrequests.getメソッドで実現できます。パラメータの渡し方は、URLに含めるかparams引数で指定します。
# URLにパラメータを含めて、GET通信を行う
r = requests.get("http://httpbin.org/get?key=value")

# または、paramsとしてGETパラメータを渡すこともできます
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://httpbin.org/get', params=payload)

# リスト項目は、値を配列で渡します.
payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
r = requests.get('http://httpbin.org/get', params=payload)
print(r.url) # 'http://httpbin.org/get?key1=value1&key2=value2&key2=value3'


POST通信を行う

POST通信はrequests.postメソッドで実現できます。POSTパラメータは、data引数で指定します。
# data引数に、POSTパラメータを渡します.
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post("http://httpbin.org/post", data=payload)
print(r.text)
"""
{
  ...
  "form": {
    "key1": "value1",
    "key2": "value2"
  },
  ...
}
"""

# リスト項目をPOSTパラメータで指定する場合には、値を配列にします.
payload = {"key1" : ["value1", "value2"]}
requests.post("http://httpbin.org/post", data=payload)
print(r.text)
"""
{
  ...
  "form": {
    "key1": ["value1", "value2"]
  },
  ...
}
"""


ファイルのアップロード

ファイルをアップロードする場合には、files引数でファイルを指定します。
# ファイルを読み込んで、
files = {'file': open('report.xls', 'rb')}
# files引数に指定します.
r = requests.post('http://httpbin.org/post', files=files)
print(r.text)
"""
{
  ...
  "files": {
    "file": "<censored...binary...data>"
  },
  ...
}
"""

# ファイル名やコンテントタイプを指定することもできます.
files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel')}
r = requests.post('http://httpbin.org/post', files=files)
print(r.text)
"""
{
  ...
  "files": {
    "file": "<censored...binary...data>"
  },
  ...
}
"""

# また、文字列をファイルとして送信することもできます
files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}
r = requests.post('http://httpbin.org/post', files=files)
print(r.text)
"""
{
  ...
  "files": {
    "file": "some,data,to,send\\nanother,row,to,send\\n"
  },
  ...
}
"""


カスタムヘッダーを付与する

headers引数に指定することで、リクエストに独自ヘッダーを付与することができます。
# カスタムヘッダーの付与
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get('https://api.github.com/some/endpoint', headers=headers)


Cookieを扱う

レスポンスにCookieが含まれる場合、以下のようにCookieの値を取得することができます。
# 以下URLがCookieを返却する場合には
r = requests.get('http://example.com/some/cookie/setting/url')

# 以下のようにCookieを取得できます.
print(r.cookies['example_cookie_name']) # 'example_cookie_value'
また、Cookieを付与してHTTP通信を行うには、cookies引数に指定します。
# Cookieを付与してHTTP通信を行う
cookies = dict(cookies_are='working')
r = requests.get('http://httpbin.org/cookies', cookies=cookies)
print(r.text) # '{"cookies": {"cookies_are": "working"}}'

# CookieJarを用いて、より詳細にCookieを指定することもできます.
jar = requests.cookies.RequestsCookieJar()
jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')
jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere')
r = requests.get('http://httpbin.org/cookies', cookies=jar)
print(r.text) # '{"cookies": {"tasty_cookie": "yum"}}'


リダイレクトの制御

デフォルトの振る舞いでは、リダイレクトが発生するURLでは自動的にリダイレクト先の情報を取得します。
# 「http://」にアクセスすると「https://」にリダイレクトされる
r = requests.get('http://github.com')

# 自動的にリダイレクト先に切り替わっている.
print(r.url) # 'https://github.com/'

# ステータスコードもリダイレクト先の内容になる
print(r.status_code) # 200

# リダイレクト履歴を確認できます.
print(r.history) # [<Response [301]>]
allow_redirects=Falseを指定することで、リダイレクトを追跡しないように振る舞うこともできます。
r = requests.get('http://github.com', allow_redirects=False)

print(r.status_code) # 301

print(r.history) # []


タイムアウトを指定する

タイムアウトを指定すると、時間内にリクエストが完了しない場合(=最初のレスポンスが時間内に返却されない場合)に、例外が発生します。
requests.get('http://github.com', timeout=0.001)
"""
Traceback (most recent call last):
  File "", line 1, in 
requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)
"""


セッションの利用

Sessionを用いることで、一連のHTTPリクエスト/レスポンスで、Cookieやカスタムヘッダーなどを使い回すことができます。

例えば、直前のレスポンスで付与されたCookieを次のリクエストで使いたい場合には、以下のようにSessionを利用します。
s = requests.Session()

s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get('http://httpbin.org/cookies')

print(r.text) # '{"cookies": {"sessioncookie": "123456789"}}'
また、Session内の全リクエストで共通して用いる内容を、以下のように設定することができます。
s = requests.Session()

# Session内の全リクエストで利用するBasic認証とカスタムヘッダ指定
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})

# 個別リクエストで、カスタムヘッダーなどを追加することも可能です
# 'x-test' と 'x-test2' のカスタムヘッダーが送信されます
s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})
ただし、以下のように個別リクエストで指定したCookieなどは、次のリクエストに引き継がれないので、注意が必要です。
s = requests.Session()

# 個別リクエストでクッキーを送信
r = s.get('http://httpbin.org/cookies', cookies={'from-my': 'browser'})
print(r.text) # '{"cookies": {"from-my": "browser"}}'

# 次のリクエストには、一つ前のCookieは反映されない
r = s.get('http://httpbin.org/cookies')
print(r.text) # '{"cookies": {}}'
また、以下のようなコンテキストマネージャー(with句)での利用も可能です。
with requests.Session() as s:
    s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')



参考情報

より詳しい情報は、以下の公式ドキュメントをご確認ください。
http://docs.python-requests.org/en/master/



最後に

requestsモジュールは良く使うのですが、腰を据えてドキュメント全体を学んだのは今回が初めて。案件で急いで使うのは良いとして、時間があるときにはドキュメント全体を学ぶと色々と学ぶことがあっていいですね。次はもっと効率的に使えそうな気がします。

最後になりますが本ブログでは、Python・フロントエンド・Node.js・Linux・インフラ・開発環境・Go言語・Swift・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSTwitterをフォローして頂けると幸いです ^ ^。

最後までご覧頂きましてありがとうございました!





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。