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

 更新时间:2026年08月03日 09:25:02   作者:SunnyRivers  
httpx是一个功能强大的Python HTTP客户端库,它提供了同步和异步的HTTP客户端接口,支持HTTP/1.1和HTTP/2协议,以及WebSocket,这篇文章主要介绍了Python的下一代HTTP客户端HTTPX特性的相关资料,需要的朋友可以参考下

前言

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

  • 同步:适合脚本、简单爬虫、非高并发场景。
  • 异步:适合高并发 I/O 密集型任务(如同时请求多个 API),需配合 async/await 使用。

同步示例:

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(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+(部分支持)。

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 参数精细控制。

  • 连接超时(connect)指定等待与目标主机建立套接字连接的最长时间。如果 HTTPX 在此时间内无法建立连接,将引发 ConnectTimeout 异常。
  • 读取超时(read)指定等待接收数据块(例如响应体的一部分)的最长持续时间。如果 HTTPX 在此时间内无法接收数据,将引发 ReadTimeout 异常。
  • 写入超时(write)指定等待发送数据块(例如请求体的一部分)的最长持续时间。如果 HTTPX 在此时间内无法发送数据,将引发 WriteTimeout 异常。
  • 连接池超时(pool)指定从连接池获取连接的最长等待时间。如果 HTTPX 在此时间内无法获取连接,将引发 PoolTimeout 异常。与此相关的配置项是连接池允许的最大连接数,可通过 limits 参数进行配置。

示例:

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

  • Punycode背景

互联网早期,域名只允许使用 ASCII 字符(a-z, 0-9, -)。
但中文、阿拉伯文、俄文等用户也希望用自己的语言注册域名,比如:

https://例子.测试

但 DNS 系统(域名解析底层)不认非 ASCII 字符!
于是,人们发明了 Punycode —— 一种编码规则,把 Unicode 域名转换成纯 ASCII 字符串。

  • Punycode是什么
    定义:一种将 Unicode 字符串(如中文、emoji)编码为 ASCII 字符串的算法。
    格式:以 xn-- 开头,后面是编码后的字母数字组合。
    目的:让国际化域名(IDN, Internationalized Domain Names)能在现有 DNS 系统中工作。

示例:

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. 文件位置
  • Linux / macOS:~/.netrc(即 /home/你的用户名/.netrc 或 /Users/你的用户名/.netrc)
  • Windows:通常不支持,或需通过环境变量指定(HTTPX 在 Windows 上对 .netrc 支持有限)

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

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

machine api.example.com
login bob
password mypass456

每一组由三行组成:

  • machine 域名:指定这个账号密码用于哪个网站(只写域名,不要带 http://)
  • login 用户名
  • password 密码

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

  1. 它解决了什么问题?
    假设你有一个 API 接口需要 Basic Auth 认证:
# 没有 .netrc 时,你必须在代码里写死账号密码(不安全!)
r = httpx.get("https://httpbin.org/basic-auth/alice/secret123", auth=("alice", "secret123"))

但如果你把账号密码写在代码里:

  • 容易被提交到 Git(泄露!)
  • 换密码要改代码
  • 多人协作麻烦
    ✅ 有了 .netrc,你的代码可以完全不出现密码:
# 代码干净又安全!
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特性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于pymysql模块的使用以及代码详解

    关于pymysql模块的使用以及代码详解

    在本篇文章里小编给大家整理的是关于关于pymysql模块的使用以及代码详解,有兴趣的朋友们学习下。
    2019-09-09
  • python统计mysql数据量变化并调用接口告警的示例代码

    python统计mysql数据量变化并调用接口告警的示例代码

    这篇文章主要介绍了python统计mysql数据量变化并调用接口告警的示例代码,帮助大家更好的利用python操作数据库,感兴趣的朋友可以了解下
    2020-09-09
  • python的re正则表达式实例代码

    python的re正则表达式实例代码

    这篇文章主要介绍了python的re正则表达式,分享了一则re模块实现的正则表达式实例代码,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • 基于Python实现视频去重小工具

    基于Python实现视频去重小工具

    这篇文章主要为大家详细介绍了如何通过Python语言编写简单的视频去重小工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起尝试一下
    2023-03-03
  • Python和OpenCV自制访客识别程序

    Python和OpenCV自制访客识别程序

    这篇文章主要为大家详细介绍了如何使用Python和OpenCV自制访客识别程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-11-11
  • Python日期格式和字符串格式相互转换的方法

    Python日期格式和字符串格式相互转换的方法

    这篇文章主要介绍了Python日期格式和字符串格式相互转换的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • python动态监控日志内容的示例

    python动态监控日志内容的示例

    本文介绍如何使用Python动态监控程序日志的内容,这里的动态指的是日志文件不断的追加新的日志内容,动态监控是指监控日志新追加的日志内容
    2014-02-02
  • 利用matplotlib+numpy绘制多种绘图的方法实例

    利用matplotlib+numpy绘制多种绘图的方法实例

    matplotlib是Python最著名的绘图库,本文给大家分享了利用matplotlib+numpy绘制多种绘图的方法实例,其中包括填充图、散点图(scatter plots)、. 条形图(bar plots)、等高线图(contour plots)、 点阵图和3D图,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-05-05
  • Python sort 自定义函数排序问题

    Python sort 自定义函数排序问题

    这篇文章主要介绍了Python sort 自定义函数排序问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Python使用Vagrant搭建开发环境的具体步骤

    Python使用Vagrant搭建开发环境的具体步骤

    使用 Vagrant 搭建开发环境是一个非常方便的方式,它可以帮助你快速创建、配置和管理虚拟机,确保开发环境的一致性,以下是使用 Vagrant 搭建开发环境的具体步骤,需要的朋友可以参考下
    2024-09-09

最新评论