网络爬虫将访问过的 url 存储在文件中

Web crawler storing visited urls in file

我在弄清楚如何存储和扫描来自网络爬虫的大量已访问 URLS 时遇到了问题。这个想法是,访问的 URL 的数量最终会太多而无法存储在内存中,我应该将它们存储在文件中,但我想知道,这不会变得非常低效吗?如果在获得一批 URL 之后,我想检查 URL 是否已经被访问过,我必须逐行检查访问过的文件,看看是否存在匹配项?

我曾考虑过使用缓存,但当在缓存中找不到 URL 时问题仍然存在,我仍然需要检查文件。我是否必须逐行检查每个 URL 的文件,是否有 better/more 有效的方法来执行此操作?

此处的关键数据结构可能是 Bloom Filter, and Guava 提供的实现。 Bloom-filter 会告诉您(也许您已经访问过 URL)或者您不确定。如果结果是,也许你可以去检查文件是否已经访问过,否则你去访问 URL 并将它存储在文件和布隆过滤器中。 现在,为了优化文件查找,您可以散列 URL 以获得固定大小 byte[] 而不是不固定的字符串长度(例如:md5)。

byte[] hash = md5(url);
if(bloomFilter.maybe(hash)){
  checkTheFile(hash);
}else{
 visitUrl(url);
 addToFile(hash);
 addToBloomFilter(hash);
}

您可以使用数据库和散列作为主键来获得 O(1) 访问时间,当您检查一个键是否存在时,或者您可以自己实现一个 index

每个 URL 有一个文件怎么样?如果文件存在,则 URL 已被抓取。

然后您可以变得更复杂,并让此文件包含指示上次爬网结果的数据、下一次爬网之前要等待多长时间等。(能够发现 404 很方便,因为例如,并决定是重试还是放弃 URL。)

使用这种方法,值得规范化 URL,这样 URL 中的微小差异就不会导致不同的文件。

我在我的节点爬虫 (https://www.npmjs.com/package/node-nutch) 中使用了这种技术,它允许我将状态存储在文件系统中(对于简单爬虫)或 S3(对于涉及多个爬虫的爬虫)服务器)。