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

3

应该有一个前沿对象 - 持有一组已访问和等待爬行的URL。

应该有一些线程负责爬取网页。

还应该有一些控制器对象来创建爬行线程。

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

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

5个回答

3

创建一个共享的、线程安全的列表,其中包含要爬取的 URL。使用与您希望同时运行的爬虫数量相对应的线程数创建 Executor。将每个爬虫作为 Runnable 启动,并引用共享列表将它们提交给 Executor。每个爬虫从列表中删除下一个 URL,并执行您需要它执行的操作,循环直到列表为空。


2
几年前有人问过这个问题,但在2015年11月,我们目前正在使用fronterascrapyd
Scrapy使用twisted,使其成为一个很好的多线程爬虫,在多核机器上,我们只受入站带宽的限制。Frontera-distributed使用hbase和kafka对链接进行评分,并使所有数据对客户端可访问。

1
创建一个中央资源,其中包含一个哈希映射,可以将URL存储为键,并记录上次扫描的时间。确保线程安全。然后只需使用队列中的链接生成线程,爬虫可以从这些链接作为起点开始爬取。每个线程都会继续爬取和更新资源。资源中的一个线程清除过时的爬取。内存中的资源可以在启动时进行序列化,也可以根据应用程序的需要存储在数据库中。
您可以通过远程服务使此资源可访问,以允许多台机器使用。您还可以通过分离URL来将资源本身分布在多台机器上。等等...

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

1

如果你不想重复造轮子,为什么不看看Apache Nutch呢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接