客户端
提示
如果你是从 Requests 迁移过来的,可以用 httpx.Client()
替代 requests.Session()
。
为什么要使用 Client?
太长不看版
如果你做的不仅仅是实验性工作、一次性脚本或原型开发,那么就应该使用 Client
实例。
更高效地利用网络资源
当你使用快速入门指南中介绍的顶层 API 发起请求时,HTTPX 必须为每个请求单独建立新连接(连接不会被复用)。随着对同一主机的请求数量增加,这种方式很快就会变得低效。
相比之下,Client
实例使用了 HTTP 连接池。这意味着当你向同一主机发起多个请求时,Client
会复用底层的 TCP 连接,而不是为每个请求重新创建。
与使用顶层 API 相比,这能带来显著的性能提升,包括:
- 减少跨请求的延迟(无需重复握手)
- 降低 CPU 使用率和往返次数
- 减少网络拥塞
额外功能
Client
实例还支持一些顶层 API 不具备的功能,例如:
- 跨请求的 Cookie 持久化
- 对所有发出请求应用统一配置
- 通过 HTTP 代理发送请求
- 使用 HTTP/2
本页其他章节将详细介绍 Client
实例的更多用法。
使用方法
推荐的使用方式是使用上下文管理器。这样可以确保在离开 with
代码块时正确清理连接:
with httpx.Client() as client:
...
或者,你也可以不使用代码块,而是显式地通过 .close()
关闭连接池:
client = httpx.Client()
try:
...
finally:
client.close()
发起请求
当你拥有一个 Client
实例后,就可以使用 .get()
、.post()
等方法发送请求。例如:
>>> with httpx.Client() as client:
... r = client.get('https://example.com')
...
>>> r
<Response [200 OK]>
这些方法接受与 httpx.get()
、httpx.post()
等相同的参数。这意味着 快速入门 指南中记录的所有功能在客户端级别同样可用。
例如,发送带有自定义标头的请求:
>>> with httpx.Client() as client:
... headers = {'X-Custom': 'value'}
... r = client.get('https://example.com', headers=headers)
...
>>> r.request.headers['X-Custom']
'value'
跨请求共享配置
客户端允许你通过向 Client
构造函数传递参数,将配置应用到所有出站请求。
例如,为每个请求应用一组自定义标头:
>>> url = 'http://httpbin.org/headers'
>>> headers = {'user-agent': 'my-app/0.0.1'}
>>> with httpx.Client(headers=headers) as client:
... r = client.get(url)
...
>>> r.json()['headers']['User-Agent']
'my-app/0.0.1'
配置合并
当某个配置选项同时在客户端级别和请求级别提供时,会出现以下两种情况之一:
- 对于 headers、查询参数和 cookies,这些值会被合并。例如:
>>> headers = {'X-Auth': 'from-client'}
>>> params = {'client_id': 'client1'}
>>> with httpx.Client(headers=headers, params=params) as client:
... headers = {'X-Custom': 'from-request'}
... params = {'request_id': 'request1'}
... r = client.get('https://example.com', headers=headers, params=params)
...
>>> r.request.url
URL('https://example.com?client_id=client1&request_id=request1')
>>> r.request.headers['X-Auth']
'from-client'
>>> r.request.headers['X-Custom']
'from-request'
- 对于所有其他参数,请求级别的值会优先。例如:
>>> with httpx.Client(auth=('tom', 'mot123')) as client:
... r = client.get('https://example.com', auth=('alice', 'ecila123'))
...
>>> _, _, auth = r.request.headers['Authorization'].partition(' ')
>>> import base64
>>> base64.b64decode(auth)
b'alice:ecila123'
如果需要更精细地控制客户端级别和请求级别参数的合并方式,请参阅请求实例。
其他仅限客户端的配置选项
此外,Client
还接受一些在请求级别不可用的配置选项。
例如,base_url
允许你为所有发出的请求添加 URL 前缀:
>>> with httpx.Client(base_url='http://httpbin.org') as client:
... r = client.get('/headers')
...
>>> r.request.url
URL('http://httpbin.org/headers')
要查看所有可用的客户端参数列表,请参阅 Client
API 参考文档。