【问题标题】:Distributed computing in Python - web crawlerPython中的分布式计算——网络爬虫
【发布时间】:2017-07-30 14:28:36
【问题描述】:

我的目标是构建一个分布式爬虫,一次处理多个网站和多个查询。 为此,我使用“requests”和“BeautifulSoup”等标准包在 Python 中构建了一个网络爬虫。它工作正常。 为了使其分布式,我使用了rabbitMQ。它使我能够通过超过 1 个进程来帮助爬网,从而使系统更快。

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

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

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

我应该用什么来代替rabbitMQ?我专门联系了rabbitMQ的开发人员,而我想要的东西不能用它来完成,所以我试图找到一个不同的“分发包”。也许是卡夫卡?

【问题讨论】:

    标签: python parallel-processing rabbitmq web-crawler distributed-computing


    【解决方案1】:

    首先,您必须确定您的程序有哪些限制。是 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 的返回值必须从 worker 进程返回到父进程。所以它必须是可以腌制的。如果您必须返回大量数据,那可能会成为 IPC 瓶颈。在这种情况下,最好将其写入例如基于 RAM 的文件系统,只返回数据文件的文件名。

    【讨论】:

    • 感谢您的回答。多处理绝对是并行化的一个想法。但是,正如我所说,我正在使用rabbitmq 使爬行分布式(许多计算机/进程可以加入),这就是导致我遇到瓶颈的原因。
    猜你喜欢
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 2023-01-26
    • 2014-10-29
    • 1970-01-01
    相关资源
    最近更新 更多