1. 程式人生 > 其它 >初識網路請求庫 Httpx

初識網路請求庫 Httpx

技術標籤:Python基礎知識python

簡介

HTTPX 是最近 GitHub看的到一個比較火的一個專案,根據官網的描述,總結有如下特點:

  • 和使用 requests 一樣方便,requests 有的它都有

  • 加入 HTTP/1.1 和 HTTP/2 的支援。

  • 能夠直接向 WSGI 應用程式或 ASGI 應用程式發出請求。

  • 到處都有嚴格的超時設定

  • 全型別註釋

  • 100% 的測試覆蓋率

比較不錯的一個特點是全型別註解,這讓我想起了一個叫Starlette的庫,它也是全型別註解的,型別註解主要方便IDE的智慧提示,Java 等靜態型別的語言都有這個功能,Python 是近期新加的。其他的後面再說吧,我們還是看例子吧。

安裝

httpx 的安裝很簡單,像其他的 Python 庫一樣,直接 pip 就完事了

python3-mpipinstallhttpx

如果需要對 HTTP/2 支援,我們需要額外安裝一個庫

python3-mpipinstallhttpx[http2]

使用示例

importhttpx
r=httpx.get('https://www.example.org/')
r.text
r.content
r.json()
r.status_code

基本的用法直接導包然後 get 就行了。其他的和 requests 的使用類似

r=httpx.put('https://httpbin.org/put',data={'key':'value'})
r=httpx.delete('https://httpbin.org/delete')
r=httpx.head('https://httpbin.org/get')
r=httpx.options('https://httpbin.org/get')

Ok,這是基本用法。

如果需要做一個爬蟲專案,裡面涉及到 Cookie 的傳遞這時候再這樣就不行了,
httpx 有個 requests 的 Session 型別的使用方法.

importhttpx
client=httpx.Client()#類似requests.Session()
try:
dosomting
finally:
client.close()#關閉連線池

更優雅的方法就是使用 with 上下文管理器的形式

withhttpx.Client()asclient:
headers={'X-Custom':'value'}
r=client.get('https://example.com',headers=headers)

這裡有個地方需要強調下 Client 和 get 裡面都可以新增 headers,
最後這兩個地方的 headers 可以合併到請求裡,官方的例子

>>>headers={'X-Auth':'from-client'}
>>>params={'client_id':'client1'}
>>>withhttpx.Client(headers=headers,params=params)asclient:
...headers={'X-Custom':'from-request'}
...params={'request_id':'request1'}
...r=client.get('https://example.com',headers=headers,params=params)
...
>>>r.request.url
URL('https://example.com?client_id=client1&request_id=request1')
>>>r.request.headers['X-Auth']
'from-client'
>>>r.request.headers['X-Custom']
'from-request'

接下來說下大家比較關心的一點代理的使用,需要注意的是 httpx 的代理只能在 httpx.Client 建立 Client 的例項的時候使用,client.get 的時候沒這個引數。
有意思的是它這個代理可以指定規則,限制哪些請求使用代理哪些不使用,來個官方的例子

允許所有請求都走代理

proxies={
"all://":"http://localhost:8030",
}

如果字典的值為 None 則表示不使用代理。

不同的協議走不用的代理

proxies={
"http://":"http://localhost:8030",
"https://":"http://localhost:8031",
}

http 走 8030 的代理,https 走 8031 的代理,這裡要注意和用 requests 使用代理的區別 requests 是下面這樣用的

proxies={
"http":"http://localhost:8030",
"https":"http://localhost:8030",
}

綜合使用

你還可以配置多個規則像下面這

proxies={
#Routealltrafficthroughaproxybydefault...
"all://":"http://localhost:8030",
#Butdon'tuseproxiesforHTTPSrequeststo"domain.io"...
"https://domain.io":None,
#Anduseanotherproxyforrequeststo"example.com"anditssubdomains...
"all://*example.com":"http://localhost:8031",
#AndyetanotherproxyifHTTPisused,
#andthe"internal"subdomainonport5550isrequested...
"http://internal.example.com:5550":"http://localhost:8032",
}

代理就這些,下面看看它的連結池的問題
你可以使用 Client 的關鍵字引數 limits 來控制連線池的大小。它需要以下例項httpx.Limits 來定義:

  • max_keepalive,允許的保持活動連線數或 None 始終允許。(預設10)

  • max_connections,允許的最大連線數或 None 無限制。(預設為100)

limits=httpx.Limits(max_keepalive_connections=5,max_connections=10)
client=httpx.Client(limits=limits)

如果預設連結數不夠用的就自己重新設定吧。(我感覺是不夠

我這邊只關注了爬蟲可能用到的部分,其他的大家可以看看官網。比如怎麼搭配flask使用等。

好了關於httpx的同步請求的內容大概就這些要提的。如果只講到這裡,你肯定會說,"就這,用 requests 不香麼?",emmm,如果這麼想你就錯了,要知道它不僅支援同步還支援非同步的,使用起來比 aiohttp 簡單多了,這才是我推薦的目的。

httpx 之非同步請求

要知道官網可是單獨把它拎出一節講的,可以看出裡面應該有點東西。
廢話少說,開整。

我們先看在 aiohttp 中是如何建立併發送請求的

importaiohttp
importasyncio

asyncdefmain():
asyncwithaiohttp.ClientSession()asclient:
asyncwithclient.get('http://httpbin.org/get')asresp:
assertresp.status==200
html=awaitresp.text()
print(html)

我們需要使用兩個 async with 來完成一個請求,然後我們看看 httpx 怎麼實現的呢

asyncwithhttpx.AsyncClient()asclient:
resp=awaitclient.get('http://httpbin.org/get')
assertresp.status_code==200
html=resp.text

感覺總體上比較 aiohttp 寫起來舒服多了,少寫很多非同步程式碼。
之前使用 aiohttp 中的 resp.status 來獲取狀態碼的時候寫了status_code,應該是使用 requests 習慣了吧,這下好了使用 httpx 不用擔心這個寫錯的問題了。

後記

最近,我剛把我之前的那個 discogs_aio_spider 的專案給改了,之前用的aiohttp,我現在改成 httpx,對 httpx 感興趣的朋友,可以到上面研究下我這個專案,有問題歡迎提出。