前言

Python 中,拜访网络资源最有名的库便是 requestsaiohttphttpx。一般情况下,requests 只能发送同步恳求;aiohttp 只能发送异步恳求;httpx 既能发送同步恳求,又能发送异步恳求。

下面,就侧重介绍一下 httpx 的运用方法。

装置

运用 pip 装置 httpx:

pip install httpx

当然了,httpx 也能够运用命令行操作。不过,需求按如下命令装置。

pip install 'httpx[cli]'

Python3的下一代HTTP客户端——HTTPX

命令行测试发送恳求:

Python3的下一代HTTP客户端——HTTPX

快速入门

建议 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 块会在退出时主动封闭呼应。

更多编程教学请重视公众号:潘高陪你学编程

Python3的下一代HTTP客户端——HTTPX