【问题标题】:What would be an appropriate data structure for storing URLs that have been visited by a web crawler?存储网络爬虫访问过的 URL 的合适数据结构是什么?
【发布时间】:2013-04-16 03:59:44
【问题描述】:

我正在用 C# 编写一个网络爬虫供我个人使用。它的主要目的是从它爬取的网页下载图像。除了下载的图片,它不会保存网页中的任何数据。

我有一些逻辑将爬虫访问的所有 URL 的文字字符串存储在列表中。这对于短暂的抓取会话来说已经足够了,但我想当抓取工具在一个包含数万个 URL 的列表中进行查找时,这将开始成为较长会话的瓶颈。我还在我的 URL 队列中进行查找,以便在等待抓取的 URL 队列中没有重复的 URL。

我的问题分为两部分:

1) 目前我没有在爬取会话之间存储任何数据,这目前很好。在爬虫运行时,有没有比简单的字符串列表更好的方法来存储已经访问过的 URL?

2) 如果我要开始在磁盘上永久存储数据以供多个会话使用,在这种情况下您建议如何存储访问过的 URL?

【问题讨论】:

  • 数据库听起来是个不错的工具

标签: c# data-structures web-crawler


【解决方案1】:

这在很大程度上取决于您的抓取工具的抓取速度。如果您有一个单线程爬虫,那么平均而言,您不会比每秒一页做得更好。因此,您可以使用HashSet 来存储您访问过的 URL。或者,如果您想保存有关您访问过的 URL 的信息,您可以使用 Dictionary<string, UrlInfo>,其中 UrlInfo 是您定义的一个类,其中包含您要保留的有关每个访问过的 URL 的信息。

以每天 86,400 秒的速度,HashSetDictionary 将存储相当多天的数据。

但您可能不想多次下载同一张图片。因此,使用我所说的“离线”或“爬行-过程-爬行”模型可能会更好。以下是它的工作原理。

当您开始抓取时,您会访问(例如)您已识别的几千个页面。您下载页面,提取链接,然后将这些链接写入日志文件。如果您找到图像,则下载并保存这些图像。您访问的每个页面也会写入一个文件。

当您访问完这些页面后,您会停止爬虫。您现在有两个保存在文件中的列表:您访问过的页面和您找到的链接。

对访问过的链接进行排序,并将它们与您之前访问过的页面列表合并。随着时间的推移,该文件可能会变得相当大。

对您提取的链接列表进行排序,并删除重复项。然后根据您已经访问过的页面列表检查这些链接。这是最简单的合并。如果该链接已被访问过,则丢弃它。否则,将其写入将在下一次抓取会话中使用的文件。

使用简单的数据库会更容易,但请注意数据库会变得非常大。使用数据库,您不必爬行过程爬行。相反,您可以根据数据库检查提取的每个链接,然后立即保存或丢弃它。

不过,请理解,您将很难访问数据库。我的爬虫经验是,平均而言,一个网页包含超过 100 个链接(即<a href="...">。这不包括图像。您将每秒至少访问该数据库 100 次线程爬虫。

您会遇到的另一个问题是您无法访问找到的每个 URL。随着时间的推移,我发现在我从普通网页中提取的 100 个链接中,有 10 个是我以前从未见过的新链接。因此,对于我阅读的每一页,我都会发现还有 10 页我没有读过。最终,您将需要一些方法来过滤掉不太可能将您引导至图片的 URL。

另一种跟踪您访问过的网址的方法是使用Bloom Filter。我在我的网络爬虫中使用了这些效果。

【讨论】:

  • 感谢您的意见。如果它有任何区别,我的爬虫是多线程的。另外,字典的字符串部分会包含什么?
  • @DavidDeMar:该 URL 将进入字典的 string(键)。如果你的爬虫是多线程的,你需要在你的字典上进行某种同步(例如锁),以防止并发更新破坏它。您还必须将我上面的估计乘以线程数。数据库看起来是一种更好的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多