requests學習筆記01
一、傳送請示
# 匯入 Requests 模組 import requests # 獲取某個網頁 r = requests.get("http://www.baidu.com")
可以傳送 HTTP POST、PUT、DELETE、HEAD 以及 OPTIONS 請求:
r = requests.post('http://httpbin.org/post', data = {'key':'value'}) r = requests.put('http://httpbin.org/put', data = {'key':'value'}) r = requests.delete('http://httpbin.org/delete') r = requests.head('http://httpbin.org/get') r = requests.options('http://httpbin.org/get')
二、傳遞 URL 引數
比如http://httpbin.org/get?key=val傳遞key=val的引數, 在Request 使用 params 關鍵字引數,以一個字串字典來提供這些引數。舉例,如想傳遞 key1=value1 和 key2=value2 到http://httpbin.org/get ,可以使用如下程式碼
payload = {'key1':'value1', 'key2':'value2'} r= requests.get("http://httpbin.org/get", params=payload) # 檢視列印 URL 地址是否正確 print(r.url) # out: http://httpbin.org/get?key2=value2&key1=value1
注意:字典裡值為 None 的鍵不會被新增到 URL 的查詢字串裡。
還可以將一個列表作為值傳入,例如下:
payload = {'key1': 'value1', 'key2': ['value2', 'value3']} r = requests.get(('http://httpbin.org/get', params=payload)print(r.url) # out: http://httpbin.org/get?key1=value1&key2=value2&key2=value3
三、響應內容
讀取伺服器響應的內容。例如下:
# 匯入 Requests 模組 import requests # 獲取某個網頁 r = requests.get("https://api.github.com/events") # 獲取伺服器響應內容 print(r.text) # out: u'[{"repository":{"open_issues":0,"url":"https://github.com/...
使用 r.encoding = "ISO-8859-1" 修改文字編碼格式,顯示改變編碼後的響應內容。如果你想在使用特殊邏輯計算出文字的編碼的情況下來修改編碼,應該使用 r.content 來找到編碼,然後設定 r.conding 為相應的編碼。這樣就能使用正確的編碼解析 r.text 了。在學習codecs模組後,可以使用定製的編碼。
四、二進位制響應內容
你能以位元組的方式訪問請求響應體,對於非文字請求:
>>> c.content b'[{"repository":{"open_issues":0,"url":"https://github.com/...
Requests 會自動為你解碼 gzip 和 deflate 傳輸編碼的響應資料。
例如,以請求返回的二進位制資料建立一張圖片,你可以使用如下程式碼:
>>> from PIL import Image >>> from io import BytesIO >>> i = Image.open(BytesIO(r.content))
四、JSON響應內容
Requests 中也有一個內建的 JSON 解碼器,助力處理 JSON 資料:
>>> import requests >>> r = requests.get('https://api.github.com/events') >>> r.json() [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
如果JSON解碼失敗, r.json() 就會丟擲一個異常。例如,響應內容是401 (Unauthorized),嘗試訪問 r.json() 將會丟擲 ValueError: No JSON object could be decoded 異常。
注意點,成功呼叫 r.json() 並不意味著響應的成功。有的伺服器會在失敗的響應中包含一個JSON物件(比如HTTP 500的錯誤細節)。這種 JSON 會被解碼返回。要檢查請求是否成功,請使用 r.raise_for_status() 或者檢查r.status_code 是否和你的期望相同。
五、原始響應內容
在罕見的情況下,你可能想獲取來自伺服器的原始套接字響應,那麼你可以訪問 r.raw。如果你確定想這麼幹,那請你確保在初始請求中設定了 stream=True。具體你可以這麼做:
>>> r = requests.get('https://api.github.com/events', stream=True) >>> r.raw <requests.packages.urllib3.response.HTTPResponse object at 0x101194810> >>> r.raw.read(10) '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
但一般情況下,你應該以下面的模式將文字流儲存到檔案中:
with open(filename, 'wb') as fd: for chunk in r.iter_content(chunk_size): fd.write(chunk)
使用 Response.iter_content 將會處理大量你直接使用 Response.raw 不得不處理的。當流下載時,上面是優先推薦的獲取內容方式。
六、定製請求頭
如果你想為請求新增 HTTP 頭部,只要簡單地傳遞一個 dict 給 headers 引數就可以了。例如,在前一個示例中我們沒有指定 content-type:
>>> url = 'https://api.github.com/some/endpoint' >>> headers = {'user-agent': 'my-app/0.0.1'} >>> r = requests.get(url, headers=headers)
注意:定製 header 的優先順序低於某些特定的資訊源,例如:
- 如果在
.netrc
中設定了使用者認證資訊,使用headers=設定的授權就不會生效。而如果設定了auth=
引數,``.netrc`` 的設定就無效了。 - 如果被重定向到別的主機,授權 header 就會被刪除。
- 代理授權 header 會被 URL 中提供的代理身份覆蓋掉。
- 在我們能判斷內容長度的情況下,header 的 Content-Length 會被改寫。
更進一步講,Requests不會基於定製 header 的具體情況改變自己的行為。只不過在最後的請求中,所有的header 資訊都會被傳遞進去。
注意: 所有的 header 值必須是string
、bytestring 或者 unicode。儘管傳遞 unicode header 也是允許的,但不建議這樣做。
七、更加複雜的POST請求
通常,你想要傳送一些編碼為表單形式的資料——非常像一個 HTML 表單。要實現這個,只需簡單地傳遞一個字典給 data 引數。你的資料字典在發出請求時會自動編碼為表單形式:
>>> payload = {'key1': 'value1', 'key2': 'value2'} >>> r = requests.post("http://httpbin.org/post", data=payload) >>> print(r.text) { ... "form": { "key2": "value2", "key1": "value1" }, ... }
你還可以為 data 引數傳入一個元組列表。在表單中多個元素使用同一 key 的使用,這種方式 尤其有效:
>>> payload = (('key1', 'value1'), ('key1', 'value2')) >>> r = requests.post('http://httpbin.org/post', data=payload) >>> print(r.text) { ... "form": { "key1": [ "value1", "value2" ] }, ... }
很多時候你想要傳送的資料並非編碼為表單形式的。如果你傳遞一個string
而不是一個dict
,那麼資料會被直接釋出出去。例如,Github API v3 接受編碼為 JSON 的 POST/PATCH 資料:
>>> import json >>> url = 'https://api.github.com/some/endpoint' >>> payload = {'some': 'data'} >>> r = requests.post(url, data=json.dumps(payload))
此處除了可以自行對dict
進行編碼,你還可以使用json
引數直接傳遞,然後它就會被自動編碼。這是 2.4.2 版的新加功能:
>> url = 'https://api.github.com/some/endpoint' >>> payload = {'some': 'data'} >>> r = requests.post(url, json=payload)