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

相關文章
相關標籤/搜索