检查网页内容是否已更改的最佳方法是什么?

5
我有一个爬虫,可以爬取数十万个页面并索引/解析页面的内容,但我遇到的问题是如何以高效的方式检查页面内容是否已更新,而不必爬取页面并检查其内容。
显然,我可以加载整个页面,重新解析所有内容,并将其与数据库中存储的内容进行比较。然而,这非常低效,会消耗大量计算资源,导致高额的主机费用。
我考虑比较哈希值,但问题在于如果页面改变了一个字节或字符,哈希值就会不同。例如,如果页面在页面上显示当前日期,则每次哈希值都会不同,告诉我内容已更新。
那么...你会怎么做呢?你会查看HTML的kb大小吗?您会查看字符串长度并检查例如长度是否增加了5%以上,表示内容已“更改”吗?还是有一种哈希算法,只要字符串/内容的小部分发生变化,哈希值就保持不变?

你正在爬取的网站上,last-modified头信息(或可选的ETag)是否可靠?如果是,就使用它。 - roippi
请使用 HEAD HTTP 请求,而不是普通的 GET - Sylvain Leroux
我正在爬取许多不同类型的域和网站,并且我们也在扩展到新的域。因此,一种可靠地适用于所有域的方法将是首选。 - Marcus Lind
关于 last-modified - 不幸的是,并非所有服务器都能正确返回此日期。我认为这不是一个可靠的解决方案。我认为更好的方式是将哈希和内容长度组合在一起。检查哈希值,如果发生了改变,则检查字符串长度。 - stepozer
关于内容长度 - 您可以尝试去除所有标签并检查字符串长度。在这种情况下,您可以忽略HTML更改。此外,您可以将所有连续的空格替换为一个,以防止它对哈希产生影响。 - stepozer
1
两步走怎么样?您可以使用哈希来筛选可能已更改的页面。如果哈希匹配,则页面未更改。如果不匹配,则可以解析以确定更改是否重要。只要没有太多误报(即哈希值发生变化但内容实际上没有更改),这应该是相当高效的。 - Mike Satteson
1个回答

2
你可以尝试使用服务器响应中“last-modified”头部包含的值。将其解析为一个漂亮的对象,可以进行简单的日期比较,让你检查是否需要重新抓取。例如(在Python中使用优秀的requests库):
import requests
r = requests.get('http://en.wikipedia.org/wiki/Monty_Python')
site_last_modified_date = r.headers["Last-Modified"]

# from here, just parse the date and compare it with the last recorded date

1
不幸的是,并非所有服务器都能正确返回此日期。我认为这不是可靠的解决方案。 - stepozer
谢谢您的回答,但正如我之前在评论中所述,由于我们爬取许多不同的服务器和域名,我们希望找到一个更可靠的解决方案,适用于任何地方。 - Marcus Lind

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