Python Requests庫簡明使用教程
Requests是一常用的http請求庫,它使用python語言編寫,可以方便地傳送http請求,以及方便地處理響應結果。
一、安裝
1.1 使用pip進行安裝
要安裝requests,最方便快捷的方法是使用pip進行安裝。
pip install requests
如果還沒有安裝pip,這個連結 Properly Installing Python 詳細介紹了在各種平臺下如何安裝python以及setuptools,pip,virtualenv等常用的python工具,可以參考其中的步驟來進行安裝。如果是在Windows平臺下使用requests,也可以參考 《Windows下安裝Django》
1.2 使用原始碼安裝
可以在github上下載最新的requests的原始碼
git clone git://github.com/kennethreitz/requests.git
下載成功後,使用以下命令進行安裝
python setup.py install
二、使用
2.1 傳送http請求
為了使用requests,需要首先將requests庫import進來:
import requests
然後,可以使用requests來發送http請求,例如傳送get請求:
r = requests.get ('http://httpbin.org/ip')
執行此行程式碼,獲得一個Response物件r
,從r
可以獲取http請求的響應結果。
如果要傳送post請求,則
r = requests.post('http://httpbin.org/post', data={'name': 'leo'})
2.2 構造url
我們常常將http請求的引數以url的query string的形式進行傳送,傳統的做法是我們使用拼湊的方式構造這個url。例如我們需要構造以下這個url:
使用reqeuets,你可以方便地構造這個url,而不用手工拼湊。你只需要將這些引數和值構造一個字典,然後將這個字典傳給params
d = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://httpbin.org/get', params=d)
print r.url
輸出
你可以看到,key1和key2這兩個引數已被正確附加到url的query string中。
2.3 HTTP響應正文
一個http響應的格式通常如下:
響應行
響應報頭
響應正文
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 07 Jul 2016 02:53:49 GMT
Content-Type: application/json
Content-Length: 31
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
[空行]
{
“origin”: “43.230.90.94”
}
注意,響應正文與響應頭部之間有一空行間隔。Requests已將http響應封裝成Response物件,從Response物件可獲取響應正文的內容。
2.3.1 響應正文文字
使用Response.text,可以獲取響應的正文文字內容。
r = requests.get('http://httpbin.org/ip')
print r.text
輸出
{
“origin”: “218.107.63.234”
}
Requests會自動對響應正文進行解碼:如果Response.encoding為空,那麼requests會猜測響應的編碼方式,然後進行解碼。如果你可以確定響應的編碼方式,也可以先對Response.encoding進行設定,然後再通過Response.text獲取響應正文。
2.3.2 二進位制響應正文
使用Response.content可以獲取響應正文的二進位制位元組內容。
from PIL import Image
from StringIO import StringIO
r = requests.get('https://img-blog.csdn.net/20150719230252020')
image = Image.open(StringIO(r.content))
print image.size # 輸出(680, 510)
image.show() # Windows平臺下可以開啟影象
上面的程式碼使用Response.content構造了一幅影象,然後輸出其尺寸並開啟該影象。
2.3.3 Json響應正文
如果響應正文是一json串,可以使用Response.json()方法對響應正文進行json decode操作,並返回一個字典。
r = requests.get('http://httpbin.org/ip')
d = r.json()
print d
print d['origin']
輸出:
{u’origin’: u’43.230.90.94’}
u’43.230.90.94’
如果響應正文不是一個json串,則會報錯。
2.4 響應狀態
Response物件status_code屬性標識http請求響應的狀態碼:
r = requests.get('http://httpbin.org/get')
print r.status_code
如果狀態碼是40X或者50X,那麼可以使用Response.raise_for_status()
丟擲一下異常:
r = requests.get('http://httpbin.org/status/404')
print r.status_code
404
響應返回404,故使用以下語句會丟擲異常:
r.raise_for_status()
Traceback (most recent call last):
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: NOT FOUND for url:
http://httpbin.org/status/404
如果是返回200,則raise_for_status()並不會丟擲異常。
r = requests.get('http://httpbin.org/status/200')
print r.status_code
r.raise_for_status()
2.5 響應的頭部
Response物件的headers屬性是一個字典,可以獲得http響應結果的頭部的相關資訊:
r = requests.get('http://httpbin.org/headers')
print r.headers
輸出:
{‘Content-Length’: ‘157’, ‘Server’: ‘nginx’, ‘Connection’: ‘keep-alive’, ‘Access-Control-Allow-Credentials’: ‘true’, ‘Date’: ‘Wed, 06 Jul 2016 15:53:36 GMT’, ‘Access-Control-Allow-Origin’: ‘*’, ‘Content-Type’: ‘application/json’}
2.6 定製請求的頭部
Requests支援定製http請求的頭部。為此,我們只需要構造一個字典,然後傳給requests.get()的headers
引數即可。
url = 'http://httpbin.org/headers'
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get(url, headers=headers)
print r.text
http://httpbin.org/headers 這個連結可以輸出請求的頭部,由於我們修改了請求頭的user-agent欄位,所以會訪問這個連結會返回:
{
“headers”: {
“Accept”: “/“,
“Accept-Encoding”: “gzip, deflate”,
“Host”: “httpbin.org”,
“User-Agent”: “my-app/0.0.1”
}
}
2.7 傳送POST請求
一個http請求包括三個部分,為別為請求行,請求報頭,訊息主體,類似以下這樣:
請求行
請求報頭
訊息主體
HTTP協議規定post提交的資料必須放在訊息主體中,但是協議並沒有規定必須使用什麼編碼方式。服務端通過是根據請求頭中的Content-Type欄位來獲知請求中的訊息主體是用何種方式進行編碼,再對訊息主體進行解析。具體的編碼方式包括:
- application/x-www-form-urlencoded
最常見post提交資料的方式,以form表單形式提交資料。 - application/json
以json串提交資料。 - multipart/form-data
一般使用來上傳檔案。
2.7.1 以form形式傳送post請求
Reqeusts支援以form表單形式傳送post請求,只需要將請求的引數構造成一個字典,然後傳給requests.post()的data
引數即可。
url = 'http://httpbin.org/post'
d = {'key1': 'value1', 'key2': 'value2'}
r = requests.post(url, data=d)
print r.text
輸出:
{
“args”: {},
“data”: “”,
“files”: {},
“form”: {
“key1”: “value1”,
“key2”: “value2”
},
“headers”: {
……
“Content-Type”: “application/x-www-form-urlencoded”,
……
},
“json”: null,
……
}
可以看到,請求頭中的Content-Type欄位已設定為application/x-www-form-urlencoded,且d = {'key1': 'value1', 'key2': 'value2'}
以form表單的形式提交到服務端,服務端返回的form欄位即是提交的資料。
2.7.2 以json形式傳送post請求
可以將一json串傳給requests.post()的data引數,
url = 'http://httpbin.org/post'
s = json.dumps({'key1': 'value1', 'key2': 'value2'})
r = requests.post(url, data=s)
print r.text
輸出:
{
“args”: {},
“data”: “{\”key2\”: \”value2\”, \”key1\”: \”value1\”}”,
“files”: {},
“form”: {},
“headers”: {
……
“Content-Type”: “application/json”,
……
},
“json”: {
“key1”: “value1”,
“key2”: “value2”
},
……
}
可以看到,請求頭的Content-Type設定為application/json,並將s
這個json串提交到服務端中。
2.7.3 以multipart形式傳送post請求
Requests也支援以multipart形式傳送post請求,只需將一檔案傳給requests.post()的files
引數即可。
url = 'http://httpbin.org/post'
files = {'file': open('report.txt', 'rb')}
r = requests.post(url, files=files)
print r.text
輸出:
{
“args”: {},
“data”: “”,
“files”: {
“file”: “Hello world!”
},
“form”: {},
“headers”: {……
“Content-Type”: “multipart/form-data; boundary=467e443f4c3d403c8559e2ebd009bf4a”,
……
},
“json”: null,
……
}
文字檔案report.txt的內容只有一行:Hello world!,從請求的響應結果可以看到資料已上傳到服務端中。
2.8 Cookie設定
使用requests,可以輕鬆獲取響應的cookies,和設定請求的cookies。
2.8.1 獲取響應的cookies
r.cookies
是響應cookies的字典,通過r.cookies
可訪問響應帶上的cookies。
r = requests.get(url)
print r.cookies['example_cookie_name']
2.8.2 傳送帶cookies的請求
url = 'http://httpbin.org/cookies'
cookies = {'cookies_are': 'working'}
r = requests.get(url, cookies=cookies)
print r.text
輸出:
{
“cookies”: {
“cookies_are”: “working”
}
}
2.9 請求的超時設定
Requests允許對一個http請求設定超時的時間,只需要在requests.get()或者requests.post()方法的timeout
引數設定一個值(單位為秒)即可。
url = 'http://httpbin.org/get'
r = requests.get(url, timeout=0.001)
將會丟擲一個超時異常:
raise ConnectTimeout(e, request=request)
requests.exceptions.ConnectTimeout: HTTPConnectionPool(host=’httpbin.org’, port=80): Max retries exceeded with url: /get (Caused by ConnectTimeoutError(
2.10 異常
在傳送http請求時,由於各種原因,requests可能會請求失敗而丟擲異常。常見的異常包括:
- ConnectionError
由於網路原因,無法建立連線。 - HTTPError
如果響應的狀態碼不為200,Response.raise_for_status()
會丟擲HTTPError 異常。 - Timeout
超時異常。 - TooManyRedirects
若請求超過了設定的最大重定向次數,則會丟擲一個 TooManyRedirects 異常。
所有requests丟擲的異常都繼承自 requests.exceptions.RequestException
類。
三、小結
從以上介紹可以看到,requests在處理httpy請求和響應時可謂簡單而直觀,這也印證了requests的開發哲學:
- Beautiful is better than ugly.(美麗優於醜陋)
- Explicit is better than implicit.(清楚優於含糊)
- Simple is better than complex.(簡單優於複雜)
- Complex is better than complicated.(複雜優於繁瑣)
- Readability counts.(重要的是可讀性)
共勉。