【发布时间】:2015-08-30 11:34:04
【问题描述】:
我对 python 很陌生(我主要用 Java 编写代码)。我有一个 python 脚本,它本质上是一个爬虫。它调用 phantomjs,它加载页面,返回其源代码,以及它在页面中找到的 url 列表。
我一直在尝试使用 Python 3 的 multiprocessing 模块来执行此操作,但我不知道如何使用工作人员也可以添加到的共享队列。我不断得到不可预测的结果。
我之前的方法使用了一个全局 URL 列表,我从中提取了一个块并使用 map_async 发送给工作人员。最后,我会收集所有返回的 URL 并将它们附加到全局列表中。问题是每个“块”花费的时间与最慢的工人一样长。我正在尝试对其进行修改,以便每当工作人员完成时,它都可以获取下一个 URL。但是,我认为我做的不对。到目前为止,这是我所拥有的:
def worker(url, urls):
print(multiprocessing.current_process().name + "." + str(multiprocessing.current_process().pid) + " loading " + url)
returned_urls = phantomjs(url)
print(multiprocessing.current_process().name + "." + str(multiprocessing.current_process().pid) + " returning " + str(len(returned_urls)) + " URLs")
for returned_url in returned_urls:
urls.put(returned_url, block=True)
print("There are " + str(urls.qsize()) + " URLs in total.\n")
if __name__ == '__main__':
manager = multiprocessing.Manager()
urls = manager.Queue()
urls.append(<some-url>)
pool = Pool()
while True:
url = urls.get(block=True)
pool.apply_async(worker, (url, urls))
pool.close()
pool.join()
如果有更好的方法,请告诉我。我正在抓取一个已知站点,最终终止条件是没有要处理的 URL。但现在看来,我将永远继续奔跑。我不确定我是否会使用queue.empty(),因为它确实说它不可靠。
【问题讨论】:
-
查看相关:stackoverflow.com/questions/17241663/…(我认为您的设计模式不太正确)我相信您希望 N 个工作人员协作访问共享队列。
-
@JamesMills 这个例子很有意义!加入
worker_main内的队列可以吗? -
另外,我试过了,它看起来几乎立即退出,即使使用
time.sleep(10)。 phantomjs 调用需要一些时间才能返回,但脚本会在此之前退出。 -
好吧,我的意思是;我不知道如何回答你的问题了:) 哈哈!
-
哈哈,不用担心。谢谢 :) 我会尝试更多并更新我的问题。
标签: python concurrency multiprocessing python-multiprocessing