基于余弦相似性的404页面识别

也许老街的腔调,是属于我的忧伤

  写过爬虫或者漏洞扫描器的朋友肯定遇到过一个问题,就是如何判断一个url对应的页面是个404页面,因为这对之后的逻辑判断尤为重要。然而由于存在一些特殊情况,导致404页面判断没有想象中的那么简单,这往往跟服务器配置有关。本篇作为《漫谈漏洞扫描器的设计与开发》的一个分支文章,重点谈谈如何判断一个页面是否为404页面。

404页面

  一般情况下,判断一个网页是否为404页面,主要看其返回的响应码。若响应码为404,则说明这是一个不存在的页面,若不是则说明是一个存在的页面。然而出于对用户的友好,有些网站往往会优化404页面,大致有以下几种优化方式。

跳转到指定页面

  第一种优化方式是:一旦用户访问了一个不存在的页面,服务器会将请求跳转到一个指定的url,往往是网站首页,或者是网站登陆页面。这种情况下,请求一个不存在的页面的响应码会从302变为200(服务端跳转),或者响应码直接为200(客户端跳转,用户可感);网页内容为网站首页或者网站登陆页面等指定页面的内容。
例子:http://didichuxing.com/nmask

跳转到优化后的404页面

  第二种优化方式是:一旦用户访问了一个不存在的页面,服务器会将请求跳转到404页面,与第一种方式不同的是跳转后的这个页面确实是404页面,但是是经过特殊处理优化的。这种情况下,请求一个不存在的页面的响应码会从302变为200(服务端跳转),或者响应码为200(客户端跳转),网页内容为一个经过优化的404页面内容。
例子:https://www.jd.com/nmask

直接显示404页面

  第三种方式是:一旦用户访问了一个不存在的页面,页面直接显示为404页面(服务器默认)。这种情况下,请求一个不存在的页面的响应码可能是404(默认情况),也可能是200,页面内容为默认404或者处理后的404页面。
例子:http://www.alibaba.com/nmask

总结404页面的特征

  综上所诉,一个404页面的响应码可能为:404,302,200(当然不排除有其他情况);一个404页面的页面内容可能是:网站首页内容(指定页面)、优化后的404页面内容、服务器默认的404页面内容。

如何科学的判断一个404页面?

综上所诉,我们大致可以得到这样的判断逻辑:(伪代码如下)

1
2
3
4
5
6
if 响应码 == 404:
return this_is_404_page
elif 目标网页内容 与 网站404页面内容 相似:
return this_is_404_page
else:
return this_is_not_404_page

  但要通过以上的逻辑判断,需要解决两个问题。问题一:如何提前收集网站的404页面内容;问题二:如何判断目标网页内容与网站404页面内容是否相似。
  先解决下问题一,这个比较好解决,我们可以构造一些不存在的路径(比如:/this_is_a_404_nmask_page),请求获取页面内容。
  第二个问题比较麻烦,首先我们需要注意这里指的是网页相似而非相同。为何这里不直接判断是否相同呢?因为一些404页面内容包含随机因子,比如当前时间,或者页面包含一些推广的信息,导致每个404页面内容都有差异。因此如何判断目标网页内容与网站404页面内容是否相似,而非相同,才是识别一个网页是否为404页面的科学方法。
  那么该如何判断2个网页是否相似呢?这里借鉴了判断文章相似性的算法—余弦相似性算法。那么什么叫余弦相似性算法,它又怎么用于判断网页相似性呢?请往下看。

余弦相似性算法介绍

假设我们有需求:判断两篇文章是否相似?
实现方案:
(1)使用TF-IDF算法,找出两篇文章的关键词;
(2)每篇文章各取出若干个关键词(比如20个),合并成一个集合,计算每篇文章对于这个集合中的词的词频(为了避免文章长度的差异,可以使用相对词频);
(3)生成两篇文章各自的词频向量;
(4)计算两个向量的余弦相似度,值越大就表示越相似。

具体例子:
句子A:我/喜欢/看/电视,不/喜欢/看/电影。
句子B:我/不/喜欢/看/电视,也/不/喜欢/看/电影。

得出所有分词为:我,喜欢,看,电视,电影,不,也。

计算词频:(出现的次数)
句子A:我 1,喜欢 2,看 2,电视 1,电影 1,不 1,也 0。
句子B:我 1,喜欢 2,看 2,电视 1,电影 1,不 2,也 1。

计算词频向量:
句子A:[1, 2, 2, 1, 1, 1, 0]
句子B:[1, 2, 2, 1, 1, 2, 1]

我们可以把它们想象成空间中的两条线段,我们可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。

计算公式:

计算结果:

说明:余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫”余弦相似性”。

基于余弦相似性算法的网页相似性判断方法

下面列举了余弦相似性算法与汉明距离算法,测试发现对于判断网页相似性余弦相似性算法准确率更高一些。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
一)网页标签相似性(筛选出网页所有标签,只选标签名称)
先计算出两个网页所有标签的向量:
A:(a,b,c,d,e,f,g,a,b,c)
B:(a,c,b,d,e,f,g,a,c)
1)计算A与B的汉明距离:
a,b,c,d,e,f,g,a,b,c
a,c,b,d,e,f,g,a,c
——————————————————
0 1 1 0 0 0 0 0 1 1
A与B的汉明距离为 1+1+1+1=4,相似度为:(10-4)/10=60%
2)计算A与B的余弦相似性:
A: a 2 b 2 c 2 d 1 e 1 f 1 g 1
B: a 2 b 1 c 2 d 1 e 1 f 1 g 1
继续简化:
A: [2,2,2,1,1,1,1]
B: [2,1,2,1,1,1,1]
余弦相似性:
2*2+2*1+2*2+1*1+1*1+1*1+1*1
------------------------------------------------------------------------------
((2^2+2^2+2^2+1^2+1^2+1^2+1^2) ** 0.5) * ((2^2+1^2+2^2+1^2+1^2+1^2+1^2) ** 0.5)
14
= -------------
4 * (13**0.5)
= 0.97
即相似性为97%
二)网页文本相似性计算
与标签判断算法一样,只是需要筛选出网页文本,并进行分词

说明:汉明距离更注重顺序相似,比如一个网页的标签排序顺序是否相似;而余弦相似性更关注整体标签的个数关系,对顺序不敏感。汉明距离可以看成是点与点间的距离,余弦相似性可以看成是线与线之间的夹角或者说距离。

更加严谨的科学判断

  通过余弦相似性算法,我们大致可以计算出两个网页的相似度。那么看似以上逻辑判断应该就可以判断出404页面了。然而实际情况还要更复杂些,比如如何设置相似度的阀值,还需要大量的打标数据去计算。再比如如何降低一些特殊url带来的误报。这里特殊的url包含网站首页、登陆页面等,因为当访问一些404页面时,可能会跳转到此页面上,导致网页相似性计算结果很接近。这些问题的解决方案这里就不介绍了。

判断404页面的测试接口

基于以上理论,我自己部署了一个判断404页面的api接口,可供大家测试一下准确性。
api接口地址:http://api.nmask.cn/not_exist_page_calculation/?target_url=http://www.baidu.com/nmask
若遇到判断错误的url,可在下方留言,或者邮件:[email protected]

本文标题:基于余弦相似性的404页面识别

文章作者:nMask

发布时间:2018年04月12日 - 16:04

最后更新:2018年04月13日 - 09:04

原始链接:http://thief.one/2018/04/12/1/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

nMask wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
坚持原创技术分享,您的支持将鼓励我继续创作!