Python 實(shí)現(xiàn)HTTP Client 的常見(jiàn)方式總覽
一、Python 實(shí)現(xiàn) HTTP Client 的常見(jiàn)方式總覽
Python 常見(jiàn) HTTP Client 實(shí)現(xiàn)方式:
| 類型 | 代表庫(kù) | 是否異步 | 推薦程度 |
|---|---|---|---|
| 標(biāo)準(zhǔn)庫(kù) | urllib | 否 | (了解即可) |
| 第三方同步 | requests | 否 | |
| 第三方現(xiàn)代同步/異步 | httpx | 支持 | (強(qiáng)烈推薦) |
| 異步高性能 | aiohttp | 是 | |
| 框架內(nèi)置 | FastAPI / Django 內(nèi)部 client | 視情況 | 場(chǎng)景依賴 |
| 底層 | socket | 否 | (特殊場(chǎng)景) |
二、urllib(標(biāo)準(zhǔn)庫(kù))
1. 是什么?
Python 標(biāo)準(zhǔn)庫(kù)自帶的 HTTP 工具。
import urllib.request
不需要安裝第三方庫(kù)。
2. 有什么用?
- 基礎(chǔ) HTTP 請(qǐng)求
- 簡(jiǎn)單下載文件
- 受限環(huán)境下使用(如不能安裝第三方庫(kù))
3. 怎么用?
import urllib.request
import json
url = "https://api.example.com/data"
req = urllib.request.Request(url, method="GET")
with urllib.request.urlopen(req) as response:
data = response.read()
print(json.loads(data))POST 示例:
import urllib.parse
data = urllib.parse.urlencode({"key": "value"}).encode()
req = urllib.request.Request(url, data=data, method="POST")4. 如何優(yōu)雅地用?
? 不優(yōu)雅點(diǎn):
- API 復(fù)雜
- 異常處理繁瑣
- JSON 解析不自動(dòng)
- 沒(méi)有 session 管理
建議:
- 僅用于腳本
- 不用于生產(chǎn)服務(wù)
5. 適用場(chǎng)景
- 無(wú)法安裝第三方庫(kù)
- 教學(xué)
- 簡(jiǎn)單腳本
三、requests(最常用同步方案)
1. 是什么?
Python 最流行的 HTTP 庫(kù)。
pip install requests
2. 有什么用?
- 微服務(wù)調(diào)用
- 第三方 API 調(diào)用
- 簡(jiǎn)單同步 HTTP 請(qǐng)求
- 內(nèi)部工具系統(tǒng)
3. 怎么用?
基本 GET
import requests
resp = requests.get("https://api.example.com/data")
print(resp.status_code)
print(resp.json())POST
resp = requests.post(
"https://api.example.com/login",
json={"username": "pan", "password": "123"},
timeout=5
)
4. 如何優(yōu)雅地用?
使用 Session 復(fù)用連接
session = requests.Session()
session.headers.update({
"Authorization": "Bearer token"
})
resp = session.get("https://api.example.com/data")好處:
- TCP 連接復(fù)用
- 性能提升
- 統(tǒng)一 header 管理
設(shè)置 timeout(必須)
requests.get(url, timeout=(3, 10)) # (connect, read)
否則:
- 可能無(wú)限阻塞
- 生產(chǎn)事故常見(jiàn)坑
異常處理規(guī)范
try:
resp = requests.get(url, timeout=5)
resp.raise_for_status()
except requests.exceptions.Timeout:
...
except requests.exceptions.RequestException:
...
? requests 的問(wèn)題
- 不支持原生 async
- 高并發(fā)場(chǎng)景性能差
- 不適合 IO 密集型服務(wù)
5. 適用場(chǎng)景
| 場(chǎng)景 | 是否推薦 |
|---|---|
| 內(nèi)部工具 | |
| 管理后臺(tái) | |
| 高并發(fā)服務(wù) | ? |
| 異步框架 | ? |
四、httpx(現(xiàn)代最佳實(shí)踐)
強(qiáng)烈推薦 3 年經(jīng)驗(yàn)工程師重點(diǎn)掌握
1. 是什么?
- requests 的升級(jí)版
- 支持同步 + 異步
- 支持 HTTP/2
- API 風(fēng)格接近 requests
pip install httpx
2. 有什么用?
- 微服務(wù)調(diào)用
- 異步高并發(fā)系統(tǒng)
- 替代 requests
- Tornado / FastAPI 等場(chǎng)景
3. 怎么用?
同步用法
import httpx
with httpx.Client(timeout=5.0) as client:
resp = client.get("https://api.example.com/data")
print(resp.json())異步用法(重點(diǎn))
import httpx
import asyncio
async def main():
async with httpx.AsyncClient(timeout=5.0) as client:
resp = await client.get("https://api.example.com/data")
print(resp.json())
asyncio.run(main())4. 如何優(yōu)雅地用(重點(diǎn))
1. 全局復(fù)用 Client
? 錯(cuò)誤寫法:
async def handler():
async with httpx.AsyncClient() as client:
await client.get(url)
這樣每次都會(huì)新建連接池。
正確寫法:
client = httpx.AsyncClient(timeout=5.0)
async def handler():
resp = await client.get(url)2. 配置連接池
limits = httpx.Limits(
max_connections=100,
max_keepalive_connections=20
)
client = httpx.AsyncClient(limits=limits)3. 分離連接超時(shí)
timeout = httpx.Timeout(
connect=3.0,
read=10.0,
write=5.0,
pool=3.0
)
4. 使用重試機(jī)制(結(jié)合 tenacity)
from tenacity import retry, stop_after_attempt
@retry(stop=stop_after_attempt(3))
async def fetch():
return await client.get(url)5. 統(tǒng)一封裝一層
推薦封裝:
class HttpClient:
def __init__(self):
self.client = httpx.AsyncClient(timeout=5.0)
async def get(self, url, **kwargs):
resp = await self.client.get(url, **kwargs)
resp.raise_for_status()
return resp.json()5. 適用場(chǎng)景
| 場(chǎng)景 | 是否推薦 |
|---|---|
| 微服務(wù)調(diào)用 | |
| 異步系統(tǒng) | |
| 高并發(fā) IO | |
| 替代 requests |
五、aiohttp(異步老牌選手)
1. 是什么?
早期 Python 異步 HTTP 主力庫(kù)。
pip install aiohttp
2. 怎么用?
import aiohttp
import asyncio
async def main():
async with aiohttp.ClientSession() as session:
async with session.get("https://api.example.com") as resp:
print(await resp.json())
asyncio.run(main())3. 特點(diǎn)
| 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|
| 性能高 | API 不如 httpx 友好 |
| 社區(qū)成熟 | 與 requests 不兼容 |
4. 適用場(chǎng)景
- 老項(xiàng)目
- 純 asyncio 系統(tǒng)
新項(xiàng)目更推薦 httpx。
六、如何優(yōu)雅地設(shè)計(jì) HTTP Client(架構(gòu)層)
這是 3 年工程師需要掌握的部分。
1. 統(tǒng)一出口
不要在業(yè)務(wù)代碼里到處寫:
httpx.get(...)
應(yīng)該:
from infra.http import http_client await http_client.get(...)
2. 加指標(biāo)埋點(diǎn)
start = time.perf_counter() resp = await client.get(url) cost = time.perf_counter() - start
記錄:
- QPS
- P50 / P99
- error_rate
3. 熔斷 & 限流
結(jié)合:
- tenacity(重試)
- aiobreaker(熔斷)
- asyncio.Semaphore(限流)
4. 不要踩的坑
| 坑 | 說(shuō)明 |
|---|---|
| 不設(shè)置 timeout | 生產(chǎn)事故高發(fā) |
| 每次新建 client | 連接爆炸 |
| 不處理異常 | 上游抖動(dòng)拖死系統(tǒng) |
| 不做限流 | 被下游打死 |
七、選型建議總結(jié)
內(nèi)部小工具
requests
微服務(wù)調(diào)用
httpx + 連接池 + 重試
高并發(fā)異步系統(tǒng)
httpx.AsyncClient
老 asyncio 項(xiàng)目
aiohttp
八、給 3 年工程師的進(jìn)階建議
你應(yīng)該掌握的不只是用法,而是:
- HTTP 連接池原理
- TCP keepalive
- TIME_WAIT 問(wèn)題
- DNS 解析緩存
- 超時(shí)分層設(shè)計(jì)(connect / read / pool)
- 上游依賴治理
九、最終推薦結(jié)論
如果你現(xiàn)在問(wèn):
2026 年 Python HTTP Client 推薦什么?
答案是:
httpx.AsyncClient
同步場(chǎng)景用:
httpx.Client
如果你愿意,我可以再給你一份:
- 面向生產(chǎn)的 HTTP Client 封裝模板
- 高并發(fā)翻譯系統(tǒng) HTTP 調(diào)優(yōu)實(shí)踐
- Tornado + httpx 的最佳實(shí)踐架構(gòu)圖
你現(xiàn)在的技術(shù)棧我大概了解一點(diǎn),如果結(jié)合你的翻譯高 IO 場(chǎng)景,我可以給你一版專門針對(duì)“高并發(fā)外部 API 調(diào)用”的優(yōu)化方案。
到此這篇關(guān)于Python 實(shí)現(xiàn) HTTP Client 的常見(jiàn)方式的文章就介紹到這了,更多相關(guān)Python HTTP Client內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python中numpy數(shù)組的計(jì)算與轉(zhuǎn)置詳解
大家好,本篇文章主要講的是Python中numpy數(shù)組的計(jì)算與轉(zhuǎn)置詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
親手教你實(shí)現(xiàn)pynq-z2條形碼識(shí)別功能
這篇文章主要介紹了pynq-z2條形碼識(shí)別功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
Python?jpg快速轉(zhuǎn)png并調(diào)整大小方式
這篇文章主要介紹了Python實(shí)現(xiàn)jpg快速轉(zhuǎn)png并調(diào)整大小方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
Python數(shù)據(jù)類型之String字符串實(shí)例詳解
這篇文章主要介紹了Python數(shù)據(jù)類型之String字符串,結(jié)合實(shí)例形式詳細(xì)講解了Python字符串的概念、定義、連接、格式化、轉(zhuǎn)換、查找、截取、判斷等常見(jiàn)操作技巧,需要的朋友可以參考下2019-05-05
pycharm中創(chuàng)建sql文件及模板的過(guò)程
很多小伙伴剛開(kāi)始使用pycharm時(shí)發(fā)現(xiàn)以前的老員工在使用pycharm創(chuàng)建sql文件時(shí)會(huì)自帶文件頭模板,例如時(shí)間、作者、版本、郵件等信息,這是怎么做到的呢,一起來(lái)看一下吧2022-07-07

