Python httpx同步异步请求与HTTP/2客户端开发指南
httpx 是一个功能强大且现代化的 Python HTTP 客户端库,支持同步和异步请求,并兼容 requests API。除基础请求外,它还提供 HTTP/2、连接池、细粒度超时控制、代理、认证、流式响应以及实验性 WebSocket 等能力。本文围绕 httpx 的安装、核心特性、同步/异步用法、高级配置、异常处理以及与 requests 的差异进行整理,适合需要在脚本、爬虫、后端服务或自动化任务中落地 HTTP 请求的开发者参考。一、安装 httpx
pip install httpx
pip install httpx
第一条命令安装 httpx;如果需要 HTTP/2 支持,需要额外安装依赖。
二、核心特性
1. 同步与异步双模式:同步使用 httpx,异步使用 AsyncClient。
2. HTTP/2 支持:默认优先使用 HTTP/2,但需要服务端支持。
3. 类型提示:完善的类型注解,提升代码可读性和 IDE 支持。
4. 连接池:复用 TCP 连接,减少握手开销。
5. 超时控制:细粒度设置连接、读取、写入超时。
6. 代理与认证:支持 HTTP/HTTPS/SOCKS 代理,以及 Basic/Digest/OAuth 认证。
7. 流式请求/响应:适合大文件上传和下载。
8. WebSocket 支持:实验性支持 WebSocket 协议。
三、基本用法
1. 同步请求
快捷方式适合简单请求:
import httpx
response = httpx.get('https://httpbin.org/get')
print(response.status_code)# 200
print(response.json()) # 解析 JSON 响应
如果要复用连接,推荐使用 Client:
import httpx
with httpx.Client() as client:
response = client.get('https://httpbin.org/get')
print(response.text)
常用方法包括:
get(url, params=...):GET 请求。
post(url, data=..., json=...):POST 请求,data 传表单,json 传 JSON。
put()、delete()、patch():其他请求方法。
head()、options():HEAD 和 OPTIONS 请求。
2. 异步请求
异步请求需要配合 async/await 语法,适合高并发场景:
import asyncio
import httpx
async def fetch():
async with httpx.AsyncClient() as client:
response = await client.get('https://httpbin.org/get')
print(response.json())
asyncio.run(fetch())
如果要在异步环境中并发多个请求,可以用 asyncio.gather:
import asyncio
import httpx
async def main():
urls = ['https://httpbin.org/get'] * 5
async with httpx.AsyncClient() as client:
tasks =
responses = await asyncio.gather(*tasks)
for resp in responses:
print(resp.status_code)
asyncio.run(main())
四、高级配置
1. 超时设置
可以针对单个请求设置超时,单位是秒:
import httpx
response = httpx.get('https://httpbin.org/delay/2', timeout=5.0)
也可以细粒度控制连接、读取、写入和连接池超时:
import httpx
timeout = httpx.Timeout(connect=5, read=10, write=2, pool=1)
response = httpx.get('https://httpbin.org/delay/2', timeout=timeout)
with httpx.Client(timeout=timeout) as client:
client.get('https://httpbin.org/delay/2')
其中 connect 是连接超时,read 是读取超时,write 是写入超时,pool 是连接池获取超时。
2. 请求头与查询参数
headers 传字典,params 传字典,params 会被自动编码:
import httpx
headers = {'User-Agent': 'my-app/1.0'}
params = {'key1': 'value1', 'key2': 'value2'}
response = httpx.get(
'https://httpbin.org/get',
headers=headers,
params=params
)
# 实际请求 URL:
# https://httpbin.org/get?key1=value1&key2=value2
3. POST 表单与 JSON
表单数据用 data 参数,JSON 数据用 json 参数。json 参数会自动序列化并设置 Content-Type: application/json:
import httpx
data = {'username': 'test', 'password': '123'}
response = httpx.post('https://httpbin.org/post', data=data)
json_data = {'name': 'Alice', 'age': 30}
response = httpx.post('https://httpbin.org/post', json=json_data)
4. 文件上传
files 参数可以传单文件或多文件。单文件上传:
import httpx
with open('file.txt', 'rb') as f:
files = {'file': ('file.txt', f, 'text/plain')}
response = httpx.post('https://httpbin.org/post', files=files)
多文件上传:
import httpx
files = [
('images', ('img1.jpg', open('img1.jpg', 'rb'), 'image/jpeg')),
('images', ('img2.png', open('img2.png', 'rb'), 'image/png'))
]
response = httpx.post('https://httpbin.org/post', files=files)
files 中元组的含义是:字段名、文件名、文件对象和 MIME 类型。
5. 代理设置
httpx 支持 HTTP、HTTPS、SOCKS 代理:
import httpx
proxies = {
'http://': 'http://user:pass@proxy:8080',
'https://': 'https://user:pass@proxy:443',
'all://': 'socks5://user:pass@socks-proxy:1080'
}
client = httpx.Client(proxies=proxies)
response = httpx.get('https://httpbin.org/ip', proxies=proxies)
其中 all:// 表示所有协议都走 SOCKS5 代理。
6. 认证
httpx 支持 Basic、Digest、OAuth 等认证方式。Basic 认证示例:
import httpx
from httpx import BasicAuth
auth = BasicAuth(username='user', password='pass')
response = httpx.get('https://httpbin.org/basic-auth/user/pass', auth=auth)
# 也可以直接传元组,自动识别为 BasicAuth
response = httpx.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))
7. 流式响应
处理大文件下载时,可以通过流式读取避免一次性加载到内存:
import httpx
with httpx.stream('GET', 'https://httpbin.org/stream/20') as response:
for chunk in response.iter_bytes(chunk_size=1024):
print(len(chunk))
iter_bytes 会按 chunk_size 逐块读取,适合边下载边写入文件或做实时处理。
五、异常处理
httpx 定义了多个异常类,实际开发中应捕获特定异常,而不是直接捕获通用 Exception。常见异常如下:
httpx.RequestError:网络层错误,例如 DNS 失败、连接拒绝。
httpx.HTTPStatusError:响应状态码非 2xx,需要手动触发。
httpx.TimeoutException:超时错误。
httpx.ConnectError:连接错误。
httpx.ReadError:读取响应错误。
示例:
import httpx
try:
response = httpx.get('https://httpbin.org/status/404')
response.raise_for_status()
except httpx.HTTPStatusError as e:
print(f'HTTP 错误: {e.response.status_code}')
except httpx.RequestError as e:
print(f'请求错误: {e}')
except httpx.TimeoutException:
print('请求超时')
这里的 raise_for_status() 会在状态码非 2xx 时抛出 HTTPStatusError。排查时可以先区分是网络层错误、连接错误、读取错误还是超时,再针对代理、DNS、服务端响应和超时参数逐项检查。
六、与 requests 对比
异步支持:requests 不支持,httpx 原生支持 AsyncClient。
HTTP/2 支持:requests 不支持,httpx 支持,但需要安装依赖。
连接池:requests 有基础支持,httpx 提供更高效的连接池管理。
类型提示:requests 有限,httpx 更完善。
WebSocket:requests 不支持,httpx 为实验性支持。
七、总结
httpx 可以看作 requests 的现代替代品,尤其适合需要异步、HTTP/2 或更高性能的场景。它的 API 设计与 requests 兼容,学习成本较低,同时提供更强大的扩展能力。对于新项目,可以优先考虑 httpx;如果只是简单同步请求,并且不需要 HTTP/2,requests 仍然足够稳定。
Re: Python httpx同步异步请求与HTTP/2客户端开发指南
感谢分享,整理得挺全面。同步和异步双模式、Client 与 AsyncClient 复用连接、以及超时细分到 connect、read、write、pool 这些点,对写爬虫和后端请求都很有参考价值。异步并发那段用 asyncio.gather 也很直观,实际跑批量任务时确实比一个个 await 高效。 有两个小地方想请教一下:一是 httpx 安装后,是不是还需要在 Client 或 AsyncClient 里显式开启 HTTP/2,如果能补一句就更完整了;二是实验性 WebSocket 目前适合放到生产脚本里吗,还是先观望比较好? 另外文件上传部分好像刚好截断了,期待后续把 files、流式上传下载以及异常处理补全,尤其是超时、连接错误这些怎么分类捕获。整体内容很实用,先收藏了。Re: Python httpx同步异步请求与HTTP/2客户端开发指南
整理得挺系统的,安装、双模式、HTTP/2、连接池、超时、代理认证、流式这些点都带到了。对我比较有用的是 Client 和 AsyncClient 的用法区分,以及 asyncio.gather 并发请求的示例,日常写爬虫或自动化任务很容易直接套。细粒度 Timeout 那段也很实用,connect、read、write、pool 分开设置,排查卡住位置会清晰不少。另外 HTTP/2 需要额外装依赖、并且需要服务端支持这一点也提醒得很到位。文件上传部分看起来还没贴完,期待后面把流式、异常处理和与 requests 的差异继续补齐。Re: Python httpx同步异步请求与HTTP/2客户端开发指南
这篇整理得挺系统,安装部分把 http2 额外依赖单独拎出来很实用。同步快捷方法和 Client 复用的区别、异步里 AsyncClient 配合 asyncio.gather 并发,都讲得比较直观;超时里 connect、read、write、pool 的拆分和 data 与 json 的区分也是容易踩坑的地方。正文好像停在文件上传示例,期待后面把流式请求响应、代理认证、异常处理以及和 requests 的差异补完。实际用时我会记得长连接和并发场景优先复用 Client 或 AsyncClient,避免每次快捷请求都重新建连。
页:
[1]