存储web爬虫访问过的url的合适数据结构是什么?

本文关键字:数据结构 是什么 url 爬虫 访问 存储 web | 更新日期: 2023-09-27 18:10:21

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

我有一些逻辑,将爬虫访问的所有url的文字字符串存储在列表中。对于较短的爬行会话来说,这已经足够了,但我认为,当爬行程序在包含成千上万个url的列表中进行查找时,这将开始成为较长会话的瓶颈。我还在我的URL队列中做了一个查找,这样我就不会在等待抓取的URL队列中有重复的URL。

我的问题分为两部分:

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

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

存储web爬虫访问过的url的合适数据结构是什么?

这在很大程度上取决于爬虫的爬行速度。如果您使用的是单线程爬虫,那么您的平均速度不会比每秒处理一个页面好多少。因此,您可以使用HashSet来存储您访问过的url。或者,如果你想保存你访问过的URL的信息,你可以使用Dictionary<string, UrlInfo>,其中UrlInfo是你定义的一个类,它包含了你想要保存的关于每个访问过的URL的信息。

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

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

当你开始抓取时,你会访问,比如说,你已经识别的几千个页面。下载页面,提取链接,并将这些链接写入日志文件。如果找到图像,就下载并保存它们。你访问的每个页面也会被写入一个文件。

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

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

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

对于一个简单的数据库,这更容易,但要注意数据库将变得非常大。使用数据库时,您不必进行爬取-处理-爬取。相反,您可以根据数据库检查提取的每个链接,并立即保存或丢弃它。

请理解,您将对数据库造成相当大的冲击。我的爬行经验是,平均而言,一个网页包含超过100个链接(即<a href="...">)。它不包括图像。使用单线程爬虫,您将至少每秒访问该数据库100次。

你会遇到的另一个问题是你不能访问你找到的每个URL。随着时间的推移,我发现在我从网页中提取的平均100个链接中,有10个是我以前从未见过的新链接。所以我每读一页,就会发现我还有10页没读。最终,您将需要某种方法来过滤掉不太可能引导您到图像的url。

另一种跟踪您访问过的url的可能性是使用Bloom过滤器。