龙空技术网

Python网络请求库httpx详解

码农世界 186

前言:

此刻同学们对“python发http请求”大体比较看重,兄弟们都需要剖析一些“python发http请求”的相关内容。那么小编在网摘上搜集了一些对于“python发http请求””的相关内容,希望小伙伴们能喜欢,小伙伴们一起来学习一下吧!

1|0 简介

httpx是Python新一代的网络请求库,它包含以下特点

基于Python3的功能齐全的http请求模块既能发送同步请求,也能发送异步请求支持HTTP/1.1和HTTP/2能够直接向WSGI应用程序或者ASGI应用程序发送请求2|0安装

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]
3|0使用3|1简单使用

httpx与requests库的基本使用方法几乎是一模一样的

import httpxr = httpx.get(';)print(r)  # <Response [200 OK]>

类似的,我们也可以使用POST, PUT, DELETE, HEADOPTIONS等请求方法,如下

r = httpx.post(';, data={'key': 'value'})r = httpx.put(';, data={'key': 'value'})r = httpx.delete(';)r = httpx.head(';)r = httpx.options(';)

带有请求头和请求参数的请求

import httpxheaders = {'user-agent': 'my-app/1.0.0'}params = {'key1': 'value1', 'key2': 'value2'}url = ';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]>200ascii{  "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": ";}{'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': ';}

请求带有cookies

import httpxurl = ';cookies = {'color': 'green'}r = httpx.get(url, cookies=cookies)print(r.json())  # {'cookies': {'color': 'green'}}

设置超时时间

import httpxr = httpx.get(';, timeout=0.001)print(r)

超过设置时间则报httpx.ConnectTimeout: timed out

3|2高级用法

我们使用上面的请求方式时,httpx每次发送请求都需要建立一个新的连接,然而随着请求的数量增加,整个程序的请求效率就会变得很低。

httpx提供了Client来解决以上问题,Client是基于HTTP连接池实现的,这意味着当你对一个网站发送多次请求的时候,Client会保持原有的TCP连接,从而提升程序的执行效率。

使用Client发送请求

创建一个client对象,使用该对象去做相应的请求

import httpxwith httpx.Client() as client:    headers = {'X-Custom': 'value'}    r = client.get(';, headers=headers)    print(r.text)
跨请求共享配置

我们可以将headerscookiesparams等参数放在http.Client()中,在Client下的请求共享这些配置参数

import httpxheaders1 = {'x-auth': 'from-client'}params1 = {'client_id': '1234'}url = ';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 httpxproxies = {    ';: ';,  # 代理1    ';: ';,  # 代理2}url = ';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(';, timeout=10.0)# client实例:with httpx.Client() as client:    client.get(";, timeout=10.0)

或者关闭超时处理

# 普通请求:httpx.get(';, timeout=None)# client实例:with httpx.Client() as client:    client.get(";, timeout=None)
SSL验证

当请求https协议的链接时,发出的请求需要验证所请求主机的身份,因此需要SSL证书来取得服务器的信任后。

如果要使用自定义的CA证书,则可以使用verify参数

import httpxr = httpx.get(";, verify="path/to/client.pem")

或者你可以完全禁用SSL验证(不推荐)。

import httpxr = httpx.get(";, verify=False)
3|3异步支持

默认情况下,httpx使用标准的同步请求方式,如果需要的话,我们也可以使用它提供的异步client来发送相关请求。

使用异步client比使用多线程发送请求更加高效,更能体现明显的性能优势,并且它还支持WebSocket等长网络连接。

异步请求

使用async/await语句来进行异步操作,创建一个httpx.AsyncClient()对象

import asyncioimport httpxasync def main():    async with httpx.AsyncClient() as client:  # 创建一个异步client        r = await client.get(';)        print(r)if __name__ == '__main__':    asyncio.run(main())
同步请求与异步请求的比较

我们来尝试使用同步和异步的方法进行请求,对比两种不同的方法的效率情况。

同步请求

import timeimport httpxdef main():    with httpx.Client() as client:        for i in range(300):            res = client.get(';)            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 httpxasync def req(client, i):    res = await client.get(';)    print(f'第{i + 1}次请求,status_code = {res.status_code}')    return resasync 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官方文档中查看。

标签: #python发http请求