1. 程式人生 > >Python爬蟲(二):Requests庫

Python爬蟲(二):Requests庫

所謂爬蟲就是模擬客戶端傳送網路請求,獲取網路響應,並按照一定的規則解析獲取的資料並儲存的程式。要說 Python 的爬蟲必然繞不過 Requests 庫。

1 簡介

對於 Requests 庫,官方文件是這麼說的:

Requests 唯一的一個非轉基因的 Python HTTP 庫,人類可以安全享用。
警告:非專業使用其他 HTTP 庫會導致危險的副作用,包括:安全缺陷症、冗餘程式碼症、重新發明輪子症、啃文件症、抑鬱、頭疼、甚至死亡。

這個介紹還是比較生動形象的,便不再多說。安裝使用終端命令 pip install requests

2 快速上手

2.1 傳送請求

匯入 Requests 模組:

import requests

獲取網頁:

r = requests.get('http://xxx.xxx')

此時,我們獲取了 Response 物件 r,我們可以通過 r 獲取所需資訊。Requests 簡便的 API 意味著所有 HTTP 請求型別都是顯而易見的,我們來看一下使用常見 HTTP 請求型別 get、post、put、delete 的示例:

r = requests.head('http://xxx.xxx/get')
r = requests.post('http://xxx.xxx/post', data = {'key':'value'})
r = requests.put('http://xxx.xxx/put', data = {'key':'value'})
r = requests.delete('http://xxx.xxx/delete')

通常我們會設定請求的超時時間,Requests 使用 timeout 引數來設定,單位是秒,示例如下:

r = requests.head('http://xxx.xxx/get', timeout=1)

2.2 引數傳遞

在使用 get 方式傳送請求時,我們會將鍵值對形式引數放在 URL 中問號的後面,如:http://xxx.xxx/get?key=val ,Requests 通過 params 關鍵字,以一個字串字典來提供這些引數。比如要傳 key1=val1key2=val2http://xxx.xxx/get,示例如下:

pms= {'key1': 'val1', 'key2': 'val2'}
r = requests.get("http://xxx.xxx/get", params=pms)

Requests 還允許將一個列表作為值傳入:

pms= {'key1': 'val1', 'key2': ['val2', 'val3']}

:字典裡值為 None 的鍵都不會被新增到 URL 的查詢字串裡。

2.3 響應內容

我們來獲取一下伺服器的響應內容,這裡地址 https://api.github.com 為例:

import requests
r = requests.get('https://api.github.com')
print(r.text)

# 輸出結果
# {"current_user_url":"https://api.github.com/user","current_user...

當訪問 r.text 之時,Requests 會使用其推測的文字編碼,我們可以使用 r.encoding 檢視其編碼,也可以修改編碼,如:r.encoding = 'GBK',當改變了編碼,再次訪問 r.text 時,Request 都將會使用 r.encoding 的新值。

1)二進位制響應內容
比如當我們要獲取一張圖片的資料,會以二進位制的方式獲取響應資料,示例如下:

from PIL import Image
from io import BytesIO
i = Image.open(BytesIO(r.content))

2)JSON響應內容
Requests 中已經內建了 JSON 解碼器,因此我們可以很容易的對 JSON 資料進行解析,示例如下:

import requests
r = requests.get('https://api.github.com')
r.json()

:成功呼叫 r.json() 並不一定響應成功,有的伺服器會在失敗的響應中包含一個 JSON 物件(比如 HTTP 500 的錯誤細節),這時我們就需要檢視響應的狀態碼了 r.status_coder.raise_for_status(),成功呼叫時 r.status_code 為 200,r.raise_for_status() 為 None。

2.4 自定義請求頭

當我們要給請求新增 headers 時,只需給 headers 引數傳遞一個字典即可,示例如下:

url = 'http://xxx.xxx'
hds= {'user-agent': 'xxx'}
r = requests.get(url, headers=hds)

:自定義 headers 優先順序是低於一些特定的資訊的,如:在 .netrc 中設定了使用者認證資訊,使用 headers 設定的授權就不會生效,而當設定了 auth 引數,.netrc 的設定會無效。所有的 headers 值必須是 stringbytestring 或者 unicode,通常不建議使用 unicode

2.5 重定向與歷史

預設情況下,Requests 會自動處理除了 HEAD 以外的所有重定向,可以使用響應物件的 history 屬性來追蹤重定向,其返回為響應物件列表,這個列表是按照請求由晚到早進行排序的,看一下示例:

import requests
r = requests.get('http://github.com')
print(r.history)
# 輸出結果
# [<Response [301]>]

如果使用的是 get、post、put、delete、options、patch 可以使用 allow_redirects 引數禁用重定向。示例如下:

r = requests.get('http://xxx.xxx', allow_redirects=False)

2.6 錯誤與異常

當遇到網路問題(如:DNS 查詢失敗、拒絕連線等)時,Requests 會丟擲 ConnectionError 異常;在 HTTP 請求返回了不成功的狀態碼時, Response.raise_for_status() 會丟擲 HTTPError 異常;請求超時,會丟擲 Timeout 異常;請求超過了設定的最大重定向次數,會丟擲 TooManyRedirects 異常。所有 Requests 顯式丟擲的異常都繼承自 requests.exceptions.RequestException。

參考:
http://cn.python-requests.org/zh_CN/latest/user/quickstart.h