HTTPX 是 Python 3 中的一个功能强大的 HTTP 客户端库,它提供了同步和异步两种 API 模式,并且全面支持 HTTP/1.1 和 HTTP/2 协议。其设计旨在提供高性能、易用性以及良好的开发体验,是进行现代网络请求和 API 调用的优秀工具。
「主要特性:」
- 「兼容 Requests API」:如果你熟悉知名的
requests 库,可以几乎无成本地迁移到 httpx。 - 「同时支持同步和异步请求」:既可用于传统的同步脚本,也能完美融入基于
asyncio 的异步应用。 - 「支持 HTTP/1.1 和 HTTP/2」:能够利用 HTTP/2 的多路复用等特性提升性能。
- 「可直接向 WSGI 或 ASGI 应用程序发送请求」:方便对 Web 应用进行测试。
- 「全面的超时控制」:提供了连接、读取、写入等细粒度的超时设置。
- 「完整的类型注解支持」:有利于代码的静态类型检查和编辑器智能提示,提升代码质量。
官网地址:https://www.python-httpx.org/安装
HTTPX 提供了基础安装和多个功能扩展选项,你可以根据项目需求选择安装不同的依赖组。以下命令展示了多种安装方式及其对应的功能增强。
# 基础安装 - 包含核心功能
pip install httpx
# 支持 HTTP/2 协议 - 提升多请求场景性能
pip install 'httpx[http2]'
# 包含 Brotli 压缩支持 - 减少传输数据量
pip install 'httpx[brotli]'
# 安装命令行工具 - 可直接在终端使用
pip install 'httpx[cli]'
# 完整安装 - 包含所有可选功能
pip install 'httpx[all]'
安装完成后,可以通过导入库并打印版本来验证是否安装成功。
import httpx
print(f"HTTPX 版本: {httpx.__version__}")
命令行工具
HTTPX 提供了一个便捷的命令行接口(CLI),允许你直接从终端发送 HTTP 请求,类似于 curl 但具有更友好的 Python 风格。使用前需要安装 CLI 扩展。
pip install httpx[cli]
安装后,你就可以在命令行中使用 httpx 命令了。
以下是一些常见的使用示例,涵盖了设置请求头、Cookie、认证、发送不同格式的数据以及下载文件等场景。
# 设置自定义请求头
httpx https://httpbin.org/headers -h User-Agent MyApp/1.0
# 发送包含特定Cookie的请求
httpx https://httpbin.org/cookies --cookies session_id abc123def456
# 使用基础认证(Basic Auth)
httpx https://httpbin.org/basic-auth/admin/secret123 --auth admin secret123
# 添加查询参数(Query Parameters)
httpx https://httpbin.org/get -p key1 value1 -p key2 value2
# 发送表单数据(Form Data)
httpx https://httpbin.org/post -m POST -d username 121 -d password 2323
# 发送JSON格式的数据
httpx https://httpbin.org/post -m POST -j "{\"name\": \"John\", \"age\": 30}"
# 上传文件
httpx https://httpbin.org/post -f file data.json
# 下载文件并保存到本地
httpx https://httpbin.org/image/jpeg --download image.jpg
# 下载HTML页面
httpx https://httpbin.org/html --download page.html
# 下载JSON数据
httpx https://httpbin.org/json --download data.json
快速开始
以下将通过一系列代码示例,详细介绍如何使用 HTTPX 的核心功能。
1. GET 请求详解
GET 请求用于从指定资源获取数据,是 HTTP 中最常用的方法。HTTPX 的 get 方法非常灵活,支持添加查询参数、自定义请求头等。
import httpx
# 基本GET请求
response = httpx.get(‘https://httpbin.org/get’)
print(response.status_code) # 200
print(response.json()) # 响应内容
# 带查询参数的GET请求
params = {‘key1’: ‘value1’, ‘key2’: ‘value2’}
response = httpx.get(‘https://httpbin.org/get’, params=params)
print(response.url) # 查看完整URL,可以看到参数已被正确编码并附加
# 自定义请求头
headers = {‘User-Agent’: ‘my-app/1.0’}
response = httpx.get(‘https://httpbin.org/headers’, headers=headers)
print(response.json())
2. POST 请求详解
POST 请求用于向服务器提交数据,例如创建新资源或提交表单。HTTPX 支持提交表单数据、JSON、二进制数据以及文件上传。
import httpx
# 提交表单数据(application/x-www-form-urlencoded)
data = {‘name’: ‘张三’, ‘age’: 25}
response = httpx.post(‘https://httpbin.org/post’, data=data)
print(response.json())
# 提交JSON数据(application/json)
json_data = {‘user’: ‘admin’, ‘active’: True}
response = httpx.post(‘https://httpbin.org/post’, json=json_data)
print(response.json())
# 上传单个文件(multipart/form-data)
with open(‘test.txt’, ‘rb’) as f:
files = {‘file’: (‘test.txt’, f, ‘text/plain’)}
response = httpx.post(‘https://httpbin.org/post’, files=files)
print(response.json())
# 提交原始二进制数据
binary_data = b’\x00\x01\x02\x03’
headers = {‘Content-Type’: ‘application/octet-stream’}
response = httpx.post(‘https://httpbin.org/post’, content=binary_data, headers=headers)
print(response.json())
在文件上传或设置请求头时,经常需要指定媒体类型(MIME Type)。了解常见的媒体类型有助于正确构建请求。
常见的媒体格式类型: • text/html :HTML格式 • text/plain :纯文本格式 • text/xml :XML格式 • image/gif :gif图片格式 • image/jpeg :jpg图片格式 • image/png:png图片格式
例如,上传一张图片需要指定正确的 image/ 类型:
files = {‘files’: (“image1.png”, b’image data’, ‘image/png’)}
response = httpx.post(‘https://httpbin.org/post’, files=files)
data = response.json()
print(f”文件信息: {data[‘files’]}“)
以 application 开头的常见媒体格式类型: • application/xhtml+xml :XHTML格式 • application/xml:XML数据格式 • application/atom+xml :Atom XML聚合格式 • application/json:JSON数据格式 • application/pdf:pdf格式 • application/msword :Word文档格式
3. 响应处理详解
发送请求后,正确处理服务器返回的响应至关重要。HTTPX 的 Response 对象提供了丰富的方法和属性来访问状态码、响应头、响应体等信息。
import httpx
response = httpx.get(“https://httpbin.org/json”)
# 获取响应状态信息
print(f”状态码: {response.status_code}“)
print(f”状态描述: {response.reason_phrase}“)
print(f”HTTP版本: {response.http_version}“)
# 以不同格式获取响应内容
json_data = response.json() # 自动解析JSON,返回Python字典或列表
text_content = response.text # 获取解码后的文本内容
binary_content = response.content # 获取原始字节内容
# 获取和检查响应头
headers = response.headers
print(f”内容类型: {headers.get(‘content-type’)}“)
print(f”内容长度: {headers.get(‘content-length’)}“)
# 错误处理:对于非2xx状态码,可以抛出异常
try:
response.raise_for_status() # 如果状态码不是2xx,抛出 httpx.HTTPStatusError
except httpx.HTTPStatusError as e:
print(f”请求失败: {e}“)
4. 流式响应
当处理大文件下载或服务器流式响应(如 Server-Sent Events)时,为了避免一次性将全部内容加载到内存,可以使用流式响应。HTTPX 的 stream 方法允许你以迭代的方式逐步读取响应体。
import httpx
# 流式接收二进制数据块
with httpx.stream(“GET”, “https://httpbin.org/stream/100”) as response:
for chunk in response.iter_bytes():
print(f”收到数据块: {len(chunk)}字节”)
# 流式按行读取文本响应(例如日志文件)
with httpx.stream(“GET”, “https://httpbin.org/stream/100”) as response:
for line in response.iter_lines():
print(f”行: {line}“)
# 流式下载并保存大文件到本地,节省内存
with httpx.stream(“GET”, “https://example.com/large-file.zip”) as response:
with open(“large-file.zip”, “wb”) as f:
for chunk in response.iter_bytes():
f.write(chunk)
5. Cookie 管理
HTTPX 可以自动处理 Cookie,也支持手动设置和发送 Cookie。Response.cookies 可以访问服务器设置的 Cookie,而 cookies 参数则用于向请求中添加 Cookie。
import httpx
# 从响应中获取服务器设置的Cookie
response = httpx.get(“https://httpbin.org/cookies/set/session_id/abc123”)
print(f”Cookie: {response.cookies.get(‘session_id’)}“)
# 在请求中发送自定义的Cookie
cookies = {“session_id”: “abc123”, “user_id”: “456”}
response = httpx.get(“https://httpbin.org/cookies”, cookies=cookies)
print(f”服务器收到的Cookie: {response.json()[‘cookies’]}“)
# 使用功能更丰富的Cookies对象进行管理
cookies_obj = httpx.Cookies()
cookies_obj.set(“token”, “xyz789”, domain=“httpbin.org”)
response = httpx.get(“https://httpbin.org/cookies”, cookies=cookies_obj)
print(f”使用Cookies对象: {response.json()}“)
6. 重定向控制
默认情况下,对于 GET、HEAD、OPTIONS、TRACE 等方法,HTTPX 会自动跟随重定向。对于 POST 等方法则不会,但可以通过 follow_redirects=True 参数显式启用。你可以通过 response.history 查看重定向历史。
import httpx
# 默认跟随GET请求的重定向
response = httpx.get(“http://github.com/”, follow_redirects=True)
print(f”最终状态码: {response.status_code}“) # 200
print(f"重定向历史记录数: {len(response.history)}") # 至少为1
print(f"重定向历史记录: {response.history}")
print(response.text)
# 下面等同上面代码
r = httpx.get('http://github.com/')
print(r.status_code)
print(r.history) # 查看重定向的记录
print(r.next_request) # 获取到重定向以后的请求对象
resp = httpx.Client().send(r.next_request) # 对请求对象发送请求
print(resp.text)
# 对于默认不跟重定向的方法,可以手动处理
response = httpx.post(“http://httpbin.org/redirect-to?url=/post”, follow_redirects=False)
print(f”状态码: {response.status_code}“) # 302
if response.status_code == 302:
redirect_url = response.headers[‘Location’]
print(f”需要重定向到: {redirect_url}“)
7. 超时与认证
合理的超时设置可以防止程序因网络问题而无限期挂起。HTTPX 提供了详细的超时配置。同时,它也支持 HTTP 基本认证(Basic)和摘要认证(Digest)。
import httpx
# 设置全局请求超时
try:
response = httpx.get(“https://httpbin.org/delay/5”, timeout=3.0)
except httpx.TimeoutException:
print(“请求超时”)
# 配置更细粒度的超时策略
timeout_config = httpx.Timeout(
connect=5.0, # 建立连接的超时时间
read=30.0, # 读取响应的超时时间
write=30.0, # 发送请求体的超时时间
pool=10.0 # 从连接池获取连接的超时时间
)
# 使用HTTP基本认证
response = httpx.get(
“https://httpbin.org/basic-auth/user/passwd”,
auth=(“user”, “passwd”)
)
print(f”基本认证状态: {response.status_code}“) # 200
# 使用HTTP摘要认证
auth = httpx.DigestAuth(“user”, “passwd”)
response = httpx.get(
“https://httpbin.org/digest-auth/auth/user/passwd”,
auth=auth
)
print(f”摘要认证状态: {response.status_code}“) # 200
使用模块级 API时,如果需要为每个请求设置相同的超时、基础 URL、认证信息、默认请求头等,必须在每个调用中重复指定,代码冗长且易错。基于API请求,适用于「一次性、零星、简单」的请求,如快速脚本、测试或仅发起少数几次调用的场景。针对多次情况,共享配置等操作,我们接下来会讲解客户端及异步客户端的使用。