python-httpx 发送http2.0时代请求
原文,自己做个笔记用
https://blog.51cto.com/u_15127674/3872190
官方文档的地址
https://www.python-httpx.org/
我们在日常开发中,经常会发送各种各样的网络请求。Python中常用的网络请求库有requests、aiohttp、httpx等,httpx是基于Python3的新一代的网络请求库,它的功能很丰富,本文将介绍httpx的相关知识和使用方法。
简介
httpx是Python新一代的网络请求库,它包含以下特点:
- 基于Python3的功能齐全的http请求模块
- 既能发送同步请求,也能发送异步请求
- 支持HTTP/1.1和HTTP/2
- 能够直接向WSGI应用程序或者ASGI应用程序发送请求
安装
httpx需要Python3.6+(使用异步请求需要Python3.8+)
pip3 install httpx
或
python3 -m pip install httpx
如果需要使用HTTP/2,则需要安装http2的相关依赖
pip3 install httpx[http2]
或
python3 -m pip install httpx[http2]
使用
简单使用
httpx与requests库的基本使用方法几乎是一模一样的
import httpx r = httpx.get('https://httpbin.org/get') print(r) # <Response [200 OK]>
类似的,我们也可以使用POST, PUT, DELETE, HEAD和OPTIONS等请求方法,如下
r = httpx.post('https://httpbin.org/post', data={'key': 'value'}) r = httpx.put('https://httpbin.org/put', data={'key': 'value'}) r = httpx.delete('https://httpbin.org/delete') r = httpx.head('https://httpbin.org/get') r = httpx.options('https://httpbin.org/get')
带有请求头和请求参数的请求
import httpx headers = {'user-agent': 'my-app/1.0.0'} params = {'key1': 'value1', 'key2': 'value2'} url = 'https://httpbin.org/get' r = httpx.get(url, headers=headers, params=params) print(r) print(r.status_code) # 状态码 print(r.encoding) # 文本编码 print(r.text) print(r.json())
结果如下
<Response [200 OK]> 200 ascii { "args": { "key1": "value1", "key2": "value2" }, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Host": "httpbin.org", "User-Agent": "my-app/1.0.0", "X-Amzn-Trace-Id": "Root=1-6139b788-2fd67d5627a5f6de346e154a" }, "origin": "113.110.227.200", "url": "https://httpbin.org/get?key1=value1&key2=value2" } {'args': {'key1': 'value1', 'key2': 'value2'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'my-app/1.0.0', 'X-Amzn-Trace-Id': 'Root=1-6139b788-2fd67d5627a5f6de346e154a'}, 'origin': '113.110.227.200', 'url': 'https://httpbin.org/get?key1=value1&key2=value2'}
请求带有cookies
import httpx url = 'http://httpbin.org/cookies' cookies = {'color': 'green'} r = httpx.get(url, cookies=cookies) print(r.json()) # {'cookies': {'color': 'green'}}
设置超时时间
import httpx r = httpx.get('http://httpbin.org', timeout=0.001) print(r)
超过设置时间则报httpx.ConnectTimeout: timed out
高级用法
我们使用上面的请求方式时,httpx每次发送请求都需要建立一个新的连接,然而随着请求的数量增加,整个程序的请求效率就会变得很低。
httpx提供了Client来解决以上问题,Client是基于HTTP连接池实现的,这意味着当你对一个网站发送多次请求的时候,Client会保持原有的TCP连接,从而提升程序的执行效率。
使用Client发送请求
创建一个client对象,使用该对象去做相应的请求
import httpx with httpx.Client() as client: headers = {'X-Custom': 'value'} r = client.get('https://example.com', headers=headers) print(r.text)
跨请求共享配置
我们可以将headers、cookies、params等参数放在http.Client()中,在Client下的请求共享这些配置参数
import httpx headers1 = {'x-auth': 'from-client'} params1 = {'client_id': '1234'} url = 'https://example.com' with httpx.Client(headers=headers1, params=params1) as client: headers2 = {'x-custom': 'from-request'} params2 = {'request_id': '4321'} r1 = client.get(url) print(r1.request.headers) r2 = client.get(url, headers=headers2, params=params2) print(r2.request.headers)
结果如下
Headers({'host': 'example.com', 'accept': '*/*', 'accept-encoding': 'gzip, deflate', 'connection': 'keep-alive', 'user-agent': 'python-httpx/0.19.0', 'x-auth': 'from-client'}) Headers({'host': 'example.com', 'accept': '*/*', 'accept-encoding': 'gzip, deflate', 'connection': 'keep-alive', 'user-agent': 'python-httpx/0.19.0', 'x-auth': 'from-client', 'x-custom': 'from-request'})
可以看出,r1的请求头包含{'x-auth': 'from-client'}, r2虽然配置了headers2,但由于里面的headers1和headers2的参数不同,Client会合并这两个headers的参数作为一个新的headers(如果参数相同,则headers2的参数会覆盖headers1的参数)。
HTTP代理
httpx可以通过设置proxies参数来使用http代理,我们也可以使用不同的代理来分别处理http和https协议的请求,假设有如下两个代理
import httpx proxies = { 'http://': 'http://localhost:8080', # 代理1 'https://': 'http://localhost:8081', # 代理2 } url = 'https://example.com' with httpx.Client(proxies=proxies) as client: r1 = client.get(url) print(r1)
上面的代理只是示范,实际场景下请替换成有效的ip代理
还有一点需要注意的是,httpx的代理参数proxies只能在httpx.Client()中添加,client.get()是没有这个参数的。
超时处理
默认情况下,httpx到处都做了严格的超时处理,默认时间为5秒,超过5秒无响应则报TimeoutException
普通请求:
httpx.get('http://example.com/api/v1/example', timeout=10.0)
client实例:
with httpx.Client() as client: client.get("http://example.com/api/v1/example", timeout=10.0)
或者关闭超时处理
普通请求:
httpx.get('http://example.com/api/v1/example', timeout=None)
client实例:
with httpx.Client() as client: client.get("http://example.com/api/v1/example", timeout=None)
SSL验证
当请求https协议的链接时,发出的请求需要验证所请求主机的身份,因此需要SSL证书来取得服务器的信任后。
如果要使用自定义的CA证书,则可以使用verify参数
import httpx r = httpx.get("https://example.org", verify="path/to/client.pem")
或者你可以完全禁用SSL验证(不推荐)。
import httpx r = httpx.get("https://example.org", verify=False)
异步支持
默认情况下,httpx使用标准的同步请求方式,如果需要的话,我们也可以使用它提供的异步client来发送相关请求。
使用异步client比使用多线程发送请求更加高效,更能体现明显的性能优势,并且它还支持WebSocket等长网络连接。
异步请求
使用async/await语句来进行异步操作,创建一个httpx.AsyncClient()对象
import asyncio import httpx async def main(): async with httpx.AsyncClient() as client: # 创建一个异步client r = await client.get('https://www.example.com/') print(r) if __name__ == '__main__': asyncio.run(main())
同步请求与异步请求的比较
我们来尝试使用同步和异步的方法进行请求,对比两种不同的方法的效率情况。
同步请求
import time import httpx def main(): with httpx.Client() as client: for i in range(300): res = client.get('https://www.example.com') print(f'第{i + 1}次请求,status_code = {res.status_code}') if __name__ == '__main__': start = time.time() main() end = time.time() print(f'同步发送300次请求,耗时:{end - start}')
同步发送300次请求,耗时:49.65340781211853
异步请求
import asyncio import time import httpx async def req(client, i): res = await client.get('https://www.example.com') print(f'第{i + 1}次请求,status_code = {res.status_code}') return res async def main(): async with httpx.AsyncClient() as client: task_list = [] # 任务列表 for i in range(300): res = req(client, i) task = asyncio.create_task(res) # 创建任务 task_list.append(task) await asyncio.gather(*task_list) # 收集任务 if __name__ == '__main__': start = time.time() asyncio.run(main()) end = time.time() print(f'异步发送300次请求,耗时:{end - start}')
异步发送300次请求,耗时:2.5227813720703125 (由于是异步执行的,所以打印的i值是无序的)
从两个例子可以看出,异步请求明显比同步请求的效率高很多。
以上就是httpx库的基本使用方法,想了解更多可以去 httpx官方文档中查看。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2020-03-04 pandas 日期时间数据的分割提取操作
2017-03-04 win7下scrapy1.3.2安装