多线程网络爬虫的最快架构

时间:2011-12-17 18:35:28

标签: java multithreading web-crawler

应该有一个前沿对象 - 持有一组访问过的并等待抓取URL。 应该有一些线程负责抓取网页。 还会有某种控制器对象来创建爬行线程。

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

控制器对象应该负责向工作线程提供新的URL - 这意味着工作线程需要抓取所有给定的URL,然后在未定义的时间内休眠。 Controller将解释这个线程,因此爬行线程应该处理InterruptedException(在Java中它有多贵 - 似乎异常处理不是很快)。 或者控制器应该只启动线程并让爬行线程自己获取边界?

5 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

自问这个问题以来已经过了几年,但在2015年11月我们正在使用fronterascrapyd

Scrapy使用twisted来使其成为一个好的多线程爬虫,而在多核机器上,这意味着我们只受到入站带宽的限制。 Frontera-distributed使用hbase和kafka对链接进行评分,并保持客户端可以访问所有数据。

答案 2 :(得分:1)

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

您可以通过远程服务访问此资源以允许多台计算机。您可以通过隔离网址使资源本身分布在多台计算机上。等...

答案 3 :(得分:1)

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

答案 4 :(得分:1)

如果您不想重新发明轮子,为什么不看Apache Nutch