我编写了一个从列表中获取URL的蜘蛛,使用requests
在单独的线程中使用concurrent.futures.ThreadPoolExecutor
加载相应页面,并在加载页面时从中提取一些信息,放入item
(字典),item
被放入名为Queue()
的{{1}}。
运行一个spider方法,在单独的线程中创建collected_items
的作业(简化):
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
个工作线程,它在set
循环中从while
获取工作项并运行相关的callables。
条件spider._executor._work_queue
不可靠,因为执行程序中的工作项队列可能是空的以及收集的项目队列,但在检查此条件时,执行程序工作者线程可能已从中获取最后一个工作项not spider._executor._work_queue.empty() or not collected_items.empty()
而且现在正在做一些工作,将收集的项目添加到spider._executor._work_queue
队列(目前也是空的)。或者工作项队列尚未收到第一个工作项。
我没有找到一种方法来可靠地确定我是否还要等待新项目出现在collected_items
中或继续前进。
更新:
如果在完成工作项后工作者线程会调用work_queue.task_done()
,我会解决这个问题。不幸的是it's not the case。
我在相关错误中添加了评论:http://bugs.python.org/issue14119#msg207512
答案 0 :(得分:1)
写下你的工人代码:
def run():
while True:
item = work_queue.get()
work(item)
work_queue.task_done()
并使用queue.unfinished_tasks
作为条件。