1. 程式人生 > >Python Requests庫簡明使用教程

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》

中有關 pip 安裝的介紹來安裝pip。

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的開發哲學:

  1. Beautiful is better than ugly.(美麗優於醜陋)
  2. Explicit is better than implicit.(清楚優於含糊)
  3. Simple is better than complex.(簡單優於複雜)
  4. Complex is better than complicated.(複雜優於繁瑣)
  5. Readability counts.(重要的是可讀性)

共勉。

四、參考資料