15

有哪些技术可以很好地检测一个网页是否与另一个网页相同?

同样,我不是指 char-for-char 等效项(这很容易),而是足够强大,可以忽略页面上的当前日期/时间等内容。

例如,去 Yahoo! 新闻文章加载页面,10 分钟后在另一个浏览器中打开同一页面。霸菱重写,这些页面会有一些差异(时间戳,可能是广告之类的东西,可能是相关故事之类的东西),但人类可以看着两者并说它们是相同的。

注意我不是试图修复(或依赖)URL 规范化。即,找出 foo.html 和 foo.html?bar=bang 是相同的。

4

13 回答 13

13

听起来您正在寻求一种可靠的方法来衡量两个页面的相似性。

鉴于页面结构不会发生太大变化,我们可以将问题归结为测试页面上的文本是否大致相同。当然,通过这种方法,nickf 提到的关于摄影师页面的问题仍然存在,但如果您主要关注的是 Yahoo!新闻之类的应该没问题。

要与页面进行比较,您可以使用机器学习中的一种称为“字符串内核”的方法。这是一篇早期论文,一组关于 R 包的最新幻灯片和一个视频讲座

非常粗略地,字符串内核会查找两个文档共有多少个词、词对、词组等。如果 A 和 B 是两个文档并且 k 是一个字符串内核,那么 k(A,B) 的值越高,两个文档就越相似。

如果你设置一个阈值 t 并且只说两个文档对于 k(A,B) > t 是相同的,那么你应该有一个相当好的方法来做你想做的事。当然,您必须调整阈值才能为您的应用程序获得最佳结果。

于 2009-01-19T02:05:51.877 回答
6

对于这类问题,我发现搜索学术论文比询问 StackOverflow 好得多,在处理具体问题时,专家通常比人群聪明得多。

每个网络爬虫或搜索引擎都有这个问题并且已经解决了。可能有一种使用基于内核的方法的好方法,就像公认的答案所建议的那样,但是您可能希望从已知效果很好的更简单的技术开始。之后您可以转到内核方法并测试它们是否可以改善您的结果。

最好的办法是阅读Henzinger 2006 年的论文“查找几乎重复的网页:算法的大规模评估”

并且您可能会将生成 Rabin 指纹作为使用'Fingerprinting by random polynomials' Rabin 1986 的第一步。

于 2012-09-19T20:47:03.513 回答
5

您可以通过使用某种相似度度量(例如余弦相似度)来检测两个页面是否相同。然后您必须定义一个最小阈值,您可以使用它来接受两个文档是否相同。例如,在应用余弦度量时,我会选择一个最接近 1 的值,因为它的范围从 -1 表示完全不同,1 表示相同。

于 2009-01-19T02:09:23.650 回答
2

我使用 vgrep 来处理这类事情。

这是一个鲜为人知的工具,称为visual-grep,它依赖于智能眼设备和视觉皮层等先进技术,可以非常快速地确定并排页面的相同性,而且它非常准确和高效(应该是因为它已经开发了很长时间)。

标记社区维基,以防幽默警察今天出局:-)。

于 2009-01-19T02:05:41.643 回答
2

根据您的工作,您可能对TemplateMaker感兴趣。你给它一些字符串(比如网页),它会标记出变化的部分。

在你的雅虎!新闻示例,您将获取页面一次并告诉 TemplateMaker 学习它。然后你会再次获取它并告诉它学习那个。

当您对您的 TemplateMaker 每次都知道相同的内容感到高兴时,您可以获取另一个页面并询问 TemplateMaker 它是否与其他页面的模板匹配。(如果您对此感兴趣,它将为您提供已更改的部分。)

于 2009-01-19T04:36:01.777 回答
1

您可以使用 Web 浏览器组件呈现两个页面的屏幕截图,然后比较图像。可能是最简单的选择。

于 2009-01-19T03:18:06.910 回答
0

如果不深入了解您要比较的页面的结构,那么这可能会非常棘手。也就是说,一台机器应该如何判断带有几张不同图片的页面是相同的——如果它是一个带有广告的新闻网站,那么它应该是相同的,但如果它是一个摄影师的作品集,那么它肯定是不同的。

如果您确实知道页面的结构,那么我要做的就是手动选择页面的各个部分(使用 ID、CSS 选择器、XPath 等)进行比较。例如,只比较#content页面刷新之间的 div。从那里,您可能需要在逐个字符比较中添加容差级别。

实际上,有一项服务可以做类似的事情。它被称为Rsspect(由 Qwantz 名声的 Ryan North 编写),即使您不控制页面,它也会检测任何网站的更改并从中创建 RSS 提要。

于 2009-01-19T01:51:50.500 回答
0

您可以为它们中的每一个生成一个 MD5 哈希,然后进行比较。就像你说的,很简单。

您正在寻找的是一种技术,用于比较具有可以更改的任意元素的两个页面。这是一个难题。

  1. 确定页面中可以更改且您不关心的区域。小心!他们总会四处走动。
  2. 散列或对您关心的页面部分的 DOM 进行校验和。小心!这些也将一直在变化。

您违反了屏幕抓取的第一条规则:页面本质上是易变的。所以这是一个棘手的问题。您的解决方案永远不会足够强大,无法解决您的源数据将受到的无数种细微变化,除非您还可以直接控制源页面并且可以针对此设计您的解决方案。

祝你好运!我有过尝试解决这个问题的系统的经验,这确实是一个难以破解的难题。

于 2009-01-19T01:53:08.407 回答
0

做到这一点的方法是不比较整个页面,因为正如你所说的那样,人类也不会被欺骗。假设您对 Yahoo! 的新闻文章感兴趣 页面,所以你应该只看新闻部分。然后你可以做任何事情,新旧版本之间的哈希或文字比较。

于 2009-01-19T01:53:23.760 回答
0

我的第一个想法是使用 BeautifulSoup (Python) 将页面处理为 XML 文档,对它们运行 diff,并计算不同的行数。如果计数 > X%,则它们是不同的。不是很健壮并且可能容易出错,但这将是我为测试所做的快速破解。

您可能想看看这个讨论比较两个 XML 文档的页面:http:
//www.ibm.com/developerworks/xml/library/x-diff/index.html

可以将 html 文档强制转换为 XML 文档,然后使用此处列出的技术进行比较。

于 2009-01-19T03:11:09.873 回答
0

我有一个类似的问题。我试图为用户提交的链接目录设计一个安全的链接系统。用户将在博客或新闻站点上发布页面并提交指向索引的链接。人类会验证链接是否合适,然后将页面添加到索引中。

问题是想出一种自动检查的方法,以确保链接随着时间的推移仍然合适。例如,是否有人在几周后修改了页面并插入了种族诽谤?新闻网站是否开始告诉人们“你必须订阅才能阅读这个故事”?

我最终提取了段落 <p> 元素并将缓存的副本与当前逐字比较。用最简单的话来说:

cached[] = { "Lorem", "Ipsum", "..." };
scanned[] = { "Lorem, "foo", ... };

在那之后,一系列的分类器会在处理它的同时忽略常用词“if but can or and”,同时以更重的权重对待其他词(亵渎等)。

这导致了一个评分系统几乎忽略了微小的编辑和修订(错别字、句子结构等),但会迅速揭示是否需要再次检查内容。然后返回一个分数,超过阈值的分数将被放入队列中以供人类重新验证。

这也有助于解释网站的重大外观变化。我不相信它会完全独立运行,但在人类的一点帮助下,它确实可以很好地完成它的工作。诚然,就方法论而言,该系统的效率并不高。

于 2009-01-19T03:40:23.403 回答
0

您可以尝试使用 HTTP 标头,例如 If-Modified-Since,或其他一些与缓存相关的标头。此外,查看站点地图文件可能会有所帮助,以了解搜索引擎应该多久查看一次。

我的另一个尝试(可能结合使用)是列出页面上 s 中找到的所有ids 和classes div。如果这些列表不匹配,则很可能发生了相当明显的变化。否则,它们可能非常相似。

编辑:您也可以比较元素的srcs 。img

于 2009-01-19T15:07:35.933 回答
0

我最近遇到了这个问题并在这里研究了一个 JavaScript 解决方案: https ://github.com/kennychua/pdiffy/

它允许您比较页面的图像(最好是无损 PNG 格式),它会告诉您图像是否不同,如果不同,它将突出显示差异。

它还能够忽略您描述的时间戳问题等区域

于 2013-09-02T08:36:55.713 回答