requests提交各種格式的數據

バージョン

version
% pip list | grep requests #インストールしてない人は pip install requestsを実行
requests           2.28.1
% python -V
Python 3.9.6

requestsモジュールができること

できることはたくさんあるのですが、自分がよく使われるだろうと思った機能を6つ紹介させて頂きます。

1. リクエストの生成

たった2行であるサイトの情報を取得することができます。
今回はgetを使っていますが、post,put,delete,head,optionsなどもちゃんとあります。

import requests
r = requests.get("http://httpbin.org/get")
print(r.text)

#”http://httpbin.org/get"を利用しているのでレスポンスはリクエストと同じ內容であることに注意。
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.28.1", 
    "X-Amzn-Trace-Id": "Root=1-63739e5e-3012837e2ed8d5c73d021077"
  }, 
  "origin": "133.32.130.44", 
  "url": "http://httpbin.org/get"
}

ちなみに "http://httpbin.org/” 
このサイトは自分がどんなリクエストを送ったかわかりやすくしてくるのですごい便利です。

 

2. クエリパラメータの作成

クエリパラメータをURLに追加したい時ありますよね。
for分で?,&,=などを一個一個URLに追加することもできますが、requestsを使えば一発で解決です。今回は例としてdogとcatをクエリパラメータに追加してみます。
やり方は簡単で、辭書にキーと値を設定してそれをparamsを引數にして渡してあげるだけです。

params = {
    "animal1":"dog",
    "animal2":"cat"
    }
r = requests.get("http://httpbin.org/get",params=params)

print(r.text)

#レスポンス
{
  "args": {
    "animal1": "dog", 
    "animal2": "cat"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.28.1", 
    "X-Amzn-Trace-Id": "Root=1-6373a04c-2e523f144af4b13d087d28e4"
  }, 
  "origin": "133.32.130.44", 
  "url": "http://httpbin.org/get?animal1=dog&animal2=cat"
}

http://httpbin.org/get?animal1=dog&animal2=cat
ちゃんとURLにクエリパラメータが付け加えられていますね。
今回の注意點としては、引數にparamsと明示することです。明示しないとdata=paramsとして受けたられクエリパラメータではなくdata、つまりbodyの方に含まれることになります。

3. ヘッダーの內容を指定

これもクエリパラメータの時と同じで、HTTPヘッダーを追加したい場合は、headersパラメーターにdictを渡すだけです。
今まではなかった"Content-Type": "text/plain"が追加されていますね。こちらから送ったheadersの"Content-Type"が追加されていることが確認できていればOKです。

headers = {"content-type":"text/plain"}
r = requests.get("http://httpbin.org/get",headers=headers)

print(r.text)

#レスポンス
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Type": "text/plain", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.28.1", 
    "X-Amzn-Trace-Id": "Root=1-6373a362-3dee925f1c112b120353f8a1"
  }, 
  "origin": "133.32.130.44", 
  "url": "http://httpbin.org/get"
}

4.1 リクエスト本文(data)をPOST

これも辭書で書いて、引數にdata=をして渡してあげれば完了です。
辭書のdataは自動的にエンコードされるので、ありがたいですよね。
畫像などのbinaryを送信したい場合には引數にfilesを使うのでよかったら覚えておいてください。

data = {'key1': 'value1', 'key2': 'value2'}
r = requests.post("http://httpbin.org/post", data=data)

print(r.text)
#レスポンス
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "key1": "value1", 
    "key2": "value2"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "23", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.28.1", 
    "X-Amzn-Trace-Id": "Root=1-6373a69c-5e870e1a252e6f1d52449701"
  }, 
  "json": null, 
  "origin": "133.32.130.44", 
  "url": "http://httpbin.org/post"
}

formに辭書で指定したキーと値が入っていることが確認できます。

4.2 jsonを使ってPOSTする場合

API通信をする際にはjsonを使われることが多いので、jsonでリクエストをする場合についても殘しておきます。

import requests
import json

headers = {"Content-Type":"application/json"}
data = {'key1': 'value1', 'key2': 'value2'}
r = requests.post("http://httpbin.org/post", data=json.dumps(data), headers=headers)
print(r.text)
#レスポンス
{
  "args": {}, 
  "data": "{\"key1\": \"value1\", \"key2\": \"value2\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "36", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.28.1", 
    "X-Amzn-Trace-Id": "Root=1-6373a898-3ebe70d46336d6cc65ecf279"
  }, 
  "json": {
    "key1": "value1", 
    "key2": "value2"
  }, 
  "origin": "133.32.130.44", 
  "url": "http://httpbin.org/post"
}

先ほどはformにdataが入っていましたが、jsonの時は"data"に入っていますね。
jsonでレスポンスが帰ってくる場合、r.json()とすれば辭書型に変換してくれるので、こちらも便利です。ただ、jsonのデコードに失敗したらNoneとなって返ってくようになってます。

5. コードが200番以外の時、エラーを起こす。

パラメータの不足やネットワークの問題でうまく通信ができない可能性があるので、現場ではエラーハンドリングを必ず行うと思います。その際使うのが、raise_for_status()です。これは、200以外のレスポンスが返ってきたときに例外を発生させます。その例外発生を契機に、リトライを行ったり待機を行ったり分岐をさせていくのに使われることが多いのかなと思います。

r = requests.get('http://httpbin.org/status/404')
r.raise_for_status()

#例外
Traceback (most recent call last):
  File "PATH", line 5, in <module>
    r.raise_for_status()
  File "PATH", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: NOT FOUND for url: http://httpbin.org/status/404

正常系ならOKですが、(準)異常系だった場合はexceptを使ってうまくエラーハンドリングを行う必要があります。

try:
    r = requests.get('http://httpbin.org/status/404')
    r.raise_for_status()
    return r
except Exception as e:
    print(e) #例外処理を記述していく

6. セッションの利用

API連攜の場合、アクセストークンで認証されることが多いですが、ログインを必要とするサイトなどはセッションを使うことが一般的ですよね。
Sessionモードを有効にするのも簡単に実裝できます。まずSessionオブジェクトからインスタンスを作成して、そのインスタンスを使って今までのようにget,postなどでリクエストを送ります。ログイン時にはログイン情報を送るので初めのリクエストはpostメソッドになることが多いと思いますが、今回はhttpbin.orgを使っているのでgetとしています。紛らわしくてすいません。

s = requests.Session() #Sessionインスタンス作成
r = s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
print(r)
r = s.get("http://httpbin.org/cookies")
print(r)

#レスポンス
{
  "cookies": {
    "sessioncookie": "123456789"
  }
}

{
  "cookies": {
    "sessioncookie": "123456789"
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章