2014-01-07 74 views
1

我寫了一個蜘蛛,從列表中獲取URL,使用requests在單獨的線程中使用concurrent.futures.ThreadPoolExecutor加載相應的頁面,並且當加載頁面時,從中提取一些信息,放入item(字典),item被放入名爲collected_itemsQueue()中。確定工作線程是否正在做任何工作

運行在單獨的線程ThreadPoolExecutor創造就業機會蜘蛛方法(簡化)後:

def start_requests(self): 

    def start_requests(): 
     for url in self.start_urls: 
      self.start_request(url) 

    self._executor = ThreadPoolExecutor(self.max_workers) 
    self._executor.submit(start_requests) 

我在等待通過工作線程收集的內容:

spider = Spider() 
spider.start_requests() 

while not spider._executor._work_queue.empty() or not collected_items.empty(): 
    try: 
     item = collected_items.get(timeout=0.25) 
    except queue.Empty: 
     continue 
    print('Found an item %s' item) 

但是有時while在收集所有物品之前循環休息。

spider._executor._threads是工作線程這while環路採取從spider._executor._work_queue工作項目,並運行相關的可調用的set

條件not spider._executor._work_queue.empty() or not collected_items.empty()是不可靠的,因爲在執行工作項隊列也許清空以及收集到的物品隊列,但在檢查這個條件的執行工作線程的時間可能從spider._executor._work_queue和權利而採取的最後一個工作項現在正在做一些工作,將收集的項目添加到collected_items隊列中(目前它也是空的)。或者工作項目隊列還沒有收到第一個工作項目。

我沒有看到一種方法可靠地確定我是否仍然等待新項目出現在collected_items或繼續前進。

UPDATE:

我會解決這個問題,如果在完成工作項目後,工作線程將調用work_queue.task_done()。不幸的是it's not the case

我添加了一個註釋相關的錯誤:http://bugs.python.org/issue14119#msg207512

+0

似乎是一個棘手的問題。順便說一句,你是否打錯了'def spider(self):'with'def start_requests(self):'? – WKPlus

+0

@WKPlus,不,這不是一個錯字。我做了一個閉包,在獨立的工作線程中運行內部'start_requests'。 – warvariuc

回答

1

寫您的工人這樣的代碼:

def run(): 
    while True: 
     item = work_queue.get() 
     work(item) 
     work_queue.task_done() 

而且使用queue.unfinished_tasks爲條件。

+0

感謝您的評論。通過'concurrent/futures/thread.py'的來源,我也想到了這一點。但是我必須修補標準庫代碼或複製它。 – warvariuc