最終更新日:190806 原本2019-02-04

python2.7

Python Requestsモジュールについて

[参照]
Pythonプロフェッショナルプログラミング第2版

Requests:HTTP for Humans

http://docs.python-requests.org/en/latest

RESTとは

RESTはソフトウェアアーキテクチャーのひとつ。
ソフトウェアの設計原則の集合。

「REST」「REST API」という単語は、「HTTP」上で動作するSOAPやRPCではないAPI」の意味で使われることが多い。

REST APIの特徴

  • HTTP上で動作する
  • データはリソースと呼ばれる
  • REST APIで使用可能なリソースは、一意なURLを持っている。
  • GET/POST/PUT/DELETEなどのHTTPメソッドはそれぞれ、取得/保存/上書き/削除などのリソースの操作と対応している。
  • JSONやXMLなどのフォーマットでデータを送受信する
  • リクエストの成功や失敗などの処理結果はステータスコードで表す

REST APIを使用するには、HTTPクライアントを利用する。
・シェル上のコマンドやシェルスクリプトではcurlを使う。
・プログラム中から使用する場合はHTTPクライアントライブラリを使う。

https://ja.wikipedia.org/wiki/REST


以下の説明内容のまとめ

1.Requestsの導入
2.テスト用サーバーの導入(httpbinのテスト)
3.リクエスト
 •3-1 GETリクエストの送信
 •3-2 POSTリクエストの送信
 •3-3 JSON形式でPOSTリクエストを送信する
 •3-4 GET/POST以外のHTTPメソッドの使用


1.Requestsの導入

pipコマンドを使用する。

$ pip install requests

2.テスト用サーバーの導入

・Requestsモジュールの動作を試すにはWebサーバーが必要。

httpbin

※httpbinというモジュールを使用する場合

$ pip install httpbin

$ python -m httpbin.core

*Running on http://127.0.0.1:5000

※Requestsモジュールから使用する前に、テストサーバーの動作をcurlコマンドで確認してみる。
※テストサーバーを起動した状態で、次のコマンドを実行する。
※正常に動作していれば、JSON形式のレスポンスが表示される。

$ curl "http://127.0.0.1:5000/get?foo=bar" #GETリクエストをテストサーバーに送信


{
    "args":{ #argsはGETパラメータ
    "foo":"bar"
},
"headers":{
    "Accept":"*/*",
    "Content-Length:"",
    "Content-Type": "",
    "Host": "127.0.0.1:5000",
    "User-Agent": "curl/7.35.0"
},
"origin":"127.0.0.1",
"url": "http://127.0.0.1:5000"/get?foo=bar"
}

$ curl -x post -d foo=bar http://127.0.0.1:5000/post #postリクエストをテスト サーバーに送信
{
"args":{},
"data":"", #dataは送信データの本文
"files":{},
"form":{ #formはフォームエンコードされたパラメータ
"foo":"bar"
},
"headers":{
    "Accept":"*/*,
    "Content-Length":"7",
    "Content-Type":"application/x-www-form-urlencoded",
    "Host":"127.0.0.1:5000",
    "User-Agent": "curl/7.35.0"
},
"json":null,
"origin":"127.0.0.1",
"url":"http://127.0.0.1:5000/post"
}

テストサーバーは、リクエストした内容をJSON形式で返してくれる。

3.リクエスト

3-1.GETリクエストの送信

Requestsを使用してGETリクエストを送信する

# coding utf-8
import pprint
import requests

def main():
    #GETパラメータはparams引数に辞書で指定する

    response = requests.get(
        'http://127.0.0.1:5000/get',
        params={'foo': 'bar'})
    #レスポンスオブジェクトのjsonメソッドを使うと、
    #JSONデータをPythonの辞書オブジェクトを変換して取得できる。
    pprint.pprint(response.json())

if __name__== '__main__':
    main()

requests.get関数に対象のURLとparamsキーワード引数でGETパラメーターを指定する。
サーバーからのレスポンスはJSON形式なので、jsonメソッドで辞書に変換してから画面に表示する。
ソースコードを実行すると次のような結果になる。

$ python requests_get.py

{u'args':{u'foo':u'bar'},
u'headers': {u'Accept':u'*/*',
            u'Accept-Encoding': u'gzip,deflate',
            u'Connection':u'keep-alive',
            u'Content-Length': u'',
            u'Content-Type': u'',
            u'Host': u'127.0.0.1:5000',
            u'User-Agent' : u'python-requests/2.5.0 CPython/2.7.8 Linux/3.13.0-35-generic'},
u'origin' : u'127.0.0.1',
u'url' : u'http://127.0.0.1:5000/get?foo=bar'}


3-2.POSTリクエストの送信

Requestsを使用してPOSTリクエストを送信するコード

# coding: utf-8
import pprint
import requests

def main():
    #POSTパラメータは二つ目の引数に辞書で指定する
    response = requests.post(
        'http://127.0.0.1:5000/post',
        {'foo':'bar'})
    #レスポンスオブジェクトのjsonメソッドを使うと、
    #JSONデータをPythonの辞書オブジェクトに変換して取得できる
    pprint.pprint(response.json())

if __name__=='__main__':
   main()


requests.post関数に対象のURLとPOSTパラメータを指定している。POSTパラメータに辞書を指定すると、URLエンコードされてから送信される。
このソースコードを実行すると次のような結果になる。

$python requests_post.py

{u'args':{},
u''data': u'',
u'data': u'',
u'files':{}
u'form':{u'foo' u'bar'},
u'headers':{u'Accept': u'*/*',
            u'Accept-Encoding': u'gzip, deflate',
            u'Connection':u'keep-alive',
            u'Content-Length': u'7',
            u'Content-Type': u'application/x-www-form-urlencoded',
            u'Host': u'127.0.0.1:5000',
            u'User-Agent': u'python-requests/2.5.0 CPython/2.7.8 Linux/3.13.0-35-generic'},
            u'json': None,
            u'origin': u'127.0.0.1',
            u'url': u'http://127.0.0.1:5000/post'}


3-3.JSON形式でPOSTリクエストを送信する

APIインターフェイスによっては、送信するデータをURLエンコードではなくJSON形式の文字列で要求するものがある。
RequestsでJSON形式の文字列をPOSTリクエストで送信するコードは以下にようになる。

requests_post_json.py
import pprint
import json
import requests

def main()
    response = requests.post(
        'http://127.0.0.1:5000/post',
        json.dumps({'foo':'bar'}),
        headers={'Content-Type': 'application/json'})
    pprint.pprint(response.json())


if __name__=='__main__':
    main()

※json.dumpsで生成した文字列を指定すると、URLエンコードされずにそのままデータが送信される。
※Content-Typeを明示的に指定する必要がある。

※post関数の引数に送信するデータを文字列で指定している。
※文字列を指定した場合、URLエンコードされず送信される。

上記のソースコードを実行すると次の結果となる。

$python requests_post_json.py

{u'args}:{},
u'data': u'{"foo": "bar"} ',
u'files': {},
u'form': {},
u'headers':{u'Accept': u'*/*,
            u''Accept-Encoding': u'gzip, deflate',
            u'Connection': u'keep-alive',
            u'Content-Length': u'14',
            u'Content-Type': u'application/json',
            u'Host': u'127.0.0.1:5000',
            u''User-Agent': u'python-requests/2.5.0 CPython/2.7.8 Linux/3.13.0-35-generic'},
            u'json':{u'foo': u'bar'},
            u'origin': u'127.0.0.1',
            u'url': u'http://127.0.0.1:5000/post'}


3-4.GET/POST以外のHTTPメソッドの使用

APIによってはGET,POST以外のHTTPメソッド(PUT、DELETE、HEAD、OPTIONS)を要求するものがある。
RequestsではGETやPOSTと同様に、これらのメソッドに対応する関数が用意されている。

# coding: utf-8
import requests

def main():
    requests.put('http://127.0.0.1:5000/put',{'foo': 'bar'}) #put
    requests.delete('http://127.0.0.1:5000/delete') #delete
    requests.head('http://127.0.0.1:5000/get') #HEAD
    requests.options('http://127.0.0.1:5000/options') #OPTIONS

if __name__ == '__main__':
    main()


上記のソースコードは実行すると、
HTTPのPUT、DELETE、HEAD、OPTIONSメソッドのリクエストをサーバーへ送信し、
レスポンスを取得したら終了する。