HTTPX 是一个功能齐全的 Python 3 HTTP 客户端,提供同步和异步 API,并支持 HTTP/1.1 和 HTTP/2。
介绍
- 支持 Python 3.8+
- HTTPX 是 Requests 的后继者,旨在提供更强大、更灵活的 HTTP 客户端
- 支持 HTTP/1.1 和 HTTP/2
- 广泛兼容请求的 API
- 标准同步接口,但在需要时也支持异步
- HTTPX 支持 HTTP/1.1 和 HTTP/2,并且可以与异步编程模型(如 asyncio)一起使用
- 可直接向 WSGI 应用程序或 ASGI 应用程序发出请求。
- 处处严格超时
- 完全类型注释
- 100% 测试覆盖率
- 加上请求的所有标准功能…
- 保持长效和连接池
- 会话与 Cookie 持久性
- 浏览器式 SSL 验证
- 基本/数字验证
- 优雅的密钥/值 Cookie
- 自动解压缩
- 自动内容解码
- Unicode 响应体
- 多部分文件上传
- HTTP(S) 代理支持
- 连接超时
- 流式下载
- 支持
.netrc
- 分块请求
安装
pip install httpx
pip install 'httpx[socks]'
pip install 'httpx[http2]'
pip install 'httpx[brotli,zstd]'
使用
同步请求
import httpx
# 发送 GET 请求
response = httpx.get('https://www.xiexianbin.cn')
print(response)
# <Response [200 OK]>
print(response.status_code)
# 200
print(response.headers['content-type'])
# text/html
print(response.text)
# 发送 POST 请求
data = {'key': 'value'}
response = httpx.post('https://www.xiexianbin.cn', data=data)
print(response.text)
# 发送 PUT 请求
response = httpx.put('https://www.xiexianbin.cn', data=data)
print(response.text)
# 发送 DELETE 请求
import httpx
import json
url = 'https://httpbin.org/post'
data = {'key1': 'value1'}
headers = {'Content-Type': 'application/json'}
try:
# 创建一个 Client 实例
with httpx.Client() as client:
# 使用 client.post() 发送 POST 请求
response = client.post(url, json=data, headers=headers)
response.raise_for_status() # 检查请求是否成功
print(response.json())
except httpx.HTTPStatusError as e:
print(f"请求出错: {e.response.status_code} - {e}")
except httpx.RequestError as e:
print(f"请求出错: {e}")
关键点:
with httpx.Client() as client::创建一个 Client 会话。使用 with 语句可以确保在代码块结束后正确关闭连接,释放资源。
client.post(...):Client 实例的方法与 requests 模块的函数非常相似,参数也基本一致。
- 异常处理:
httpx 的异常类与 requests 不同,需要使用 httpx.HTTPStatusError 和 httpx.RequestError 来捕获不同的错误类型。
异步请求
如果您正在构建一个需要处理多个并发请求的应用程序(例如 Web 服务器或爬虫),异步方法会更高效。httpx 的一个主要优势就是其对异步的支持。
同步代码(如上)
使用 httpx.AsyncClient 进行异步重写:
import httpx
import asyncio
import json
async def make_async_post_request():
url = 'https://httpbin.org/post'
data = {'key1': 'value1'}
headers = {'Content-Type': 'application/json'}
try:
# 创建一个 AsyncClient 实例
async with httpx.AsyncClient() as client:
# 使用 await client.post() 发送异步 POST 请求
response = await client.post(url, json=data, headers=headers)
response.raise_for_status() # 检查请求是否成功
print(response.json())
except httpx.HTTPStatusError as e:
print(f"请求出错: {e.response.status_code} - {e}")
except httpx.RequestError as e:
print(f"请求出错: {e}")
# 运行异步函数
if __name__ == '__main__':
asyncio.run(make_async_post_request())
关键点:
async with httpx.AsyncClient() as client::使用 AsyncClient 创建异步会话,同样使用 with 语句来管理连接。
await client.post(...):在调用异步方法时,必须在前面加上 await 关键字,并且该调用必须在一个 async 函数内部。
asyncio.run(...):使用 asyncio 库来运行顶层异步函数。
对比
| 特性 |
httpx.Client |
httpx.AsyncClient |
| 行为 |
同步 (Synchronous) |
异步 (Asynchronous) |
| I/O 模型 |
阻塞 (Blocking) |
非阻塞 (Non-blocking) |
| 使用方式 |
直接调用方法,如 client.get() |
需配合 async/await,如 await client.get() |
| 适用场景 |
简单脚本、Web 爬虫、API 测试、不需要高并发的后端应用 |
高并发场景,如需要同时处理大量网络请求的 Web 服务、爬虫等 |
| 类似库 |
requests |
aiohttp |
命令行
pip install 'httpx[cli]'
$ httpx http://httpbin.org/json
HTTP/1.1 200 OK
Date: Sun, 10 Nov 2024 08:27:48 GMT
Content-Type: application/json
Content-Length: 429
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
{
"slideshow": {
"author": "Yours Truly",
"date": "date of publication",
"slides": [
{
"title": "Wake up to WonderWidgets!",
"type": "all"
},
{
"items": [
"Why <em>WonderWidgets</em> are great",
"Who <em>buys</em> WonderWidgets"
],
"title": "Overview",
"type": "all"
}
],
"title": "Sample Slide Show"
}
}
F&Q
发送大文件慢的问题
参考 https://github.com/encode/httpx/pull/3661