http2的安装与使用教程:
Mac下安装httpx: 报错: 场景:pip3 install httpx[http2] 当在Mac中执行此命令时出现 zsh: no matches found: httpx[http2]
注意:此问题适用于所有相关场景 zsh: no matches found: xxx
解决办法:
1、编辑 zprofile 文件
vim ~/.zprofile
2、在文件中添加 setopt no_nomatch,然后按ESC保存文件 :wq
setopt no_nomatch
3、重新执行文件
source ~/.zprofile
之后可以重新尝试执行命令。
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 来获取 HTTP/2 的内容时,可以配置 HTTP/2 支持并设置相关参数。httpx 是一个支持异步编程和 HTTP/2 协议的 Python 库,使用它可以轻松发出 HTTP/2 请求。
下面是一个示例代码,演示如何使用 httpx 来获取 HTTP/2 的内容:
同步使用(测试正常):
import httpxwith httpx.Client(http2=True ) as client: url = "https://ev-h.phncdn.com/hls/videos/202309/29/440305311/720P_4000K_440305311.mp4/master.m3u8?validfrom=1730126962&validto=1730134162&ipa=35.241.118.11&hdl=-1&hash=e+p6Imk3TAqllNY8Os/rJvoWk+w=" response = client.get(url) if response.status_code == 200 : with open ("master.m3u8" , "wb" ) as file: file.write(response.content) print ("m3u8 文件下载成功" ) else : print (f"请求失败,状态码:{response.status_code} " )
异步使用(测试正常):
如果想要异步执行请求,可以使用 httpx.AsyncClient,如下所示:
import httpximport asyncioasync def fetch_m3u8 (): url = "https://ev-h.phncdn.com/hls/videos/202309/29/440305311/720P_4000K_440305311.mp4/master.m3u8?validfrom=1730126962&validto=1730134162&ipa=35.241.118.11&hdl=-1&hash=e+p6Imk3TAqllNY8Os/rJvoWk+w=" async with httpx.AsyncClient(http2=True ) as client: response = await client.get(url) if response.status_code == 200 : with open ("master.m3u8" , "wb" ) as file: file.write(response.content) print ("m3u8 文件下载成功" ) else : print (f"请求失败,状态码:{response.status_code} " ) asyncio.run(fetch_m3u8())
上述代码使用了 httpx 的 HTTP/2 支持功能,通过设置 http2=True 参数来启用。根据需要可以进一步添加自定义的请求头信息、超时设置、代理等参数。
简单使用 httpx与requests库的基本使用方法几乎是一模一样的
import httpxr = httpx.get('https://httpbin.org/get' ) print (r)
类似的,我们也可以使用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' , 'https://' : 'http://localhost:8081' , } 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 asyncioimport httpx async def main (): async with httpx.AsyncClient() as client: r = await client.get('https://www.example.com/' ) print (r) if __name__ == '__main__' : asyncio.run(main())
同步请求与异步请求的比较 我们来尝试使用同步和异步的方法进行请求,对比两种不同的方法的效率情况。
同步请求 import timeimport 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 asyncioimport timeimport 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官方文档中查看。