Python中的分布式计算 - 网络爬虫

问题描述 投票:1回答:1

我的目标是构建一个分布式爬虫,一次处理多个网站,也可以处理多个查询。为此,我使用标准包(如'requests'和'BeautifulSoup')在Python中构建了一个Web爬虫。它工作正常。为了使其分发,我使用了rabbitMQ。它使我能够通过多个进程帮助爬行来加快系统运行速度。

我的系统在工作池模型中工作:

  • 我有一个主服务器接收查询并为每个服务器开始新的爬网。
  • 开始抓取时,通过将查询输入搜索引擎来收集一些网址。
  • 从现在开始,主服务器使用rabbitMQ将URL发送到可用的worker /进程,并等待从它们接收更多url。

但是,我在这个体系结构中有一个巨大的瓶颈,它不是主服务器...... rabbitMQ不允许我一次消耗超过1条消息(channel.basic_qos()函数不起作用!)。我想要的是为每个查询创建一个私有队列(就像我现在一样),并且能够尽可能快地同时处理这两个查询。通过这种方式,并行化工作人员代码,以便它可以处理最大数量的网址,而不是一次处理1个网址。

我应该用什么来替换这里的rabbitMQ?我特意到达了RabbitMQ的开发人员,我想要的东西无法完成,所以我试图找到一个不同的“分发包”。也许卡夫卡?

python parallel-processing rabbitmq web-crawler distributed-computing
1个回答
0
投票

首先,您必须确定程序的限制是什么。是I / O绑定还是CPU绑定?

例如。如果程序的简单非并行版本可以使您的网络连接饱和,那么制作并行版本是没有用的。

对于网络爬虫来说,通常是网络是最终的瓶颈。

但我们假设您有足够的网络容量。在那种情况下,我建议使用multiprocessing.Pool。充当工作进程的函数将URL作为输入,并从URL返回已处理的数据。您创建一个池,并使用imap_unordered方法将工作者函数应用于URL列表;

def worker(url):
   rv = requests.get(url)
   # Do whatever processing is needed.
   result = ...
   return (url, result)

urls = ['www.foo.com', ...]
p = multiprocessing.Pool()
for url, result in p.imap_unordered(worker, urls):
    print('The URL ', url, 'returned ', result)

默认情况下,Pool将使用与CPU具有核心一样多的工作程序。使用更多工人通常没用。

请注意,必须将worker的返回值从工作进程返回到父进程。所以它必须是可以腌制的。如果必须返回大量数据,那可能会成为IPC的瓶颈。在这种情况下,最好将其写入例如基于RAM的文件系统,只返回数据文件的文件名。

© www.soinside.com 2019 - 2024. All rights reserved.