1.基础概念
1.协程
- 在函数(特殊的函数)定义的时候,如果使用了async修饰的话,则改变函数调用后返回一个协程对象,并且函数内部的实现语句不会被立即执行。
2.任务对象
- 任务对象就是对协程对象的进一步封装,任务对象==高级的协程对象==特殊的函数
- 任务对象必须要注册到事件循环对象中
- 给任务对象绑定回调函数:爬虫的数据解析中
3.事件循环
- 当作是一个容器,容器中必须存放任务对象
- 当启动事件循环对象后,则事件循环对象会对其内部存储任务对象进行一步的执行
4.aiohttp
- 支持异步网络请求的模块
协程
import asyncio
def callback(task): # 作为任务对象的回调函数
print('i am callback and ', task.result()) # task.result是用来接收特殊函数的返回值
async def test():
print("i am test")
return "123"
c = test()
# 封装了一个任务对象
task = asyncio.ensure_future(c)
task.add_done_callback(callback)
# 创建一个事件循环的对象
loop = asyncio.get_event_loop()
loop.run_until_complete(task)
# 执行结果
i am test
i am callback and 123
多任务
import time
import asyncio
start = time.time()
# 在特殊函数内部的实现中不可以出现不支持异步的模块代码
async def get_request(url):
await asyncio.sleep(2)
print("下载成功:", url)
urls = [
'www.1.com',
'www.2.com',
]
tasks = []
for url in urls:
c = get_request(url)
task = asyncio.ensure_future(c)
tasks.append(task)
loop = asyncio.get_event_loop()
# 注意:挂起操作需要手动处理
loop.run_until_complete(asyncio.wait(tasks))
print(time.time() - start)
# 执行结果:
下载成功: www.1.com
下载成功: www.2.com
2.0021142959594727
在爬虫中的应用
# flask_server.py
from flask import Flask
import time
app = Flask(__name__)
@app.route('/bobo')
def index_bobo():
time.sleep(2)
return 'Hello bobo'
@app.route('/jay')
def index_jay():
time.sleep(2)
return 'Hello jay'
if __name__ == '__main__':
app.run(threaded=True)
# 在爬虫中的应用.py
import time
import asyncio
import aiohttp
start = time.time()
urls = [
'http://127.0.0.1:5000/bobo',
'http://127.0.0.1:5000/jay',
]
async def get_request(url):
async with aiohttp.ClientSession() as s:
async with await s.get(url=url) as response:
page_text = await response.text()
# print(page_text)
return page_text
tasks = []
for url in urls:
c = get_request(url)
task = asyncio.ensure_future(c)
tasks.append(task)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
print(time.time() - start)
待续
来源:https://www.cnblogs.com/zangyue/p/12201487.html