Requests 響應(yīng)內(nèi)容

2022-06-27 15:27 更新

我們能讀取服務(wù)器響應(yīng)的內(nèi)容。再次以 GitHub 時(shí)間線為例:

>>> import requests
>>> r = requests.get('https://api.github.com/events')
>>> r.text
u'[{"repository":{"open_issues":0,"url":"https://github.com/...

Requests 會(huì)自動(dòng)解碼來自服務(wù)器的內(nèi)容。大多數(shù) unicode 字符集都能被無縫地解碼。

請求發(fā)出后,Requests 會(huì)基于 HTTP 頭部對響應(yīng)的編碼作出有根據(jù)的推測。當(dāng)你訪問 ?r.text? 之時(shí),Requests 會(huì)使用其推測的文本編碼。你可以找出 Requests 使用了什么編碼,并且能夠使用 ?r.encoding? 屬性來改變它:

>>> r.encoding
'utf-8'
>>> r.encoding = 'ISO-8859-1'

如果你改變了編碼,每當(dāng)你訪問 ?r.text? ,Request 都將會(huì)使用 ?r.encoding? 的新值。你可能希望在使用特殊邏輯計(jì)算出文本的編碼的情況下來修改編碼。比如 HTTP 和 XML 自身可以指定編碼。這樣的話,你應(yīng)該使用 r.content 來找到編碼,然后設(shè)置 ?r.encoding? 為相應(yīng)的編碼。這樣就能使用正確的編碼解析 ?r.text? 了。

在你需要的情況下,Requests 也可以使用定制的編碼。如果你創(chuàng)建了自己的編碼,并使用 codecs 模塊進(jìn)行注冊,你就可以輕松地使用這個(gè)解碼器名稱作為 ?r.encoding? 的值, 然后由 Requests 來為你處理編碼。

二進(jìn)制響應(yīng)內(nèi)容

你也能以字節(jié)的方式訪問請求響應(yīng)體,對于非文本請求:

>>> r.content
b'[{"repository":{"open_issues":0,"url":"https://github.com/...

Requests 會(huì)自動(dòng)為你解碼 gzip 和 deflate 傳輸編碼的響應(yīng)數(shù)據(jù)。

例如,以請求返回的二進(jìn)制數(shù)據(jù)創(chuàng)建一張圖片,你可以使用如下代碼:

>>> from PIL import Image
>>> from io import BytesIO

>>> i = Image.open(BytesIO(r.content))

JSON 響應(yīng)內(nèi)容

Requests 中也有一個(gè)內(nèi)置的 JSON 解碼器,助你處理 JSON 數(shù)據(jù):

>>> 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()? 就會(huì)拋出一個(gè)異常。例如,響應(yīng)內(nèi)容是 401 (Unauthorized),嘗試訪問 ?r.json()? 將會(huì)拋出 ?ValueError: No JSON object could be decoded? 異常。

需要注意的是,成功調(diào)用 ?r.json()? 并**不**意味著響應(yīng)的成功。有的服務(wù)器會(huì)在失敗的響應(yīng)中包含一個(gè) JSON 對象(比如 HTTP 500 的錯(cuò)誤細(xì)節(jié))。這種 JSON 會(huì)被解碼返回。要檢查請求是否成功,請使用 ?r.raise_for_status()? 或者檢查 ?r.status_code? 是否和你的期望相同。

原始響應(yīng)內(nèi)容

在罕見的情況下,你可能想獲取來自服務(wù)器的原始套接字響應(yīng),那么你可以訪問 ?r.raw?。 如果你確實(shí)想這么干,那請你確保在初始請求中設(shè)置了 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'

但一般情況下,你應(yīng)該以下面的模式將文本流保存到文件:

with open(filename, 'wb') as fd:
    for chunk in r.iter_content(chunk_size):
        fd.write(chunk)

使用 Response.iter_content 將會(huì)處理大量你直接使用 ?Response.raw? 不得不處理的。 當(dāng)流下載時(shí),上面是優(yōu)先推薦的獲取內(nèi)容方式。?請注意,chunk_size可以自由調(diào)整為可能更適合您的用例的數(shù)字。?

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號