也許老街的腔調,是屬於個人憂傷
寫過爬蟲或者漏洞掃描器的朋友確定遇到過一個問題,就是如何判斷一個url對應的頁面是個404頁面,由於這對以後的邏輯判斷尤其重要。然而因爲存在一些特殊狀況,致使404頁面判斷沒有想象中的那麼簡單,這每每跟服務器配置有關。本篇做爲《漫談漏洞掃描器的設計與開發》的一個分支文章,重點談談如何判斷一個頁面是否爲404頁面。算法
通常狀況下,判斷一個網頁是否爲404頁面,主要看其返回的響應碼。若響應碼爲404,則說明這是一個不存在的頁面,若不是則說明是一個存在的頁面。然而出於對用戶的友好,有些網站每每會優化404頁面,大體有如下幾種優化方式。api
第一種優化方式是:一旦用戶訪問了一個不存在的頁面,服務器會將請求跳轉到一個指定的url,每每是網站首頁,或者是網站登錄頁面。這種狀況下,請求一個不存在的頁面的響應碼會從302變爲200(服務端跳轉),或者響應碼直接爲200(客戶端跳轉,用戶可感);網頁內容爲網站首頁或者網站登錄頁面等指定頁面的內容。 例子:didichuxing.com/nmask bash
第二種優化方式是:一旦用戶訪問了一個不存在的頁面,服務器會將請求跳轉到404頁面,與第一種方式不一樣的是跳轉後的這個頁面確實是404頁面,可是是通過特殊處理優化的。這種狀況下,請求一個不存在的頁面的響應碼會從302變爲200(服務端跳轉),或者響應碼爲200(客戶端跳轉),網頁內容爲一個通過優化的404頁面內容。 例子:www.jd.com/nmask 服務器
第三種方式是:一旦用戶訪問了一個不存在的頁面,頁面直接顯示爲404頁面(服務器默認)。這種狀況下,請求一個不存在的頁面的響應碼多是404(默認狀況),也多是200,頁面內容爲默認404或者處理後的404頁面。 例子:www.alibaba.com/nmask 微信
綜上所訴,一個404頁面的響應碼可能爲:404,302,200(固然不排除有其餘狀況);一個404頁面的頁面內容多是:網站首頁內容(指定頁面)、優化後的404頁面內容、服務器默認的404頁面內容。測試
綜上所訴,咱們大體能夠獲得這樣的判斷邏輯:(僞代碼以下)優化
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)計算兩個向量的餘弦類似度,值越大就表示越類似。ui
具體例子: 句子A:我/喜歡/看/電視,不/喜歡/看/電影。 句子B:我/不/喜歡/看/電視,也/不/喜歡/看/電影。this
得出全部分詞爲:我,喜歡,看,電視,電影,不,也。
計算詞頻:(出現的次數) 句子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度,也就是兩個向量越類似,這就叫"餘弦類似性"。
下面列舉了餘弦類似性算法與漢明距離算法,測試發現對於判斷網頁類似性餘弦類似性算法準確率更高一些。
一)網頁標籤類似性(篩選出網頁全部標籤,只選標籤名稱)
先計算出兩個網頁全部標籤的向量:
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頁面的api接口,可供你們測試一下準確性。 api接口地址:api.nmask.cn/not_exist_p… 若遇到判斷錯誤的url,可在下方留言,或者郵件:tzc@maskghost.com。
本文來自我的博客:基於餘弦類似性的404頁面識別 | nMask'blog
如需更多優質文章,請掃一掃關注微信公衆號
或者訪問我的博客:thief.one