it编程 > 前端脚本 > Python

Python的下一代HTTP客户端HTTPX特性示例详解

4人参与 2026-08-03 Python

前言

httpx是python 的下一代 http 客户端。(官网自称)

httpx 是一个功能全面的 python 3 http 客户端,提供同步和异步 api,并支持 http/1.1 和 http/2。

我们就将官网的特性逐一进行讲解。

1. 广泛兼容的 requests api

解释:

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 写法几乎一样,说明兼容性很好。

2. 标准同步接口,但也支持异步操作(如有需要)

解释:

httpx 同时提供了 同步客户端(httpx.client) 和 异步客户端(httpx.asyncclient)。

同步示例:

import httpx

with httpx.client() as client:
    r = client.get("https://httpbin.org/delay/1")
    print(r.status_code)

异步示例(需在 async 环境中运行,如 jupyter 或 asyncio.run):

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())

3. 支持 http/1.1 和 http/2

解释:

httpx 默认使用 http/1.1,但如果目标服务器支持 http/2 且你安装了 httpx[http2](即 pip install httpx[http2]),它会自动协商使用 http/2。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")

4. 能够直接向 wsgi 应用 或 asgi 应用 发起请求

解释:

通常我们通过网络(如 http://localhost:8000)测试 web 应用。但 httpx 可以绕过网络层,直接调用 python 的 wsgi(如 flask/django)或 asgi(如 fastapi/starlette)应用对象,用于单元测试或集成测试,速度更快、更可靠。

wsgi 示例(flask):

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'}

asgi 示例(fastapi):

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())

这对测试非常有用,无需启动真实服务器。

5. 严格的全局超时控制

解释:

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))

6. 完整的类型注解

解释:

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 等。

7. 100% 测试覆盖率

解释:

这是指 httpx 的源代码每一行都被单元测试覆盖到(通过工具如 pytest-cov 验证)。这不保证没有 bug,但说明开发者非常重视质量,变更不易引入回归问题。

📌 这属于项目质量指标,对用户透明,但让你用得更放心。

8. 以及 requests 的所有标准功能…

接下来这些其实是 requests 的经典功能,httpx 也都支持:

国际化域名和 url(idn)

解释:

支持包含非 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)
# 三次请求复用同一个连接(如果服务器支持)

带 cookie 持久化的会话

解释:

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 验证

解释:

默认启用 ssl 证书验证(使用系统 ca 证书),防止中间人攻击。和浏览器一样严格。

示例(正常情况):

r = httpx.get("https://github.com")  # 验证通过

禁用验证(不推荐):

r = httpx.get("https://self-signed.badssl.com", verify=false)

✅ 安全默认开启。

基本/摘要认证

解释:

支持 http basic auth 和 digest auth。

basic auth 示例:

r = httpx.get("https://httpbin.org/basic-auth/user/pass", auth=("user", "pass"))
print(r.status_code)  # 200 if ok

digest auth 需要 httpx.digestauth(注意:requests 有,httpx 从 v0.23+ 开始支持):

# 需要服务器支持 digest auth
auth = httpx.digestauth("user", "pass")
r = httpx.get("https://httpbin.org/digest-auth/auth/user/pass", auth=auth)

优雅的键值对 cookie

解释:

可手动设置 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 响应体

解释:

支持任意 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)

http(s) 代理支持

解释:

可通过 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 支持

解释:

如果存在 ~/.netrc 文件,httpx 会自动读取其中的认证信息(用户名/密码)用于对应域名。

.netrc文件

.netrc 是一个“自动填账号密码”的小本本,放在你电脑的家目录里,专门给命令行工具(比如 curl、httpx、ftp)用,避免每次都要手动输用户名和密码。

  1. 文件位置

⚠️ 注意:这个文件必须权限设为 600(仅自己可读写),否则很多工具会拒绝使用(安全考虑):

chmod 600 ~/.netrc
  1. 文件格式(非常简单)
    .netrc 是纯文本文件,内容长这样:
machine httpbin.org
login alice
password secret123

machine api.example.com
login bob
password mypass456

每一组由三行组成:

你可以为多个网站分别配置。

  1. 它解决了什么问题?
    假设你有一个 api 接口需要 basic auth 认证:
# 没有 .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 头!

  1. 那如果代码里同时写了 auth 和 .netrc,以代码里的 auth 为准,.netrc 被忽略。

示例(需先创建 ~/.netrc):

machine httpbin.org
login user
password pass

然后

r = httpx.get("https://httpbin.org/basic-auth/user/pass")  # 自动带 auth

分块请求(chunked transfer encoding)

解释:

当你发送的数据长度未知时,可使用分块传输(无需提前知道 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 客户端之一。

参考文献

httpx官网
httpx中文官网

到此这篇关于python的下一代http客户端httpx特性的文章就介绍到这了,更多相关python客户端httpx特性内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

python的安装详细教程及常见问题排查

08-03

Python自动化办公之Excel和Word操作指南

08-03

Python数值类型(int、float、complex与bool)的使用小结

08-03

Python实现PDF到HTML的转换(附代码详解)

08-03

Python内置模块之datetime日期时间处理详解

08-03

一文详解Python虚拟环境venv创建与隔离项目依赖

08-03

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论