【Python3爬虫】使用异步协程编写爬虫

 

一、基本概念

进程:进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。进程是操作系统动态执行的基本单元。

线程:一个进程中包含若干线程,当然至少有一个线程,线程可以利用进程所拥有的资源。线程是独立运行和独立调度的基本单元。

协程:协程是一种用户态的轻量级线程。协程无需线程上下文切换的开销,也无需原子操作锁定及同步的开销。

同步:不同程序单元为了完成某个任务,在执行过程中需靠某种通信方式以协调一致,称这些程序单元是同步执行的。

异步:为完成某个任务,不同程序单元之间过程中无需通信协调,也能完成任务的方式,不相关的程序单元之间可以是异步的。

多进程:多进程就是利用 CPU 的多核优势,在同一时间并行地执行多个任务。多进程模式优点就是稳定性高,因为一个子进程崩溃了,不会影响主进程和其他子进程,但是操作系统能同时运行的进程数是有限的。

多线程:多线程模式通常比多进程快一点,但是也快不到哪去,而且,多线程模式致命的缺点就是任何一个线程挂掉都可能直接造成整个进程崩溃,因为所有线程共享进程的内存。

 

二、异步协程

Python 中使用协程最常用的库莫过于 asyncio,然后我们还需要了解一些概念:

event_loop:事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上,当满足条件发生的时候,就会调用对应的处理方法。

coroutine:协程对象类型,我们可以将协程对象注册到事件循环中,它会被事件循环调用。我们可以使用 async 关键字来定义一个方法,这个方法在调用时不会立即被执行,而是返回一个协程对象。

task:任务,它是对协程对象的进一步封装,包含了任务的各个状态,比如 running、finished 等。

另外我们还需要了解两个关键字:async(定义一个协程),await(用来挂起阻塞方法的执行)。下面是一个示例:

复制代码
 1 import asyncio  2  3  4 async def show(num):  5     print("Number is {}".format(num))  6  7  8 cor = show(1)  9 print("Coroutine: ", cor) 10 print("After execute...") 11 task = asyncio.ensure_future(cor) 12 print("Task: ", task) 13 loop = asyncio.get_event_loop() 14 loop.run_until_complete(cor) 15 print("Task: ", task) 16 print("After loop...")
复制代码

运行结果如下:

Coroutine: <coroutine object show at 0x0000000012ED91A8>
After execute...
Task: <Task pending coro=<show() running at E:/Python/1.py:4>>
Number is 1
Task: <Task finished coro=<show() done, defined at E:/Python/1.py:4> result=None>
After loop...

这里首先使用async定义了一个show方法,传入一个数字然后打印出来,我们调用了这个方法,但是这个方法并没有执行,而是返回了一个Coroutine协程对象。然后我们使用了asyncio的ensure_future()方法,该方法会返回一个task对象,此时task的状态是pending。然后我们使用 get_event_loop() 方法创建了一个事件循环 loop,并调用了run_until_complete() 方法将协程注册到事件循环loop中,然后启动。最后我们才看到了show() 方法打印了输出结果,此时task的状态已经是finished了。

再来看一个例子:

关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信