结合了前两部分学习的内容,今天来模拟一下向多个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)
要注意里面两个手动挂起操作!!!可以看到成功实现了异步协程操作。