Python3的下一代HTTP客户端——HTTPX
csdh11 2025-05-09 17:49 1 浏览
前言
在 Python 中,访问网络资源最有名的库就是 requests、aiohttp 和 httpx。一般情况下,requests只能发送同步请求;aiohttp 只能发送异步请求;httpx 既能发送同步请求,又能发送异步请求。
下面,就着重介绍一下 httpx 的使用方法。
安装
使用 pip 安装 httpx:
pip install httpx
当然了,httpx 也可以使用命令行操作。不过,需要按如下命令安装。
pip install 'httpx[cli]'
命令行测试发送请求:
快速入门
发起 GET 请求
直接用 get 方法,如下:
import httpx
r = httpx.get('https://httpbin.org/get')
print(r.status_code) #状态
print(r.text) #内容
对于带参数的 URL,传入一个 dict 作为 params 参数,如下:
import httpx
r = httpx.get('https://httpbin.org/get', params={'q': 'python', 'cat': '1001'})
print(r.url) #实际请求的URL
print(r.text)
对于特定类型的响应,例如 JSON,可以直接获取,如下:
r = httpx.get('https://httpbin.org/get')
r.json()
# {'args': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': ...
对于非文本响应,响应内容也可以以字节的形式访问,如下:
>>> r.content
b'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'
添加 Headers
需要传入 HTTP Header 时,我们传入一个 dict 作为 headers 参数,如下:
r = httpx.get('https://www.baidu.com/', headers={'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit'})
获取响应头,如下:
r.headers
# {Content-Type': 'text/html; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Content-Encoding': 'gzip', ...}
r.headers['Content-Type']
# 'text/html; charset=utf-8'
发起 POST 请求
要发送 POST 请求,只需要把 get()方法变成 post(),然后传入 data 参数作为 POST 请求的数据,如下:
r = httpx.post('https://accounts.baidu.com/login', data={'form_email': 'abc@example.com', 'form_password': '123456'})
httpx 默认使用 application/x-www-form-urlencoded 对 POST 数据编码。如果要传递 JSON 数据,可以直接传入 json 参数,如下:
params = {'key': 'value'}
r = httpx.post(url, json=params) #内部自动序列化为JSON
发起二进制请求
content = b'Hello, world'
r = httpx.post("https://httpbin.org/post", content=content)
上传文件
上传文件操作如下:
upload_files = {'upload-file': open('report.xls', 'rb')}
r = httpx.post('https://httpbin.org/post', files=upload_files)
如果需要在上传文件时包含非文件数据字段,请使用 data 参数,如下:
data = {'message': 'Hello, world!'}
files = {'file': open('report.xls', 'rb')}
r = httpx.post("https://httpbin.org/post", data=data, files=files)
print(r.text)
流媒体响应
可以流式传输响应的二进制内容:
>>> with httpx.stream("GET", "https://www.example.com") as r:
... for data in r.iter_bytes():
... print(data)
或者返回文本:
>>> with httpx.stream("GET", "https://www.example.com") as r:
... for text in r.iter_text():
... print(text)
或者逐行流式传输:
>>> with httpx.stream("GET", "https://www.example.com") as r:
... for line in r.iter_lines():
... print(line)
添加 Cookie
在请求中传入 Cookie,只需准备一个 dict 传入 cookies 参数,如下:
cs = {'token': '12345', 'status': 'working'}
r = httpx.get(url, cookies=cs)
httpx 对 Cookie 做了特殊处理,使得我们不必解析 Cookie 就可以轻松获取指定的 Cookie,如下:
r.cookies['token']
# 12345
指定超时
默认超时为 5 秒。要指定超时,传入以秒为单位的 timeout 参数。超时分为连接超时和读取超时,如下:
try:
# 3.1秒后连接超时,27秒后读取超时
r = requests.get(url, timeout=(3.1, 27))
except requests.exceptions.RequestException as e:
print(e)
当然,也可以禁用超时:
httpx.get('https://github.com/', timeout=None)
超时重连
def gethtml(url):
i = 0
while i < 3:
try:
html = httpx.get(url, timeout=5).text
return html
except httpx.exceptions.RequestException:
i += 1
重定向
默认情况下,httpx 不会遵循所有 HTTP 方法的重定向,不过可以使用 follow_redirects 开启重定向:
>>> r = httpx.get('http://github.com/', follow_redirects=True)
>>> r.url
URL('https://github.com/')
>>> r.status_code
200
>>> r.history
[<Response [301 Moved Permanently]>]
高级用法
使用 httpx.Client() ,实际上是调用 HTTP 链接池。可以带来显著的性能改进。包括:减少跨请求的延迟(无需握手),减少 CPU 使用和往返,减少网络拥塞。
用法
使用 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]>
跨请求共享配置
Client 允许您通过将参数传递给 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'
此外,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')
监控下载进度
如果您需要监控大响应的下载进度,您可以使用响应流并检查 responseresponse.num_bytes_downloaded 属性:
import tempfile
import httpx
with tempfile.NamedTemporaryFile() as download_file:
url = "https://speed.hetzner.de/100MB.bin"
with httpx.stream("GET", url) as response:
print('response', response)
total = int(response.headers["Content-Length"])
print('total', total)
for chunk in response.iter_bytes():
download_file.write(chunk)
percent = response.num_bytes_downloaded / total
print('percent: {:.2%}'.format(percent))
添加代理
httpx 支持通过 proxies 参数设置 HTTP 代理:
with httpx.Client(proxies="http://localhost:8030") as client:
...
对于更高级的用例,请传递代理 dict。例如,要将 HTTP 和 HTTPS 请求路由到 2 个不同的代理,分别位于 http://localhost:8030 和 http://localhost:8031,请传递代理 URL:
proxies = {
"http://": "http://localhost:8030",
"https://": "http://localhost:8031",
}
with httpx.Client(proxies=proxies) as client:
...
代理凭据可以作为代理 URLuserinfo 部分传递:
proxies = {
"http://": "http://username:password@localhost:8030",
# ...
}
异步支持
发送异步请求
>>> async with httpx.AsyncClient() as client:
... r = await client.get('https://www.example.com/')
...
>>> r
<Response [200 OK]>
打开和关闭 Client
使用 with:
async with httpx.AsyncClient() as client:
...
显式关闭客户端:
client = httpx.AsyncClient()
...
await client.aclose()
流媒体响应
>>> client = httpx.AsyncClient()
>>> async with client.stream('GET', 'https://www.example.com/') as response:
... async for chunk in response.aiter_bytes():
... ...
异步响应流方法有:
- Response.aread()-用于有条件地读取流块内的响应。
- Response.aiter_bytes()-用于将响应内容流化为字节。
- Response.aiter_text()-用于将响应内容流化为文本。
- Response.aiter_lines()-用于将响应内容流式传输为文本行。
- Response.aiter_raw()-用于流式传输原始响应字节,无需应用内容解码。
- Response.aclose()-用于结束回复。您通常不需要这个,因为.stream 块会在退出时自动关闭响应。
相关推荐
- OKHttp原理解析(okhttp的作用)
-
Okhttp应该是Android目前非常流行的第三方网络库,尝试讲解他的使用以及原理分析,分成几个部分:...
- 快速教会你优雅的解决TCP客户端端口耗尽的问题
-
Hello,我是Henry,相信各位开发老爷在使用大并发网络连接的时候,可能都遇到过TCP客户端端口耗尽的问题,这是一个常见问题,以下是系统性的解决方案及技术细节:1.理解端口限制的本质...
- 这3个接口基础知识,产品经理需要知道
-
产品经理在工作中,避免不了要阅读接口文档,希望本文能够帮助大家更好的了解接口。接口,即客户端(浏览器)向服务器提交请求,服务器向客户端返回响应。本质就是数据的传输与接收。本文主要介绍接口相关的基础知识...
- Java 11新特性对开发者的影响:让编程更高效、更自由
-
Java11新特性对开发者的影响:让编程更高效、更自由在这个瞬息万变的编程世界里,每一代Java的更新都承载着无数开发者对性能优化、生产力提升以及代码美感追求的期望。作为继Java8之后的首个长期...
- 干货-okHttp的优点-收藏了(okhttp的好处)
-
OkHttp相较于其它的实现有以下的优点.支持SPDY,允许连接同一主机的所有请求分享一个socket。如果SPDY不可用,会使用连接池减少请求延迟。使用GZIP压缩下载内容,且压缩操作对用...
- 如何在 Java 项目中集成 DeepSeek
-
一、使用官方SDK基础集成1.添加依赖(Maven)<dependency><groupId>com.deepseek</groupId>...
- spring cloud gateway 性能优化思路
-
SpringCloudGateway是一个高性能的API网关,但在实际的生产环境中,可能会遇到一些性能瓶颈。以下是一些SpringCloudGateway的性能优化方面:调整线程池...
- 你对Android中的okHttp的使用真的了解吗
-
框架下载地址:https://github.com/square/okhttp今天给大家讲解下网络框架okhttp的使用,这个框架非常强大,很多框架都用它来加载网络资源,目前很多开发者还在用As...
- 京东大佬问我,Nginx并发连接如何设置?详细说明
-
京东大佬问我,Nginx并发连接如何设置?详细说明首先,我需要回忆一下Nginx的并发模型。Nginx是基于事件驱动的异步架构,所以它的并发处理能力和配置参数有很大关系。主要的参数应该包括worker...
- 如何实现一个连接池?一文带你深入浅出,彻底搞懂
-
-前言-【2w1h】是技术领域中一种非常有效的思考和学习方式,即What、Why和How;坚持【2w1h】,可以快速提升我们的深度思考能力。...
- Golang 网络编程(golang 系统编程)
-
TCP网络编程存在的问题:拆包:对发送端来说应用程序写入的数据远大于socket缓冲区大小,不能一次性将这些数据发送到server端就会出现拆包的情况。通过网络传输的数据包最大是1500字节,当TCP...
- Spring6|Spring Boot3有哪些HTTP客户端可以选择
-
个人博客:无奈何杨(wnhyang)个人语雀:wnhyang...
- 10. 常用标准库(标准库有哪些)
-
本章深入解析Go语言核心标准库的关键功能与生产级应用技巧,结合性能优化与安全实践,提供高效开发指南。10.1fmt/io/os10.1.1fmt高级格式化...
- Nginx之连接池(nginx 长连接 连接复用)
-
我们知道Nginx利用连接池来增加它对资源的利用率。下面我们一起来看看Nginx是如何使用连接池的。从上一节模块开始已经慢慢会接触一些Nginx的源码部分来。每个worker进程都有一个独立的ngx...
- 开发者必备的Android开发资源之OkHttp
-
小编在这里给各位Android开发者介绍的资源包括工具、库和网站等。有效地利用它们,将有助于减轻我们的工作量,提高我们的工作效率。为什么需要一个HTTP库Android系统提供了两种HTTP通信类,H...
- 一周热门
- 最近发表
- 标签列表
-
- mydisktest_v298 (34)
- document.appendchild (35)
- 头像打包下载 (61)
- acmecadconverter_8.52绿色版 (39)
- word文档批量处理大师破解版 (36)
- server2016安装密钥 (33)
- mysql 昨天的日期 (37)
- parsevideo (33)
- 个人网站源码 (37)
- centos7.4下载 (33)
- mysql 查询今天的数据 (34)
- intouch2014r2sp1永久授权 (36)
- 先锋影音源资2019 (35)
- jdk1.8.0_191下载 (33)
- axure9注册码 (33)
- pts/1 (33)
- spire.pdf 破解版 (35)
- shiro jwt (35)
- sklearn中文手册pdf (35)
- itextsharp使用手册 (33)
- 凯立德2012夏季版懒人包 (34)
- 冒险岛代码查询器 (34)
- 128*128png图片 (34)
- jdk1.8.0_131下载 (34)
- dos 删除目录下所有子目录及文件 (36)