Python新一代爬蟲請求庫!!

來源 |?Python編程與實戰(zhàn)
在 Python3 網(wǎng)絡(luò)爬蟲領(lǐng)域最新的比較火的工具莫過于 httpx 了,號稱新一代網(wǎng)絡(luò)請求神庫
對比大家常用的 requests, 除了支持 requests 的所有操作之外,還具有以下特點:
同時支持同步和異步請求 支持 HTTP1.0/HTTP2.0 可直接向 WSGI 程序或 ASGI 程序發(fā)出請求 類型注釋
從以上可以看出在 requests 的所有功能之上,增加了更多新的功能,相當(dāng)于一個功能更強大的 requests !!
簡單用法
首先需要使用 pip 進行安裝pip insatll httpx
如果使用支持 HTTP/2 的功能, 使用以下安裝pip install httpx[http2]
基本的使用方法和 requests 非常類似
r?=?httpx.get('https://httpbin.org/post')
r.text
r.status_code
r.content
上面是 get 請求,post 請求也是一樣
r?=?httpx.post('https://httpbin.org/post',?data={'key':?'value'})
r.json()
r.status_code
r.content
除了上面的發(fā)送表單格式數(shù)據(jù)之外,發(fā)送 json 類型數(shù)據(jù)時候使用 json 參數(shù)
requests 中我們習(xí)慣使用 requests.Session(), 在 httpx 中用 httpx.Client() 來代替,代碼如下:
>>>?with?httpx.Client()?as?client:
...?r?=?client.get('https://example.com')
...
>>>?r
200?OK]>
另外使用 Client 具有更高的性能,在使用 httpx 發(fā)送請求的時候會為每一個請求建立一個新的連接,如果你的請求量很大,效率相對于Client 會變得低效
因為Client實例使用HTTP 連接池!在向同一主機發(fā)出多個請求時,Client 將重用底層 TCP 連接,而不是為每個請求重新創(chuàng)建一個。
所以它的性能會更好
減少跨請求的延遲 減少 CPU 使用率和往返次數(shù) 減少網(wǎng)絡(luò)擁塞
同時還多了好幾個功能,比如保持會話功能,維持整個請求過程中 cookie的一致性等
事件監(jiān)聽
HTTPX 支持在請求和響應(yīng)端監(jiān)聽的功能,常說的 hook 功能
可以非常方便的進行日志記錄、監(jiān)控或跟蹤等
def?log_request(request):
????print(f"Request?event?hook:?{request.method}?{request.url}?-?Waiting?for?response")
def?log_response(response):
????request?=?response.request
????print(f"Response?event?hook:?{request.method}?{request.url}?-?Status?{response.status_code}")
client?=?httpx.Client(event_hooks={'request':?[log_request],?'response':?[log_response]})
如在請求完全準(zhǔn)備好之后,但還未被發(fā)送到網(wǎng)絡(luò)之前會調(diào)用 log_request 函數(shù)
在網(wǎng)絡(luò)獲取響應(yīng)返回之后,但還未發(fā)送到調(diào)用著之前會調(diào)用 log_response 函數(shù)
通過上面兩個函數(shù),可以實現(xiàn)日志記錄,請求監(jiān)控等等功能
可以看到上面?zhèn)鲄⑹峭ㄟ^列表 [log_request] 的方式,所以我們可以注冊多個 hook函數(shù)
異步請求
默認(rèn)情況下,HTTPX 使用同步 API 進行請求,但其也支持異步請求。
異步請求的方式如下,使用AsyncClient
import?asyncio
import?httpx
async?def?main():
????async?with?httpx.AsyncClient()?as?client:
????????response?=?await?client.get('https://www.example.com/')
????????print(response)
asyncio.run(main())
HTTP/2
HTTP/2 是 HTTP 協(xié)議的主要新迭代,它提供了更高效的傳輸,并具有潛在的性能優(yōu)勢。HTTP/2 不會改變請求或響應(yīng)的核心語義,但會改變數(shù)據(jù)發(fā)送到服務(wù)器和從服務(wù)器發(fā)送的方式
使用 httpx 客戶端時,默認(rèn)情況下不啟用 HTTP/2 , 在安裝 HTTP/2 依賴后可使用,方法也很簡單
async?with?httpx.AsyncClient(http2=True)?as?client:
????...
在安裝好依賴之后,將 http2 參數(shù)設(shè)為 True即可,非常的方便
HTTP/2 支持可用于Client和AsyncClient, 如果要發(fā)送大并發(fā)請求,使用異步效果會更好
但是不是所有的網(wǎng)站都支持 HTTP/2 協(xié)議, 可通過下面代碼判斷
client?=?httpx.AsyncClient(http2=True)
response?=?await?client.get(...)
print(response.http_version)
#?"HTTP/1.0",?"HTTP/1.1",?or?"HTTP/2".
以上便是 httpx 的常見用法,和 requests 用法是不是非常的相似,不過 httpx 的功能更加豐富,趕緊用起來!
