python多进程multiprocessing模块中Queue的妙用

  最近的部门RPA项目中,小爬为了提高爬虫性能,使用了Python中的多进程(multiprocessing)技术,里面须要用到进程锁Lock,用到进程池Pool,同时利用map方法一次构造多个process。Multiprocessing的使用确实能显著提高爬虫速度,不过程序交由用户使用时,缺少一个好的GUI窗口来显示爬虫进度。以前的文章中使用了Chrome浏览器来渲染js脚本生成了进度条。可是鉴于Chrome在运行时十分吃内存资源,用Chrome只是生成一个进度条不免有些“大材小用”,因此,小爬决定使用Tkinter库来制做进度条,进而摆脱对chrome浏览器的依赖。html

  要制做进度条,就得有计数器存储爬虫的总数,当前的爬取数甚至是当前的耗费时间等做为存储变量。考虑到各个进程之间没法直接通讯,这个当前量和总量如何获得,就只能借助multiprocessing中的Queue类了。根据官方文档,multiprocessing中的Queue 类几乎完美克隆了Queue.Queue中的功能,可是它是专为多进程间的通讯单独设计的。python

 

透过一个简单的例子看下Queue是如何运用的:chrome

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print q.get()    # prints "[42, None, 'hello']"
    p.join()

从上面的例子能够看到,此处的Queue示例出的q对象很是灵活,使用Ipython的代码提示功能能够轻松知道q对象含如下方法,供用户调用:浏览器

好比:性能

一、它主要是经过q.put()来入列,该方法支持存入单个变量,也支持经过列表一次入列多个不一样类型的元素,异常灵活多变。url

二、q.qsize()能够获得当前队列的元素总数。spa

三、q.empty()能够判断当前队列中是否还有值,返回一个布尔型的结果。如:设计

In [36]: q.empty()
Out[36]: True

四、经过q.get()方法来出队列。code

这样咱们就能够灵活使用队列来在各进程间通讯和制做进度条了。orm

咱们在爬虫中,每每会遇到一个这样的状况,目录页和详情页的信息须要结合到一个item中存储起来,它就能够巧妙借助Queue来实现。

上面的例子中,我一次存入了url,bpmDefName,dataId,afFormNumber 等多个字段信息。

后面咱们再从queue中取出一个结果,则该结果是包含 url,bpmDefName,dataId,afFormNumber 多个信息的元组。进而获得元组的每一个元素与详情页的相关字段拼接到一块儿,造成一行信息。代码示例以下:

最后经过Q.qsize()方法判断队列中的元素是否已彻底取出,来实时计算爬虫进度和决定后续动做,很是方便!

有了multiprocessing模块的Queue类和它提供的诸多方法,制做进度条和关联多个item信息,便再也不是难题!

更详细的multiprocessing模块的Queue类介绍,能够参见python官方的文档说明:

https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Queue

相关文章
相关标签/搜索