4人参与 • 2026-08-03 • Python
httpx是python 的下一代 http 客户端。(官网自称)
httpx 是一个功能全面的 python 3 http 客户端,提供同步和异步 api,并支持 http/1.1 和 http/2。
我们就将官网的特性逐一进行讲解。
httpx 的设计目标之一是让熟悉 requests 库的用户几乎无需学习成本就能上手。它的核心 api(如 httpx.get(), httpx.post(), response.text, response.json() 等)与 requests 几乎一致。
# requests 风格
import httpx
resp = httpx.get("https://httpbin.org/get")
print(resp.status_code)
print(resp.json())
这段代码和用 requests 写法几乎一样,说明兼容性很好。
httpx 同时提供了 同步客户端(httpx.client) 和 异步客户端(httpx.asyncclient)。
import httpx
with httpx.client() as client:
r = client.get("https://httpbin.org/delay/1")
print(r.status_code)
import asyncio
import httpx
async def main():
async with httpx.asyncclient() as client:
r = await client.get("https://httpbin.org/delay/1")
print(r.status_code)
asyncio.run(main())
httpx 默认使用 http/1.1,但如果目标服务器支持 http/2 且你安装了 httpx[http2](即 pip install httpx[http2]),它会自动协商使用 http/2。http/2 支持多路复用、头部压缩等,性能更好。
import httpx
# 需先安装: pip install httpx[http2]
with httpx.client(http2=true) as client:
r = client.get("https://http2.pro/")
print("using http/2:", r.http_version == "http/2")
通常我们通过网络(如 http://localhost:8000)测试 web 应用。但 httpx 可以绕过网络层,直接调用 python 的 wsgi(如 flask/django)或 asgi(如 fastapi/starlette)应用对象,用于单元测试或集成测试,速度更快、更可靠。
wsgi(web server gateway interface)
(1)诞生时间:2003 年(python 社区标准,pep 3333)
(2)作用:定义了一个标准接口,让 python web 框架(如 flask、django)和 web 服务器(如 gunicorn、uwsgi)能够互相通信。
(3)特点:
同步:每个请求必须等前一个处理完才能开始。
不支持 websocket、长连接、http/2。
只处理 http。
(4)典型框架:flask、django(默认模式)、bottle。
asgi(asynchronous server gateway interface)
(1)诞生时间:2017 年左右(为支持现代 web 需求而生)
(2)作用:wsgi 的异步超集,同样是一个标准接口,但支持异步 i/o 和多种协议。
(3)特点:
异步:一个请求等待数据库时,可以去处理另一个请求。
支持 websocket、http/2、sse(服务器推送)等。
向后兼容 wsgi(可通过适配器运行 wsgi 应用)。
(4)典型框架:fastapi、starlette、quart(异步版 flask)、django 3.0+(部分支持)。
from flask import flask
import httpx
from werkzeug.test import client as wsgiclient
from httpx._transports.wsgi import wsgitransport
app = flask(__name__)
@app.route("/hello")
def hello():
return {"msg": "hi"}
# 使用 httpx 直接调用 wsgi app
transport = wsgitransport(app=app)
with httpx.client(transport=transport, base_url="http://testserver") as client:
r = client.get("/hello")
print(r.json()) # {'msg': 'hi'}
from fastapi import fastapi
import httpx
from httpx._transports.asgi import asgitransport
app = fastapi()
@app.get("/hello")
def hello():
return {"msg": "hi"}
transport = asgitransport(app=app)
with httpx.client(transport=transport, base_url="http://testserver") as client:
r = client.get("/hello")
print(r.json())
这对测试非常有用,无需启动真实服务器。
httpx 允许你设置连接超时(connect)、读取超时(read)、写入超时(write) 和连接池超时(pool)。默认超时是 5 秒,可通过 timeout 参数精细控制。
import httpx
# 设置所有阶段超时为 3 秒
try:
r = httpx.get("https://httpbin.org/delay/5", timeout=3.0)
except httpx.timeoutexception:
print("请求超时!")
也可以分别设置:
timeout = httpx.timeout(connect=1.0, read=2.0, write=1.0, pool=5.0)
r = httpx.get("https://example.com", timeout=timeout)
比 requests 的超时控制更细粒度(requests 只有 connect + read)。
# 连接超时+读超时 response = requests.get(url, timeout=5) # 分别设置连接超时和读超时。第一个数字是连接超时时间(connect timeout),第二个数字是读取超时时间(read timeout) response = requests.get(url, timeout=(3, 5))
httpx 所有函数、类、方法都带有 pep 484 类型提示(type hints),配合 mypy 或 ide(如 pycharm、vscode)可实现静态类型检查,减少 bug。
def fetch(url: str) -> httpx.response:
return httpx.get(url)
resp: httpx.response = fetch("https://example.com")
ide 能自动提示 resp.status_code 是 int,resp.text 是 str 等。
这是指 httpx 的源代码每一行都被单元测试覆盖到(通过工具如 pytest-cov 验证)。这不保证没有 bug,但说明开发者非常重视质量,变更不易引入回归问题。
📌 这属于项目质量指标,对用户透明,但让你用得更放心。
接下来这些其实是 requests 的经典功能,httpx 也都支持:
支持包含非 ascii 字符的域名,如 https://例子.测试,httpx 会自动将其转换为 punycode(如 xn–fsq.xn–0zwm56d)。
互联网早期,域名只允许使用 ascii 字符(a-z, 0-9, -)。
但中文、阿拉伯文、俄文等用户也希望用自己的语言注册域名,比如:
https://例子.测试
但 dns 系统(域名解析底层)不认非 ascii 字符!
于是,人们发明了 punycode —— 一种编码规则,把 unicode 域名转换成纯 ascii 字符串。
import httpx # 注意:这个域名可能不存在,仅演示编码 url = "https://例子.测试" print(httpx.url(url)) # 自动转为 punycode 形式
✅ 实际请求时,dns 解析会处理转换。
httpx 会复用 tcp 连接(http keep-alive),避免每次请求都新建连接。client 对象内部维护连接池,提升性能。
import httpx
with httpx.client() as client:
for _ in range(3):
r = client.get("https://httpbin.org/get")
print(r.status_code)
# 三次请求复用同一个连接(如果服务器支持)
client 会自动保存服务器返回的 cookie,并在后续请求中自动携带。
import httpx
with httpx.client() as client:
# 第一次请求设置 cookie
client.get("https://httpbin.org/cookies/set?name=value")
# 第二次请求自动带 cookie
r = client.get("https://httpbin.org/cookies")
print(r.json()) # {'cookies': {'name': 'value'}}
默认启用 ssl 证书验证(使用系统 ca 证书),防止中间人攻击。和浏览器一样严格。
r = httpx.get("https://github.com") # 验证通过
r = httpx.get("https://self-signed.badssl.com", verify=false)
✅ 安全默认开启。
支持 http basic auth 和 digest auth。
r = httpx.get("https://httpbin.org/basic-auth/user/pass", auth=("user", "pass"))
print(r.status_code) # 200 if ok
# 需要服务器支持 digest auth
auth = httpx.digestauth("user", "pass")
r = httpx.get("https://httpbin.org/digest-auth/auth/user/pass", auth=auth)
可手动设置 cookie,像字典一样操作。
cookies = {"session_id": "abc123"}
r = httpx.get("https://httpbin.org/cookies", cookies=cookies)
print(r.json())
如果服务器返回 gzip、deflate 等压缩内容,httpx 会自动解压,你拿到的是原始内容。
r = httpx.get("https://httpbin.org/gzip")
print(r.json()["gzipped"]) # true,但你无需手动解压
根据响应头的 content-type(如 charset=utf-8),自动将 bytes 解码为 str(通过 .text 属性)。
r = httpx.get("https://httpbin.org/encoding/utf8")
print(type(r.text)) # <class 'str'>
支持任意 unicode 字符,不会乱码(前提是服务器正确声明编码)。
支持 multipart/form-data 上传文件,类似 html 表单。
files = {"file": ("test.txt", b"hello world")}
r = httpx.post("https://httpbin.org/post", files=files)
print(r.json()["files"])
也可上传真实文件:
with open("test.txt", "rb") as f:
files = {"file": f}
r = httpx.post("https://httpbin.org/post", files=files)
可通过 proxies 参数设置 http/https/socks 代理。
proxies = {"http://": "http://10.10.1.10:3128", "https://": "http://10.10.1.10:3128"}
r = httpx.get("https://example.com", proxies=proxies)
已在上面第 5 条“严格的全局超时控制”中涵盖。只是比requests更加细致。
对于大文件,可逐块(chunk)读取,避免一次性加载到内存。
with httpx.stream("get", "https://httpbin.org/stream-bytes/1024") as r:
for chunk in r.iter_bytes(chunk_size=128):
print(len(chunk)) # 每次 128 字节
如果存在 ~/.netrc 文件,httpx 会自动读取其中的认证信息(用户名/密码)用于对应域名。
.netrc 是一个“自动填账号密码”的小本本,放在你电脑的家目录里,专门给命令行工具(比如 curl、httpx、ftp)用,避免每次都要手动输用户名和密码。
⚠️ 注意:这个文件必须权限设为 600(仅自己可读写),否则很多工具会拒绝使用(安全考虑):
chmod 600 ~/.netrc
machine httpbin.org login alice password secret123 machine api.example.com login bob password mypass456
每一组由三行组成:
你可以为多个网站分别配置。
# 没有 .netrc 时,你必须在代码里写死账号密码(不安全!)
r = httpx.get("https://httpbin.org/basic-auth/alice/secret123", auth=("alice", "secret123"))
但如果你把账号密码写在代码里:
# 代码干净又安全!
r = httpx.get("https://httpbin.org/basic-auth/alice/secret123")
只要 .netrc 里配了 machine httpbin.org 的账号密码,httpx 会自动读取并加上 basic auth 头!
machine httpbin.org login user password pass
然后
r = httpx.get("https://httpbin.org/basic-auth/user/pass") # 自动带 auth
当你发送的数据长度未知时,可使用分块传输(无需提前知道 content-length)。
def data_generator():
yield b"part1"
yield b"part2"
r = httpx.post("https://httpbin.org/post", content=data_generator())
httpx = requests 的易用性 + 异步 + http/2 + 类型安全 + 现代架构。
无论是写脚本、做测试、还是构建高性能服务,它都是目前 python 最先进的 http 客户端之一。
到此这篇关于python的下一代http客户端httpx特性的文章就介绍到这了,更多相关python客户端httpx特性内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论