【背景】在一般的爬虫开发或者清理脚本运行过程中,会受到网络请求的阻塞影响,程序在运行到网络请求的时候会停留,直到请求回结果之后才能进行下一步操作。这些情况在面对各种变态的及时响应,敏捷开发的需求时,一般的爬虫程序难以应对,这时候需要各种提升效率的工具,gevent在对协程greenlet库的封装上提供了各种加速工具,使爬取效率提升。
【简单介绍】gevent是一个并发网络库。它的协程是基于greenlet,其作用是在一个函数执行过程中将其挂起,去执行另一个函数,并在必要时将之前的函数唤醒。
三个主要用到的函数:gevent.spawn()方法会创建一个新的greenlet协程对象,并运行它。gevent.joinall()方法会等待所有传入的greenlet协程运行结束后再退出,这个方法可以接受一个”timeout”参数来设置超时时间,单位是秒。
一般标准库中的方法是阻塞式的,所以需要猴子补丁, 把阻塞式方法在函数运行时切换成gevent封装好的非阻塞式方法。
单次读取数据库IO会阻塞非常长的时间,让程序看上去像卡死了一样,而且为了方便协程间通讯,一般会通过消息队列分发任务的形式使协程间的合作更安全
【实际效果】
只要把monkey.patch_all()这一行删掉,原程序的网络请求就会变回阻塞式,通过这样的程序作为对照组。在单位时间内,并发执行的程序处理任务的能力远快于对照组。并发程序在实际过程中领先了几千个任务,而且协程数量越多,效率越高(但是受限于计算性能,协程数量不可能无限),而且同样退出程序后发现,协程所消耗的内存居然比对照组要少。
【代码实例】