超牛逼的异步协程爬虫超牛逼的异步协程爬虫
写在前面:
本来这篇文章只是用来记录一下学习异步协程爬虫的笔记,感谢CSDN的大力支持,引来了很多关注和浏览,也有很多大佬的
批评指针。
事先声明:本文只是学习使用,在爬虫的实战应用中还要添加诸多限制,比如UA伪装,添加timeout,设置代理等等。
在此感谢以下大佬的批评指针:
血色v残阳
热爱造轮子的程序员
…
文章目录文章目录一、引入二、异步协程1. event_loop2. coroutine3. task4. future5. 绑定回调三、多任务协程
一、引入一、引入
如果因为 IO 阻塞导致被操作系统强行剥夺走 CPU 的执行权限,程序的执行效率会降低了下来。
想要解决这个问题,我们可以自己从应用程序级别检测 IO 阻塞,如果阻塞就切换到程序的其它任务,这样就可以将程序的 IO
降到最低,程序处于就绪态就会增多,以此来迷惑操作系统。
操作系统会以为我们的程序是 IO 较少的程序,从而会尽可能多的分配到 CPU,这样也就达到了提升程序执行效率的目的。
在 Python 3.4 之后新增了 asyncio 模块,可以帮助我们检测 IO 阻塞,通过它可以帮助我们实现异步 IO。
注意:注意:asyncio 只能发只能发 TCP 级别的请求,不能发级别的请求,不能发 HTTP 协议的请求。协议的请求。
什么是异步 IO
所谓的异步异步 IO,就是发起一个 IO 阻塞的操作,但是不用等到它结束,可以在它执行 IO 的过程中继续做别的事情,当 IO 执行
完毕之后会收到它的通知。
实现异步 IO 的方式
通过单线程+异步协程的方式可以实现异步 IO 操作。
二、异步协程二、异步协程
在将异步协程之前,我们需要了解以下几个概念:
1. event_loop
事件循环,相当于一个无限循环。我们可以把一些函数注册到这个事件循环上,当满足某些条件的时候,函数就会被循环执
行。
程序是按照设定的顺序从头执行到尾,运行的次数也是完全按照设定。在编写程序时,如果有一部分程序的运行耗时是比较久
的,需要先让出其控制权,让它在后台运行,其它的程序可以先运行起来。
当后台运行的程序完成后,也需要及时通知主程序已经完成任务可以进行下一步操作,但这个过程所需的时间是不确定的,需
要主程序不断的监听状态,一旦收到了任务完成的消息,就开始进行下一步。
loop就是这个持续不断的监视器。
2. coroutine
中文翻译叫协程,在 Python 中昌指代为协程对象类型,可以将协程对象注册到时间循环中被调用。使用 async 关键字来定义
的方法在调用时不会立即执行,而是返回一个协程对象。
# 首先引入 asyncio 包,这样才能使用 async 和 await
import asyncio
# 使用 async 定义一个 execute 方法,接收一个参数并打印
async def execute(x):
print("Number = ", x)
# 此时调用 execute 函数并不会执行,而是返回一个协程对象
coroutine = execute(1)
print("coroutine:", coroutine)
print("After calling execute.")
# 然后使用 get_event_loop 方法创建一个事件循环 loop
loop = asyncio.get_event_loop()
# 之后调用 loop 对象的 run_until_complete 方法将协程对象注册到事件循环 loop 中并启动,函数才能运行
loop.run_until_complete(coroutine)