最近的部門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