aiohttp实现多任务异步协程
结合了前两部分学习的内容,今天来模拟一下向多个url发起请求,话不多说直接放代码(为了控制每个url请求的时间,向自己写的Flask服务器发送请求):
# -*- coding:utf-8 -*-
# @Time : 2022/1/22 0022 9:52
# @Author : Tzy0425
# @File : aiohttp实现多任务异步协程.py
import asyncio
import requests
import time
start = time.time()
urls = [
'http://127.0.0.1:5000/tzy',
'http://127.0.0.1:5000/lyy',
'http://127.0.0.1:5000/genuis'
]
# headers = {
# 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36'
# }
async def get_page(url):
print('正在下载......',url)
response = requests.get(url=url)
print('下载完毕!!!',response.text)
tasks = []
for url in urls:
c = get_page(url)
task = asyncio.ensure_future(c)
tasks.append(task)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
end = time.time()
print('总耗时为:',end-start)
Flask服务器
# -*- coding:utf-8 -*-
# @Time : 2022/1/22 0022 10:19
# @Author : Tzy0425
# @File : flask服务器.py
from flask import Flask
import time
app = Flask(__name__)
@app.route('/tzy')
def index_tzy():
time.sleep(2)
return 'Hello tzy!!!'
@app.route('/lyy')
def index_lyy():
time.sleep(2)
return 'Hello lyy!!!'
@app.route('/genuis')
def index_genuis():
time.sleep(2)
return 'Hello genuis!!!'
if __name__ == '__main__':
app.run(threaded = True)
通过运行截图,我们发现并没有实现异步协程操作,而是同步串行:
回忆昨天的内容,在异步协程中不能出现同步模块的代码,否则异步操作失效,再回看上述代码发现 response = requests.get(url=url) 不就是同步模块中的代码嘛,就是因为它导致了异步协程的失效,那么在异步协程中进行模拟请求发送要用的方法是什么呢?
答:基于异步网络请求的模块aiohttp,使用此模块中的ClientSession进行模拟异步请求的发送
修改代码如下:
async def get_page(url):
print('正在下载......',url)
# requests代码属于同步模块,因此异步失效
# response = requests.get(url=url)
async with aiohttp.ClientSession() as session:
# get()方法为阻塞操作,涉及到阻塞操作必须手动挂起
async with await session.get(url) as response:
# 获取响应数据之前必须进行手动挂起
page_text = await response.text()
print('下载完毕!!!',page_text)
要注意里面两个手动挂起操作!!!可以看到成功实现了异步协程操作。