2011-12-17 44 views
3

应该有一个边界对象 - 保存一组访问并等待抓取URL。 应该有一些线程负责抓取网页。 也会有某种控制器对象来创建爬行线程。最快的多线程网络爬虫体系结构

我不知道什么架构会更快,更容易扩展。如何尽可能少的同步来分配责任,并且最小化检查当前URL是否已经被访问的次数。

控制器对象是否应该负责为工作线程提供新的URL - 这意味着工作线程需要抓取所有给定的URL,然后睡眠时间不确定。控制器将解释这个线程,所以爬行线程应该处理InterruptedException(它在Java中的代价是多少 - 似乎异常处理不是很快)。 或者,也许控制器应该只启动线程并让线程自行抓取边界?

回答

3

创建一个共享的线程安全列表,其中包含要被抓取的URL。创建一个Executor,其线程数与您希望并发运行的抓取工具数量相对应。通过引用共享列表将您的搜寻器作为Runnables启动,并将它们分别提交给Executor。每个爬虫从列表中移除下一个URL并执行您需要的任何操作,循环直到列表为空。

1

使用哈希映射创建中央资源,该哈希映射可以将URL存储为上次扫描时的密钥。使这个线程安全。然后,只需使用队列中的链接生成线索,这些链接可以由抓取工具拾取,作为起点。然后每个线程将继续爬行并更新资源。资源中的线程清除过期的爬网。内存资源可以在开始时序列化,也可以在数据库中根据您的应用需求进行分配。

您可以通过远程服务访问此资源以允许多台计算机。您可以通过隔离网址将资源分散到多台机器上。等...

1

你应该使用一个阻塞队列,其中包含需要获取的URL。在这种情况下,您可以创建多个使用者,以便在多个线程中获取URL。如果队列为空,则所有收件人都将被锁定。在这种情况下,您应该在开始时运行所有线程,并且不应在稍后控制它们。 此外,您还需要在某些持久性存储中维护已下载页面的列表,并在添加到队列之前进行检查。

2

它已经几年,因为这个问题被问过,但在2015年11月,我们目前正在使用fronterascrapyd

Scrapy使用双绞线这使它成为一个很好的多线程爬虫,并在多核机器,这意味着我们仅受入站带宽的限制。 Frontera分布式使用hbase和kafka来对链接进行评分,并将所有数据保存到客户端。