全國服務(wù)熱線:400-080-4418
在關(guān)于網(wǎng)絡(luò)爬蟲的那些事(一)提到,如果爬蟲偽裝自己的User-Agent信息,就必須尋找新的辦法來封殺爬蟲了。事實上對網(wǎng)站來說,大的挑戰(zhàn)就是如何準(zhǔn)確的甄別一個IP發(fā)起的請求,究竟是真實用戶訪問還是爬蟲訪問呢?
先說點題外話,在很多年以前(2000年),我就做過網(wǎng)站流量統(tǒng)計系統(tǒng)。主流的網(wǎng)站流量統(tǒng)計系統(tǒng)不外乎兩種策略:一種策略是在網(wǎng)頁里面嵌入一段js,這段js會向特定的統(tǒng)計服務(wù)器發(fā)送請求的方式記錄訪問量;另一種策略是直接分析服務(wù)器日志,來統(tǒng)計網(wǎng)站訪問量。
在理想的情況下,嵌入js的方式統(tǒng)計的網(wǎng)站流量應(yīng)該高于分析服務(wù)器日志,這是因為用戶瀏覽器會有緩存,不一定每次真實用戶訪問都會觸發(fā)服務(wù)器的處理。但實際情況是,分析服務(wù)器日志得到的網(wǎng)站訪問量遠遠高于嵌入js方式,極端情況下,甚至要高出10倍以上。
現(xiàn)在很多網(wǎng)站喜歡采用awstats來分析服務(wù)器日志,來計算網(wǎng)站的訪問量,但是當(dāng)他們一旦采用Google Analytics來統(tǒng)計網(wǎng)站流量的時候,卻發(fā)現(xiàn)GA統(tǒng)計的流量遠遠低于awstats,所以開始懷疑GA的準(zhǔn)確性。其實GA的統(tǒng)計確實會略低于真實的用戶訪問量,但數(shù)據(jù)的真實性比較靠譜,不會偏差特別大。之所以略低是因為GA的服務(wù)器有時候用戶訪問不到,還有一種情況是訪問JavaEye的用戶所在公司使用了白名單,他能訪問JavaEye卻無法訪問GA服務(wù)器,此外也有可能用戶還沒有等到GA加載就跳轉(zhuǎn)到下一頁了,所以統(tǒng)計量沒有被GA計算。
那么為什么GA和awstats統(tǒng)計會有這么大差異呢? 罪魁禍?zhǔn)拙褪前炎约簜窝b成瀏覽器的網(wǎng)絡(luò)爬蟲。一些網(wǎng)絡(luò)爬蟲為了避免被網(wǎng)站以識別User-Agent的方式封殺,就修改了自己的User-Agent信息,通常偽裝成WindowsXP上的IE6瀏覽器,也有偽裝成Firefox瀏覽器的。這種情況下awstats無法有效的識別了,所以awstats的統(tǒng)計數(shù)據(jù)會虛高。不過說句公道話,這也怪不了awstats,只怪爬蟲太狡猾,不但awstats無法有效識別,就算我們?nèi)庋廴ゲ榭慈罩,也往往無法有效識別。
因此作為一個網(wǎng)站來說,如果希望了解自己的網(wǎng)站真實訪問量,希望精確了解網(wǎng)站每個頻道的訪問量和訪問用戶,開發(fā)自己的網(wǎng)站流量統(tǒng)計系統(tǒng)就顯得非常有必要性。JavaEye網(wǎng)站就開發(fā)了自己的網(wǎng)站流量統(tǒng)計系統(tǒng),采用在頁面里面嵌入js的方式來實現(xiàn)網(wǎng)站流量統(tǒng)計。因此我們可以精確的掌握登錄用戶和非登錄用戶的比例,不同的訪問偏好,JavaEye每個頻道精確的流量和比例,真實的用戶數(shù)量和分布等GA無法提供的有價值的信息。
JavaEye自己的流量統(tǒng)計系統(tǒng)盡管并不是為了甄別爬蟲而編寫的,但是他可以幫助甄別網(wǎng)絡(luò)爬蟲。我們知道只有用戶使用瀏覽器訪問頁面的時候才會執(zhí)行js,而爬蟲并不會執(zhí)行頁面里面的js,所以rails的production.log里面出現(xiàn)的IP地址,卻并沒有相應(yīng)的流量統(tǒng)計系統(tǒng)記錄這個IP地址,我們可以99%的斷定這個IP是個爬蟲。如果爬蟲編寫者專門偽裝真實IP向流量統(tǒng)計服務(wù)器發(fā)起請求的話,流量統(tǒng)計系統(tǒng)也有自己的防范作弊的機制,以及數(shù)據(jù)分析機制來甄別異常的訪問請求,這點就不展開討論了。
總之有了JavaEye流量統(tǒng)計系統(tǒng)提供的真實IP作為參考標(biāo)準(zhǔn),我們就可以拿日志里面出現(xiàn)的IP地址進行比較,如果日志里面某個IP發(fā)起了大量的請求,在流量統(tǒng)計系統(tǒng)里面卻根本找不到,或者即使找得到,可訪問量卻只有寥寥幾個,那么這無疑就是一個網(wǎng)絡(luò)爬蟲,我們可以直接用iptables封殺該C段地址了。
根據(jù)這種策略,我們可以重新調(diào)整封殺方案。首先統(tǒng)計production.log,統(tǒng)計訪問多的200個C段地址,這僅僅需要一條shell命令:
grep Processing production.log | awk ‘{print $4}’ | awk -F‘! ‘{print $1“!$2“!$3“.0”}’ | sort | uniq -c | sort -r -n | head -n 200 》 stat_ip.log
這200個C段地址就是我們需要重點考察的對象,網(wǎng)絡(luò)爬蟲就混跡在這200個C段地址之內(nèi)。它的格式大致如下,顯示訪問請求多的C段IP地址和請求次數(shù):[Page]
99650 203.208.60.0
55813 123.125.66.0
21131 221.235.58.0
18360 72.14.199.0
14632 121.0.29.0
11789 202.165.185.0
10539 61.135.216.0
10153 65.55.106.0
7001 65.55.211.0
4240 65.55.207.0
3789 219.133.0.0
3721 194.8.74.0
然后我們還需要流量統(tǒng)計系統(tǒng)提供的真實IP地址的C段地址作為參考,這已經(jīng)由流量統(tǒng)計系統(tǒng)提供給我們了。
接著我們還需要準(zhǔn)備一個白名單列表,比方說Google和百度的爬蟲IP地址段,對于這些爬蟲,我們給予放行,究竟放行哪些爬蟲,就需要完全根據(jù)自己網(wǎng)站的情況而定了。例如JavaEye現(xiàn)在的白名單(還在不斷添加中):
60.28.204.0 抓蝦
61.135.163.0 百度
61.135.216.0 有道
65.55.106.0 微軟
65.55.207.0 微軟
65.55.211.0 微軟
66.249.66.0 Google
72.14.199.0 Google
121.0.29.0 阿里巴巴
123.125.66.0 百度
124.115.10.0 騰訊搜搜
124.115.11.0 騰訊搜搜
124.115.12.0 騰訊搜搜
203.208.60.0 Google
209.85.238.0 Google
219.239.34.0 鮮果
220.181.50.0 百度
220.181.61.0 搜狗
后我們還需要準(zhǔn)備一個IP地址庫,對于那些被我們揪出來的爬蟲,我們還需要甄別一下他的身份,它究竟是一個惡意的爬蟲,還是一個未被我們放入白名單的合法爬蟲呢?IP地址庫很容易從互聯(lián)網(wǎng)下載一份,所以也不展開討論了。總之有了這些素材,我們要甄別網(wǎng)絡(luò)爬蟲就十分簡單了,僅僅十幾行ruby代碼就搞定了:
whitelist = []
IO.foreach(“#{RAILS_ROOT}/lib/whitelist.txt”) { |line| whitelist 《《 line.split[0].strip if line }
realiplist = []
IO.foreach(“#{RAILS_ROOT}/log/visit_ip.log”) { |line| realiplist 《《 line.strip if line }
iplist = []
IO.foreach(“#{RAILS_ROOT}/log/stat_ip.log”) do |line|
ip = line.split[1].strip
iplist 《《 ip if line.split[0].to_i 》 3000 && !whitelist.include?(ip) && !realiplist.include?(ip)
end
Report.deliver_crawler(iplist)
代碼的實現(xiàn)很簡單,就是讀入訪問請求次數(shù)超過3000次的C段地址,根據(jù)經(jīng)驗來說,超過3000次的訪問請求已經(jīng)非常可疑了。然后去掉白名單里面的C段地址,再去掉出現(xiàn)在真實訪問列表中的IP地址段,后剩下來的就是高度可疑的C段地址了。對于這些地址查詢IP地址數(shù)據(jù)庫信息,再格式化成報告自動給我發(fā)送電子郵件。
后需要人肉的簡單識別,比方說某地址的來源信息顯示為“Google公司總部”,那么我就知道這個地址需要添加到白名單里面。除去這些可以肉眼識別的地址,剩下來的就可以統(tǒng)統(tǒng)干掉了。
另外,對于這個簡單的程序還需要進一步完善,比方說不是簡單的根據(jù)realiplist進行比對和排除,而是給realiplist也建立一個ip段的統(tǒng)計信息,即使該段地址有真實訪問量,仍然需要進一步甄別,用該地址的請求數(shù)量除以realiplist里面的訪問數(shù)量,如果倍數(shù)大于一個閥值比方說1000,就可以斷定仍然是網(wǎng)絡(luò)爬蟲。
四、使用瀏覽器內(nèi)核驅(qū)動的網(wǎng)絡(luò)爬蟲
有人在文章后面的評論里面提到一種新的爬蟲的爬取方式,就是不用程序去爬取,而是編程控制一個真正的瀏覽器內(nèi)核去爬取網(wǎng)站,由于瀏覽器內(nèi)核可以真正執(zhí)行js,所以會被識別為真實用戶訪問,從而避開網(wǎng)站的檢查機制。這種爬蟲是難以甄別的爬蟲,如果精心編寫,甚至可以欺騙Google的服務(wù)器。由于Safari的webkit瀏覽器內(nèi)核和Firefox的Gecko瀏覽器內(nèi)核都是開源的,因此一個水平比較高的程序員自己動手編寫程序驅(qū)動一個真實的瀏覽器內(nèi)核作為爬蟲并不是非常困難的事情。
實際上這種爬蟲我們也遇到過幾次,但也并不難以甄別,只是需要一定的手工甄別機制,難以用程序全部自動化甄別。我們知道一個網(wǎng)站的真實用戶訪問量如果沒有短期的市場推廣活動,那么會保持一個比較穩(wěn)定的水平,如果網(wǎng)站的訪問量出現(xiàn)一個比較大的跳躍,或者網(wǎng)站頻道之間的訪問比例出現(xiàn)突變,就可以99%斷定有此類爬蟲出現(xiàn)了。[Page]
那么要甄別它也很簡單,對真實訪問IP進行統(tǒng)計和排序,挑選出來前200名C段IP地址中每天訪問量超過3000次的IP段地址,然后去除白名單,后再用IP地址數(shù)據(jù)庫去比對。根據(jù)經(jīng)驗來說,一個C段地址每天超過3000次訪問已經(jīng)肯定是一個大公司在訪問JavaEye了,可如果該來源C段并非出自像阿里巴巴,IBM中國公司,搜狐,騰訊這樣的公司地址,就可以99%斷定是網(wǎng)絡(luò)爬蟲,直接用iptables干掉該C段地址。
總之,通過這種方式目前已經(jīng)可以有效甄別偽裝的網(wǎng)絡(luò)爬蟲,以及通過n多國外代理服務(wù)器的分布式網(wǎng)絡(luò)爬蟲,不過網(wǎng)站和爬蟲之間的戰(zhàn)爭永遠不會結(jié)束,我們可以通過每天的日志報告來檢測網(wǎng)站的運行狀況,一旦發(fā)現(xiàn)數(shù)據(jù)報告異常,就知道有新的爬蟲出現(xiàn),那么就可以通過日志分析尋找封殺它的新辦法。
Copyright 2008 © 上海網(wǎng)至普信息科技有限公司 All rights reserved. 滬ICP備11006570號-13
滬公網(wǎng)安備 31011402007386號