1

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

我的系统工作在一个workpool模型:

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

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

我应该用什么来取代rabbitMQ?我特意到达rabbitMQ的开发人员,而我想要的却无法完成,所以我试图找到一个不同的“分发包”。也许卡夫卡?

回答

0

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

E.g.如果一个简单的非并行版本的程序可以使您的网络连接饱和,那么制作并行版本就没有用处。

对于网络爬虫,网络往往是最终的瓶颈。

但是让我们假设你有足够的网络容量。 在这种情况下,我会建议使用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内核具有使用尽可能多的工人。使用更多的工人通常没有用。

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

+0

感谢您的回答。多处理无疑是并行化的想法。 但是,正如我所说的,我正在使用rabbitmq使分布式爬虫(许多计算机/进程可以加入),这就是我造成的瓶颈。 – Skinishh