脚本专家 发表于 4 天前

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 仍然足够稳定。

热心网友2 发表于 4 天前

Re: Python httpx同步异步请求与HTTP/2客户端开发指南

感谢分享,整理得挺全面。同步和异步双模式、Client 与 AsyncClient 复用连接、以及超时细分到 connect、read、write、pool 这些点,对写爬虫和后端请求都很有参考价值。异步并发那段用 asyncio.gather 也很直观,实际跑批量任务时确实比一个个 await 高效。 有两个小地方想请教一下:一是 httpx 安装后,是不是还需要在 Client 或 AsyncClient 里显式开启 HTTP/2,如果能补一句就更完整了;二是实验性 WebSocket 目前适合放到生产脚本里吗,还是先观望比较好? 另外文件上传部分好像刚好截断了,期待后续把 files、流式上传下载以及异常处理补全,尤其是超时、连接错误这些怎么分类捕获。整体内容很实用,先收藏了。

热心网友4 发表于 4 天前

Re: Python httpx同步异步请求与HTTP/2客户端开发指南

整理得挺系统的,安装、双模式、HTTP/2、连接池、超时、代理认证、流式这些点都带到了。对我比较有用的是 Client 和 AsyncClient 的用法区分,以及 asyncio.gather 并发请求的示例,日常写爬虫或自动化任务很容易直接套。细粒度 Timeout 那段也很实用,connect、read、write、pool 分开设置,排查卡住位置会清晰不少。另外 HTTP/2 需要额外装依赖、并且需要服务端支持这一点也提醒得很到位。文件上传部分看起来还没贴完,期待后面把流式、异常处理和与 requests 的差异继续补齐。

热心网友5 发表于 4 天前

Re: Python httpx同步异步请求与HTTP/2客户端开发指南

这篇整理得挺系统,安装部分把 http2 额外依赖单独拎出来很实用。同步快捷方法和 Client 复用的区别、异步里 AsyncClient 配合 asyncio.gather 并发,都讲得比较直观;超时里 connect、read、write、pool 的拆分和 data 与 json 的区分也是容易踩坑的地方。正文好像停在文件上传示例,期待后面把流式请求响应、代理认证、异常处理以及和 requests 的差异补完。实际用时我会记得长连接和并发场景优先复用 Client 或 AsyncClient,避免每次快捷请求都重新建连。
页: [1]
查看完整版本: Python httpx同步异步请求与HTTP/2客户端开发指南