我寫了一個蜘蛛,從列表中獲取URL,使用requests
在單獨的線程中使用concurrent.futures.ThreadPoolExecutor
加載相應的頁面,並且當加載頁面時,從中提取一些信息,放入item
(字典),item
被放入名爲collected_items
的Queue()
中。確定工作線程是否正在做任何工作
運行在單獨的線程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
似乎是一個棘手的問題。順便說一句,你是否打錯了'def spider(self):'with'def start_requests(self):'? – WKPlus
@WKPlus,不,這不是一個錯字。我做了一個閉包,在獨立的工作線程中運行內部'start_requests'。 – warvariuc