Python aiohttp异步请求

requests只能发送同步请求;
aiohttp 只能发送异步请求;
httpx既能发送同步请求,又能发送异步请求。

本地测试:批量下载78张图(线上环境稍快些):
  • 同步下载: requests大概40s。
    • 改进:用requests.post每次都会创建新连接,速度较慢。而如果首先初始化一个 Session,那么 requests 会保持连接,从而大大提高请求速度。
  • 异步下载:requests大概18s.
  • 异步下载:asyncio大概12s.

用asyncio.gather执行,前期速度慢…???
Python aiohttp异步请求_第1张图片

aiohttp异步请求

安装:pip3 install aiohttp

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url, verify_ssl=False) as response:
        content = await response.content.read()
        filename = url.rsplit('_')[-1]
        with open(filename, 'wb') as f:
            f.write(content)
            
            
async def main():
	urls = ['https://XXX/2.jpg', 'https://XXX/1.jpg']
	
    async with aiohttp.ClientSession() as session:
        await asyncio.gather(*[asyncio.create_task(fetch(session, url)) for url in urls]


if __name__ == '__main__':
    asyncio.run(main())   
限制并发数

3.6.8 支持asyncio.ensure_future,不支持asyncio.create_task
asyncio中用到select,而select是系统IO多路复用的一种方式,它会限制单个进程打开文件描述符的数量(linux是1024个,window是509个),如果超出这个值程序就会报错ValueError: too many file descriptors in select(),.

解决方案:

  • asyncio.Semaphore类是同步装置,用于限制并发请求
  • async with 是异步上下文管理器.

上下文管理协议:当使用with语句时,解释器会自动调用 __enter__,__exit__

semaphore = asyncio.Semaphore(500)

async def request():
    async with semaphore:
        url = 'http://127.0.0.1:5000'
        result = await get(url)

你可能感兴趣的:(Python,aiohttp)