学习时间:9:00——11:00 14:30——16:30
事件循环(底层逻辑)
理解成为一个死循环,去检测并执行某些代码。
#伪代码
任务列表=[任务1,任务2,任务3,... ]
while True:
可执行的任务列表,已完成的任务列表=去任务列表中检查所有的任务,将'可执行'和'已完成'的任务返回
for就绪任务in可执行的任务列表:
执行已就绪的任务
for已完成的任务in已完成的任务列表:
在任务列表中移除已完成的任务
如果任务列表中的任务都已完成,则终止循环
import asyncio
#去生成或获取一个事件循环
loop = asyncio.get_event_loop()
#将任务放到任务列表
loop.run_until_complete(任务)
协程函数:定义函数时候async def函数名。
协程对象:执行协程函数()得到的协程对象。
async def func() :
pass
result = func()
注意︰执行协程函数创建协程对象,函数内部代码不会执行!
如果想要运行协程函数内部代码,必须要将协程对象交给事件循环来处理。
import asyncio
async def func():
print("快来搞我吧!")
result = func()
#loop = asyncio.get_event_loop()
#1oop.run_until_complete(result)
asyncio.run(result) #python3.7以后的简便语法,实际是把前面两句封装之后加上错误检测
await
await + 可等待的对象(协程对象、Future、Task对象 ——> IO等待)
当有多个任务执行时,遇到某个任务中的await,会切换到其他任务开始执行,等await后面的耗时操作结束后,继续完成本次任务,通过利用等待的时间完成其他任务来提高效率
Task对象
白话:在事件循环中添加多个任务的。
Tasks用于并发调度协程,通过asyncio.create_task(协程对象)的方式创建Task对象,这样可以让协程加入事件循环中等待被调度执行。除了使用asyncio.create_task()函数以外,还可以用低层级的
loop.create_task()或ensure_future()函数。不建议手动实例化Task对象。
注意:asyncio.create_task()函数在Python 3.7中被加入。在Python 3.7之前,可以改用低层级的asyncio.ensure_future()函数。
import asyncio
async def func():
print(1)
await asyncio.sleep(2)
print(2)
return "返回值"
async def main():
print( "main开始")
task_list = [
asyncio.create_task(func(), name='n1'),
asyncio.create_task(func(), name='n2')
]
print("main结束")
done,pending = await asyncio.wait(task_list,timeout=None)
print(done)
asyncio.run(main())
多任务异步协程实现
import asyncio
import time
async def request(url):
print('正在下载:',url)
await asyncio.sleep(2)
print('下载完成!',url)
start = time.time()
urls = [
'www.baidu.com',
'www.sogou.com',
'www.iqiyi.com'
]
tasks = [request(url) for url in urls]
asyncio.run(asyncio.wait(tasks))
print(time.time()-start)
结果是2秒多一点,验证了异步协程确实实现了(如果同步的话至少要6秒)
注意:有些模块本身是同步的,导入到异步函数中无法实现异步效果,比如time.sleep()和requests.get()方法均不可以
selenuim
- 基于浏览器自动化的一个模块
- 浏览器自动化:我们可以通过编写相关的python代码,让这些python代码表示一些行为动作,让这些行为动作出发到浏览器当中,让浏览器实现自动化的操作。