相关文章推荐
冷冷的麦片  ·  HTTP协议详解 - ...·  1 月前    · 
内向的小蝌蚪  ·  【MATLAB绘图】在灰度图上绘制带颜色的散 ...·  8 月前    · 
温文尔雅的竹笋  ·  android的listview点击获取当前 ...·  1 年前    · 
仗义的自行车  ·  Apache Camel ...·  2 年前    · 
高大的圣诞树  ·  pandas中对文本类型数据的处理小结_py ...·  2 年前    · 
谦和的弓箭  ·  V-for玩不明白Vue基本废了 - ...·  2 年前    · 
Code  ›  python asyncio 异步 I/O - 实现并发http请求(asyncio + aiohttp)开发者社区
python response async http请求
https://cloud.tencent.com/developer/article/1949693
暗恋学妹的铅笔
1 年前
作者头像
上海-悠悠
0 篇文章

python asyncio 异步 I/O - 实现并发http请求(asyncio + aiohttp)

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > 从零开始学自动化测试 > python asyncio 异步 I/O - 实现并发http请求(asyncio + aiohttp)

python asyncio 异步 I/O - 实现并发http请求(asyncio + aiohttp)

作者头像
上海-悠悠
发布 于 2022-03-03 15:40:30
2.6K 0
发布 于 2022-03-03 15:40:30
举报

前言

如果需要并发 http 请求怎么办呢?requests库是同步阻塞的,必须等到结果才会发第二个请求,这里需使用http请求异步库 aiohttp。

环境准备

aiohttp 用于 asyncio 和 Python 的异步 HTTP 客户端/ 服务器 。 使用pip安装对应的包。当前使用版本v3.8.1

pip install aiohttp

并发http请求

如果使用requests 库,发10个请求访问我的博客,那么这10个请求是串行的。

import requests
import time
url = "https://www.cnblogs.com/yoyoketang/"
start_time = time.time()
for i in range(10):
    r = requests.get(url)
    print(r)
print('总耗时:', time.time()-start_time)

运行结果,总共耗时1秒左右

<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
<Response [200]>
总耗时:1.0870192050933838

使用asyncio + aiohttp 并发请求

import asyncio
from aiohttp import ClientSession
import time
async def bai_du(url):
    print(f'启动时间: {time.time()}')
    async with ClientSession() as session:
        async with session.get(url) as response:
            res = await response.text()
            return res
async def main():
    url = "https://www.cnblogs.com/yoyoketang/"
    task_list = []
    for i in range(10):
        task = asyncio.create_task(bai_du(url))
        task_list.append(task)
    done, pending = await asyncio.wait(task_list, timeout=None)
    # 得到执行结果
    for done_task in done:
        print(f"{time.time()} 得到执行结果 {done_task.result()}")
# asyncio.run(main())
start_time = time.time()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
print("总耗时: ", time.time()-start_time)

运行结果

启动时间: 1646028822.3952098
启动时间: 1646028822.4161537
启动时间: 1646028822.4171515
启动时间: 1646028822.4171515
启动时间: 1646028822.4171515
启动时间: 1646028822.4171515
启动时间: 1646028822.4181483
启动时间: 1646028822.4181483
启动时间: 1646028822.4181483
启动时间: 1646028822.4181483
总耗时:  0.17400002479553223

从运行结果可以看到,启动时间非常接近,也就是并发的请求,总过耗时 0.17 秒。

asyncio.run

需注意的是这里使用 asyncio.run(main()) 会报错RuntimeError: Event loop is closed

Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x00000238675A8F70>
Traceback (most recent call last):
  File "D:\python3.8\lib\asyncio\proactor_events.py", line 116, in __del__
    self.close()
  File "D:\python3.8\lib\asyncio\proactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "D:\python3.8\lib\asyncio\base_events.py", line 719, in call_soon
    self._check_closed()
 
推荐文章
冷冷的麦片  ·  HTTP协议详解 - 通过C++实现HTTP服务剖析HTTP协议
1 月前
内向的小蝌蚪  ·  【MATLAB绘图】在灰度图上绘制带颜色的散点-CSDN博客
8 月前
温文尔雅的竹笋  ·  android的listview点击获取当前选项值的方法 - o0寂寞的泡沫0o - 博客园
1 年前
仗义的自行车  ·  Apache Camel 测试指南_51CTO博客_apache camel
2 年前
高大的圣诞树  ·  pandas中对文本类型数据的处理小结_python_脚本之家
2 年前
谦和的弓箭  ·  V-for玩不明白Vue基本废了 - 腾讯云开发者社区-腾讯云
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号