程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python新一代網絡庫HTTPX

編輯:Python

背景

最近在寫一個自動化腳本,從某電商網站批量獲取手機設備信息參數,基於python + requests完成腳本開發,但是實際運行效率上並不是特別滿意。無意中看到了HTTPX,在功能性和效率性上,給了我眼前一亮的感覺。

本文就來揭秘HTTPX的基本使用和高級特性用法。

介紹

HTTPX是Python3的全功能HTTP客戶端,它提供同步和異步API,並支持HTTP/1.1和HTTP/2。

根據官網的描述,總結有如下特點:

  • 和使用 requests 一樣方便,requests 有的它都有
  • 加入 HTTP/1.1 和 HTTP/2 的支持。
  • 能夠直接向 WSGI 應用程序或 ASGI 應用程序發出請求。
  • 到處都有嚴格的超時設置
  • 全類型注釋
  • 100% 的測試覆蓋率

github介紹:https://github.com/encode/httpx

文檔介紹:https://www.python-httpx.org/

安裝

httpx的安裝很簡單,直接pip就完事了。

安裝命令如下:

pip install httpx

httpx還支持命令行方式,需要安裝httpx[cli]

pip install 'httpx[cli]'

使用例子:

httpx http://httpbin.org/json

基本使用

get請求和post請求,直接導包然後get方法或者post方法就行了。使用方式和requests庫很類似。

get請求

需要的請求參數和requests庫的get請求參數差不多,也支持代理模式發送請求、重定向、證書認證等。

代碼如下:

r = httpx.get('http://www.baidu.com')
print(r.status_code)

post請求

post請求對於json、formdata、files類型支持也比較全面。

代碼如下:

r = httpx.post(url='http://api.bakend.com/saveResult',json={'name':'mike'})
print(r.json())

其他方式請求

r = httpx.delete('http://www.baidu.com')
r = httpx.put('http://www.baidu.com')
r = httpx.head(''http://www.baidu.com')
r = httpx.options('http://www.baidu.com')

以上就是基本使用方式,這裡並沒有什麼特別之處,我們接著放下看。

高階使用

客戶端實例

如果使用來自requests,httpx.Client()可以使用它來代替requests.Session()。主要優勢是更有效地利用網絡資源,當發出API請求請求時,HTTPX會為為每個請求建立一個新連接(連接不被重)。隨著對主機的請求數量增加,這很快就會變得低效。

另一方面,Client實例使用HTTP連接池。這意味著當向同一主機發出多個請求時,Client將重用底層TCP連接,而不是為每個請求重新創建一個。

這可以帶來顯著的性能提升:

  • 減少請求之間的延遲(無握手)。
  • 減少 CPU 使用率和往返次數。
  • 減少網絡擁塞。

代碼如下:

Client是作為上下文管理器。with這將確保在離開塊時正確清理連接。

with httpx.Client() as client:
headers = {'os': 'Android'}
r = client.get('https://www.baidu.com', headers=headers)

或者,可以使用以下命令顯式關閉連接池而不使用阻塞.close():

client = httpx.Client()
try:
client.get('https://www.baidu,com')
finally:
client.close()

異步請求

使用過requests庫的同學應該知道,它在處理批量請求、爬蟲等場景,需要循環等待每個請求發送完成腳本,在效率方面表現的一般。

HTTPX可以使用異步方式發送網絡請求,異步是一種比多線程更高效的並發模型,並且可以提供顯著的性能優勢並支持使用長壽命的網絡連接,例如WebSockets。

要發出異步請求,需要一個AsyncClient,使用await關鍵字修飾get方法。

async def get_result():
async with httpx.AsyncClient() as client:
resp = await client.get('http://httpbin.org/get')
assert resp.status_code == 200
html = resp.text
asyncio.run(get_result())

請求耗時對比

這裡主要使用HTTPX異步請求和request的請求,做一個請求耗時對比。

request的Session方式

def request_post_json():
print('----------- 同步請求 -----------')
url = host + "/responseTime/insert"
headers = {
'Content-Type': 'application/json',
}
payload = {}
payload['taskname'] = '響應測試'
payload['appnname'] = 999
payload['platform'] = platform.Android.value
payload['scenes'] = scenes.home.value
payload['videocount'] = 5 # 視頻個數
payload['grouptime'] = ','.join(["11.5", "11.6", "11.3"]) # 耗時數組
payload['avgtime'] = 5.55 # 平均耗時
payload['author'] = 'xinxi'
print(json.dumps(payload, indent=4))
r = requests.Session()
response = r.post(url, headers=headers, json=payload)
print(response.text)
for i in range(100):
request_post_json()
endTime = time.time()
print(endTime - startTime)

耗時:

15.002s

HTTPX異步請求

async def httpx_post_json():
print('----------- 異步請求 -----------')
url = host + "/responseTime/insert"
print(url)
headers = {
'Content-Type': 'application/json',
}
payload = {}
payload['taskname'] = '響應測試'
payload['appnname'] = 99
payload['platform'] = platform.Android.value
payload['scenes'] = scenes.home.value
payload['videocount'] = 5 # 視頻個數
payload['grouptime'] = ','.join(["11.5", "11.6", "11.3"]) # 耗時數組
payload['avgtime'] = 5.55 # 平均耗時
payload['author'] = 'xinxi'
async with httpx.AsyncClient() as client:
resp = await client.post(url, headers=headers, json=payload)
assert resp.status_code == 200
html = resp.text
print(html)
startTime = time.time()
loop = asyncio.get_event_loop()
task = [httpx_post_json() for i in range(100)] # 把任務放入數組,准備給事件循環器調用
loop.run_until_complete(asyncio.wait(task))
loop.close()
endTime = time.time()
print(endTime - startTime)

耗時:

3.070s

可以看出HTTPX異步請求方式明顯比request的請求耗時降低了很多。

結語

以上就是HTTPX的一些使用分享,在實際工作中能替代requests完成工作。另外,加持高級用法,更可以極大提高工作效率。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved