说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Python 的下一代 HTTP 客户端 HTTPX。HTTPX 是 Python 3 的一个功能齐全的 HTTP 客户端,它提供同步和异步 API,并支持H TTP/1.1和 HTTP/2。
安装:
pip install httpx
# 或者,使用命令行客户端,命令行客户端是可选的依赖项
pip install 'httpx[cli]'
现在,让我们开始:
>>> import httpx
>>> r = httpx.get('https://www.example.org/')
>>> r
<Response [200 OK]>
>>> r.status_code
200
>>> r.headers['content-type']
'text/html; charset=UTF-8'
>>> r.text
'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'
HTTPX 在 requests 可用性基础上,为您提供:
当然,也包含 requests 所有标准功能:
导入 httpx 并获取网页内容:
>>> import httpx
>>> r = httpx.get('https://httpbin.org/get')
>>> r
<Response [200 OK]>
# 发出HTTP POST请求
>>> r = httpx.post('https://httpbin.org/post', data={'key': 'value'})
其他类型(PUT, DELETE, HEAD, and OPTIONS)请求:
>>> 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')
要在传出请求中包含其他标头,请使用headers关键字参数:
>>> url = 'https://httpbin.org/headers'
>>> headers = {'user-agent': 'my-app/0.0.1'}
>>> r = httpx.get(url, headers=headers)
某些类型的HTTP请求(如POST和PUT请求)可以在请求主体中包含数据。一种常见的包含方式是作为表单编码数据,用于HTML表单。
>>> data = {'key1': 'value1', 'key2': 'value2'}
>>> r = httpx.post("https://httpbin.org/post", data=data)
>>> print(r.text)
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
表单编码数据还可以包括来自给定密钥的多个值。
>>> data = {'key1': ['value1', 'value2']}
>>> r = httpx.post("https://httpbin.org/post", data=data)
>>> print(r.text)
{
...
"form": {
"key1": [
"value1",
"value2"
]
},
...
}
如果您只需要一个简单的键值数据结构,那么表单编码数据就可以了。对于更复杂的数据结构,您通常希望使用JSON编码。
>>> data = {'integer': 123, 'boolean': True, 'list': ['a', 'b', 'c']}
>>> r = httpx.post("https://httpbin.org/post", json=data)
>>> print(r.text)
{
...
"json": {
"boolean": true,
"integer": 123,
"list": [
"a",
"b",
"c"
]
},
...
}
对于其他编码,应使用 content=...
参数,传递字节类型或生成字节的生成器。
>>> content = b'Hello, world'
>>> r = httpx.post("https://httpbin.org/post", content=content)
在URL中传递参数:
>>> params = {'key1': 'value1', 'key2': 'value2'}
>>> r = httpx.get('https://httpbin.org/get', params=params)
>>> r.url
URL('https://httpbin.org/get?key2=value2&key1=value1')
# 还可以将项目列表作为值传递:
>>> params = {'key1': 'value1', 'key2': ['value2', 'value3']}
>>> r = httpx.get('https://httpbin.org/get', params=params)
>>> r.url
URL('https://httpbin.org/get?key1=value1&key2=value2&key2=value3')
HTTPX 将自动处理将响应内容解码为 Unicode 文本。
>>> r = httpx.get('https://www.example.org/')
>>> r.text
'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'
# 检查将使用什么编码来解码响应
>>> r.encoding
'UTF-8'
在某些情况下,响应可能不包含显式编码,在这种情况下,HTTPX将尝试自动确定要使用的编码。
>>> r.encoding
None
>>> r.text
'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'
如果需要重写标准行为并显式设置要使用的编码,那么也可以这样做。
>>> r.encoding = 'ISO-8859-1'
我们可以检查响应的HTTP状态代码:
>>> r = httpx.get('https://httpbin.org/get')
>>> r.status_code
200
>>> r.status_code == httpx.codes.OK
True
对于非文本响应,也可以以字节形式访问响应内容:
>>> r.content
b'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'
任何gzip和deflate HTTP响应编码都将自动为您解码。如果安装了brotlpy,那么也将支持brotli响应编码。例如,要从请求返回的二进制数据创建图像,可以使用以下代码:
>>> from PIL import Image
>>> from io import BytesIO
>>> i = Image.open(BytesIO(r.content))
通常,Web API响应将编码为JSON。
>>> r = httpx.get('https://api.github.com/events')
>>> r.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...' ... }}]
要发出异步请求,您需要一个AsyncClient。
>>> async with httpx.AsyncClient() as client:
... r = await client.get('https://www.example.com/')
...
>>> r
<Response [200 OK]>
AsyncIO是Python的内置库,用于使用async/await语法编写并发代码。
import asyncio
import httpx
async def main():
async with httpx.AsyncClient() as client:
response = await client.get('https://www.example.com/')
print(response)
asyncio.run(main())
HTTPX允许您向客户端注册“事件挂钩”,每次发生特定类型的事件时都会调用这些挂钩。
目前有两个事件挂钩:
这些允许您安装客户端范围的功能,如日志记录、监视或跟踪。
def log_request(request):
print(f"Request event hook: {request.method} {request.url} - Waiting for response")
def log_response(response):
request = response.request
print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")
client = httpx.Client(event_hooks={'request': [log_request], 'response': [log_response]})
# 单独添加
client = httpx.Client()
client.event_hooks['request'] = [log_request]
client.event_hooks['response'] = [log_response, raise_on_4xx_5xx]
更新时间:2022-12-28 19:42:43 标签:python 爬虫 httpx