httpx的使用

urllib和requests库已经可以爬取大多数网站的数据,但对于一些强制使用HTTP/2.0协议访问,这时urllib和requests是无法爬取数据的,因为只支持HTTP/1.1,不支持HTTP/2.0。可以使用一些支持HTTP/2.0的请求库,比较有代表性的是hyper和httpx,后者用起来方便也更强大,requests已有的功能几乎都支持。

示例

https://spa16.scrape.center/就是强制使用HTTP/2.0访问的一个网站,在Network面板中可以看到Protocol一列为h2,。

 尝试使用request爬取

import requests

url = 'https://spa16.scrape.center/'
response = requests.get(url)
print(response.text)

 抛出RemoteDisconnected错误,请求失败。

安装

Python3.6及以上,httpx可以直接使用pip工具安装

pip3 install httpx

但是这样安装不支持HTTP/2.0,如果想支持可以这样安装

pip3 install "httpx[http2]"

这样即安装了httpx,又安装了HTTP/2.0支持模块

基本使用

httpx和requests的很多API存在相似之处,下面是GET请求

import httpx

response = httpx.get(url='https://www.httpbin.org/get')
print(response.status_code)
print(response.headers)
print(response.text)

可以看到User-Agent是python-httpx/0.27.0,表示使用httpx请求的

换一个User-Agent再请求一次

import httpx

headers = {
    'User-Agent' : 'Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.188 Safari/537.36 CrKey/1.54.250320'
}

response = httpx.get(url='https://www.httpbin.org/get', headers=headers)
print(response.text)

User-Agent生效后,尝试用户httpx请求刚才的网站  

import httpx


headers = {
    'User-Agent':'Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.188 Safari/537.36 CrKey/1.54.250320'
}

response = httpx.get(url='https://spa16.scrape.center', headers=headers)
print(response.text)

 抛出了和使用requests请求时类似的错误,httpx默认不会开启对HTTP/2.0的支持,默认使用的是HTTP/1.1,需要手动声明一下才能使用HTTP/2.0,改写代码:

import httpx

client = httpx.Client(http2=True)
headers = {
    'User-Agent':'Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.188 Safari/537.36 CrKey/1.54.250320'
}

response = client.get(url='https://spa16.scrape.center', headers=headers)
print(response.text)

 声明了一个Client对象,赋值为client变量,同时显式地将http2参数设置为True,这样便开启了对HTTP/2.0的支持,就发现可以成功获取HTML代码。

httpx和requests有很多类似API,上面实现GET请求,对于POST请求、PUT请求和DELETE请求实现方式是一样的。

import httpx

r = httpx.get('https://www.httpbin.org/get', params={'name':'germey'})
r = httpx.post('https://www.httpbin.org/post', params={'name':'germey'})
r = httpx.put('https://www.httpbin.org/put')
r = httpx.delete('https://www.httpbin.org/delete')
r = httpx.patch('https://www.httpbin.org/patch')

基于得到的Response对象,可以使用以下书型盒方法获取想要的内容

  • status_code:状态码
  • text:响应体的文本内容
  • content:相应体的二进制内容,当请求体的目标是二进制数据(如图片)时,可以使用此属性获取
  • headers:相应头,是Headers对象,可以使用像获取字典中的内容一样获取期中某个Header的值
  • json:方法,可以调用此方法将文本结果转换为JSON对象

官方文档:https://www.python-httpx.org/quickstart/

Client对象

httpx中有一些基本的API和requests中的非常相似,但也有一些API不相似,例如httpx中的Client对象,就可以和Session对象类比学习

下面介绍Client的使用

import httpx

with httpx.Client() as client:
    response = client.get(url='https://www.httpbin.org/get')
    print(response)

运行结果如下:

<Response [200 OK]>

该方法等价于:

import httpx

client = httpx.Client()
try:
    response = client.get('https://www.httpbin.org/get')
finally:
    client.close()

两种方式运行结果一样,只不过需要再最后显式地调用close方法关闭Client对象。

在声明Client对象时可以指定一些参数,例如headers,这样使用该对象发起的所有请求都会默认带上这些参数配置。示例如下:

import httpx

url = 'http://www.httpbin.org/headers'
headers = {'User-Agent': 'Mozilla/5.0'}
with httpx.Client(headers=headers) as client:
    r = client.get(url)
    print(r.json()['headers']['User-Agent'])

声明了一个headers变量,内容为User-Agent属性,然后将此变量传递给headers参数,初始化了一个Client对象,并赋值为client变量,最后用client变量请求了测试网站,并打印返回结果

Mozilla/5.0

官方文档:https://www.python-httpx.org/advanced/

支持HTTP/2.0

 在客户端上开启对HTTP/2.0的支持,同样是声明Client对象,然后将http2参数设置为True,若不设置默认支持HTTP/1.1
import httpx

client = httpx.Client(http2=True)
res = client.get(url='https://httpbin.org/get')
print(res.text)
print(res.http_version)

 支持异步请求

httpx还支持异步客户端请求(即AsyncCkient)支持Python的async请求的模式:

import httpx
import asyncio

async def fetch(url):
    async with httpx.AsyncClient(http2=True) as client:
        response = await client.get(url)
        print(response.text)
if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(fetch('https://www.httpbin.org/get'))

 

posted @ 2024-05-24 01:47  JJJhr  阅读(72)  评论(0编辑  收藏  举报