异步HTTP请求库aiohttp客服端

aiohttp官方文档
aiohttp GitHub源码

代理池的优化需要异步请求,而asyncio还是不能正常使用(百度相关文章太少),
就打算先学习一下aiohttp的使用,于是就硬着头皮用谷歌翻译的插件阅读官方文档。

aiohttp既可以做客服端也可以实现高并发服务器。这次主要是学习一下怎么做客户端请求。

简单的一个请求:

import aiohttp
import asyncio
 
async def fetch():
    async with aiohttp.ClientSession() as session:
        async with session.get('http://httpbin.org/get') as resp:
            print(resp.status)
            print(await resp.text())
 
loop = asyncio.get_event_loop()
loop.run_until_complete(fetch())
loop.close()

发起post请求可以使用

session.post('http://httpbin.org/post', data=b'aaaaa')
session.post('http://httpbin.org/post',data={‘key1’:'value1','key2':'value2'})

手动构造URL

async def fetch():
    params = {'key1': 'value1', 'key2': 'value2'}
    async with aiohttp.ClientSession() as session:
        async with session.get('http://httpbin.org/get', params=params) as resp:
            print(resp.url)
            print(await resp.text())

params还可以是这样的形式

params = [('key','value1'), ('key', 'value2')]
#url = http://httpbin.org/get?key=value1&key=value2
params = 'key1=value1'
# url = http://httpbin.org/get?key1=value1

第一个就可以实现一个key有多个值的情况
我觉得第二个还不如我下面那样
这我一直有个不明白的地方,为什么不这样写呢

session.get('http://httpbin.org/get?key=value1&key=value2')

简单明了,还不会有奇怪的错误,如果key和value是变量传入的,只要

'http://httpbin.org/get?%d=%d&%d=%d'\
%(key,value1,key,value2)

有明白这样不好的大佬还请指教一下

如果想传入url编码的链接需要这样,不然它就会自动为你编码:

await session.get(URL('http://example.com/%30', encoded=True))

这里还有一个警告:不要同时使用params和encoded两个参数。因为会有矛盾。

resp(响应)的几个参数

  • resp.status 响应码
  • resp.text(encoding=‘utf-8’) 响应信息,encoding默认也行,可以不写
  • resp.read() 响应二进制信息
  • resp.json() 自动解码返回的json信息,无法解码则抛出异常

请求附带json内容

async with aiohttp.ClientSession() as session:
    async with session.post(url, json={'test': 'object'})

还可以这样:

import ujson

async with aiohttp.ClientSession(
        json_serialize=ujson.dumps) as session:
    await session.post(url, json={'test': 'object'})

区别在于第一个使用了内置的json模块,第二个使用ujson,而ujson速度更快,但略有不兼容。

当响应体太大时,则不应直接使用text(),read(),json()

with open(filename, 'wb') as fd:
    while True:
        chunk = await resp.content.read(chunk_size)
        if not chunk:
            break
        fd.write(chunk)

默认超时是5分钟,也可以通过timeout修改

timeout = aiohttp.ClientTimeout(total=60)
async with aiohttp.ClientSession(timeout=timeout) as session:
    pass
async with session.get(url, timeout=timeout) as resp:
    ...

冷知识:…相当于pass

附上代理池:https://mp.csdn.net/mdeditor/83279127#

猜你喜欢

转载自blog.csdn.net/Qwertyuiop2016/article/details/83343380