天天看點

如何對付網絡爬蟲 - JavaEye和網絡爬蟲鬥争之路

http://www.kuqin.com/searchengine/20090806/66174.html

作者:robbin 來源:JavaEye

由于搜尋引擎的泛濫,網絡爬蟲如今已經成為全球網際網路的一大公害。除了專門做搜尋的Google,Yahoo,微軟,百度以外,幾乎每個大型門戶網站都有自己的搜尋引擎,搜狐,騰訊,網易。再加上十分流氓的社群搜尋奇虎等等,國内大大小小叫得出來名字得就幾十家,還有各種不知名的幾千幾萬家,另外還有國外各種奇奇怪怪的搜尋引擎。隻要你做的網站是内容豐富的網站,就避免不了被幾千幾萬個爬蟲每天爬來爬去。

大的搜尋引擎如Google的爬取網頁十分智能,爬取頻率和爬取壓力都沒有那麼高,對網站資源消耗還比較少,最怕各種各樣弱智的爬蟲,對網頁内容的分析能力很差,經常并發幾十上百個請求循環重複抓取,對網站往往是毀滅性打擊。

我随便舉幾個例子:網易有道搜尋曾經在一個上午的時間就通路了JavaEye網站60多萬次請求,把網站通路拖得很慢,被我們立刻封殺。還比方說雅虎爬蟲的爬行也十分弱智,經常循環爬取,爬行頻率非常高,也被我們封殺掉了。然而最可怕的還是奇虎的爬蟲,他托管在河北廊坊機房的伺服器上面的爬蟲,經常并發上百個請求同時爬取,我有次解除了對該機房的封鎖,幾秒鐘之内,JavaEye網站就徹底無法通路,觀察web servr上面堵塞了幾百個來自奇虎爬蟲的請求。

除了這些叫得出來名字的爬蟲之外,還有很多程式員自己寫的山寨爬蟲,特别是一些菜鳥程式員,完全沒有編寫爬蟲的經驗,寫出來的爬蟲破壞力極強。曾經有一次我在JavaEye的日志裡面發現一個User-Agent是Java的爬蟲一天之内爬行了将近100萬次動态請求。毫無疑問是個利用JDK類庫編寫的簡單爬網頁程式,由于JavaEye網站内部連結構成了回環導緻該程式陷入了爬行死循環,而程式沒有相應的處理代碼,導緻網站資源被大量消耗。

對于一個原創内容豐富,URL結構合理易于爬取的網站來說,簡直就是各種爬蟲的盤中大餐,很多網站的通路流量構成當中,爬蟲帶來的流量要遠遠超過真實使用者通路流量,甚至爬蟲流量要高出真實流量一個數量級。即使像JavaEye這樣一向嚴厲封殺爬蟲的網站,隻要稍微松懈一段時間,爬蟲流量就能輕易超過真實通路流量的2倍以上。對于大型網際網路網站來說,有足夠的硬體資源來應付爬蟲帶來的龐大通路壓力,也有足夠的資源和能力去解決這個問題。但是對于中小型網際網路網站來說,爬蟲帶來的就是毀滅性打擊了。

JavaEye網站也一直被網絡爬蟲問題所困擾,并且不斷采用一些新的手段對付網絡爬蟲,網站和爬蟲之間的戰争就像此消彼長的拉鋸戰一樣。

一、野蠻型爬蟲

在2006年的時候,JavaEye遭遇的網絡爬蟲基本上都是比較野蠻的爬蟲,動不動上百個并發請求一起過來,網站立刻被拖慢或者幹脆無法通路,例如奇虎的爬蟲就是這樣(百度的爬蟲早期也是如此,現在已經斯文多了)。這種爬蟲是很容易識别出來的,通過netstat資訊檢視,或者web server提供的并發連接配接資訊,比方說lighttpd的mod_status就可以非常直覺的觀察到目前每個并發連接配接的狀态,請求的位址和IP,以及連接配接時間。

對付這種野蠻的爬蟲其實沒有什麼太好的辦法,隻有一種辦法,就是直接封殺。然而爬蟲往往并不分布在一台伺服器上,而是很多台伺服器上面,是以你封掉一個ip位址根本不解決問題,是以我們采取的辦法就是直接封殺爬蟲所在的C網段位址,例如:

C代碼

如何對付網絡爬蟲 - JavaEye和網絡爬蟲鬥争之路
  1. iptables -A INPUT -i eth0 -j DROP -p tcp --dport 80 -s 84.80.46.0/24  
iptables -A INPUT -i eth0 -j DROP -p tcp --dport 80 -s 84.80.46.0/24
      

除此之外還可以采取一些輔助的解決辦法,比方說在web server上面限制每IP并發連接配接數量,如果超過一定的并發連接配接數量,就直接傳回拒絕請求的頁面。例如lighttpd可以這樣配置:

C代碼

如何對付網絡爬蟲 - JavaEye和網絡爬蟲鬥争之路
  1. $HTTP["url"] =~ "^/topics/download/" {   
  2.   evasive.max-conns-per-ip = 2   
  3. }  
$HTTP["url"] =~ "^/topics/download/" {
  evasive.max-conns-per-ip = 2
}
      

限定每IP隻能并發一個線程下載下傳。

總的來說,這種蠻不講理的爬蟲相對比較稀少,碰到一個封殺一個C段位址基本可以解決此類爬蟲。現在JavaEye已經很少遇到這種爬蟲了。

這裡要特别說明一點:有很多人提出一種極度腦殘的觀點,說我要懲罰這些爬蟲。我專門在網頁裡面設計不消耗資源的靜态循環連結頁面,讓爬蟲掉進陷阱,死循環爬不出來。能出這種弱智點子的人一看就知道紙上談兵。根本用不着你設定陷阱,弱智爬蟲對正常網頁自己就爬不出來,你這樣做多此一舉不說,而且會讓真正的搜尋引擎降低你的網頁排名。

而且運作一個爬蟲根本不消耗什麼機器資源,我在自己的筆記本電腦上面跑個Java程式,發起上百個線程,就算死循環了,也消耗不了多少CPU,根本不消耗我什麼。相反,真正寶貴的是你的伺服器CPU資源和伺服器帶寬,誰消耗誰阿?做程式員最可怕的不是弱智,而是自己不知道自己弱智,總以為自己很明智。

二、爬蟲的海量抓取和海量的各種小爬蟲

有很多智能程度比較低的爬蟲,比方說雅虎和網易有道的爬蟲,它雖然并不會以很高的并發連接配接爬取你的網站,但是它會以較低的頻率持續不間斷爬取網站,一天下來至少爬取幾十萬頁面,極大消耗了伺服器資源,拖慢伺服器的響應速度。而且由于它爬取的并發不高,一般不容易暴露自己,特别是雅虎的爬蟲,分布很廣,來自大約二十幾個C段位址,狡兔n窟,你很難找全它所有的C段位址,是以通過簡單的封殺IP位址段,對這種爬蟲基本無效。

另外還有很多各種各樣的小爬蟲,特别是以國外的各式各樣稀奇古怪的搜尋引擎為主,它們都在嘗試Google以外創新的搜尋方式,每個爬蟲每天爬取你幾萬的網頁,幾十個爬蟲加起來每天就能消耗掉你上百萬動态請求的資源。由于每個小爬蟲單獨的爬取量都很低,是以你很難把它從每天海量的通路IP位址當中把它準确的挖出來,是以也沒有辦法通過直接封殺IP的方式對付它們。

怎麼解決這個問題呢? 其實這些爬蟲都有一個共同的特點,在爬取網頁的時候,會聲明自己的User-Agent資訊。我們知道每個浏覽器都有自己獨一無二的User-Agent資訊,比較正規的爬蟲,特别是來自國外的爬蟲都比較規矩,會聲明自己的User-Agent資訊,是以我們就可以通過記錄和分析User-Agent資訊來挖掘和封殺這些爬蟲。

首先我們需要記錄每個請求的User-Agent資訊,對于用rails開發的JavaEye網站來說這很簡單,我們在app/controllers/application.rb裡面添加一個全局的before_filter,來記錄每個請求的User-Agent資訊:

Ruby代碼

如何對付網絡爬蟲 - JavaEye和網絡爬蟲鬥争之路
  1. logger.info "HTTP_USER_AGENT #{request.env["HTTP_USER_AGENT"]}"  
logger.info "HTTP_USER_AGENT #{request.env["HTTP_USER_AGENT"]}"
           

這樣就會把每個請求的User-Agent資訊記錄到production.log裡面去。

然後我們統計每天的production.log,抽取User-Agent資訊,找出通路量最大的那些User-Agent。但是這裡要注意的是我們隻關注那些爬蟲的User-Agent資訊,而不是真正浏覽器User-Agent,是以我們還要排除掉浏覽器User-Agent,最後我們就可以得到一個通路量最多的爬蟲清單。要做到這一點僅僅需要一行shell:

C代碼

如何對付網絡爬蟲 - JavaEye和網絡爬蟲鬥争之路
  1. grep HTTP_USER_AGENT production.log | grep -v -E 'MSIE|Firefox|Chrome|Opera|Safari|Gecko' | sort | uniq -c | sort -r -n | head -n 100 > bot.log  
grep HTTP_USER_AGENT production.log | grep -v -E 'MSIE|Firefox|Chrome|Opera|Safari|Gecko' | sort | uniq -c | sort -r -n | head -n 100 > bot.log
      

這行shell指令從production.log裡面抽取包含User-Agent的日志,然後排除真實浏覽器的User-Agent,再統計通路量,然後按照通路量從大到小排序,最後挑選排名前100的記錄到日志檔案裡面去。或者你也可以直接把輸出内容發送到你的郵箱裡面去。

最終的爬蟲統計結果類似下面這樣:

C代碼

如何對付網絡爬蟲 - JavaEye和網絡爬蟲鬥争之路
  1. 57335 HTTP_USER_AGENT Baiduspider+(+http://www.baidu.com/search/spider.htm)   
  2. 56639 HTTP_USER_AGENT Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)   
  3. 42610 HTTP_USER_AGENT Mediapartners-Google   
  4. 19131 HTTP_USER_AGENT msnbot/2.0b (+http://search.msn.com/msnbot.htm)   
  5.  8980 HTTP_USER_AGENT Mozilla/5.0 (compatible;YoudaoFeedFetcher/1.0;http://www.youdao.com/help/reader/faq/topic006/;1 subscriber;)   
  6.  8034 HTTP_USER_AGENT Sosoblogspider+(+http://help.soso.com/soso-blog-spider.htm)   
  7.  7847 HTTP_USER_AGENT msnbot/1.1 (+http://search.msn.com/msnbot.htm)   
  8.  4342 HTTP_USER_AGENT Mozilla/5.0 (compatible; Google Desktop)   
  9.  3183 HTTP_USER_AGENT   
  10.  3115 HTTP_USER_AGENT Mozilla/4.0   
  11.  2900 HTTP_USER_AGENT WordPress/2.7   
  12.  2096 HTTP_USER_AGENT Apple-PubSub/65.11   
  13.  1891 HTTP_USER_AGENT Zhuaxia.com 1 Subscribers   
  14.  1201 HTTP_USER_AGENT Apple-PubSub/65   
  15.  1154 HTTP_USER_AGENT Mozilla/5.0 (compatible;YoudaoFeedFetcher/1.0;http://www.youdao.com/help/reader/faq/topic006/;2 subscribers;)   
  16.  1059 HTTP_USER_AGENT FeedBurner/1.0 (http://www.FeedBurner.com)  
57335 HTTP_USER_AGENT Baiduspider+(+http://www.baidu.com/search/spider.htm)
  56639 HTTP_USER_AGENT Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
  42610 HTTP_USER_AGENT Mediapartners-Google
  19131 HTTP_USER_AGENT msnbot/2.0b (+http://search.msn.com/msnbot.htm)
   8980 HTTP_USER_AGENT Mozilla/5.0 (compatible;YoudaoFeedFetcher/1.0;http://www.youdao.com/help/reader/faq/topic006/;1 subscriber;)
   8034 HTTP_USER_AGENT Sosoblogspider+(+http://help.soso.com/soso-blog-spider.htm)
   7847 HTTP_USER_AGENT msnbot/1.1 (+http://search.msn.com/msnbot.htm)
   4342 HTTP_USER_AGENT Mozilla/5.0 (compatible; Google Desktop)
   3183 HTTP_USER_AGENT
   3115 HTTP_USER_AGENT Mozilla/4.0
   2900 HTTP_USER_AGENT WordPress/2.7
   2096 HTTP_USER_AGENT Apple-PubSub/65.11
   1891 HTTP_USER_AGENT Zhuaxia.com 1 Subscribers
   1201 HTTP_USER_AGENT Apple-PubSub/65
   1154 HTTP_USER_AGENT Mozilla/5.0 (compatible;YoudaoFeedFetcher/1.0;http://www.youdao.com/help/reader/faq/topic006/;2 subscribers;)
   1059 HTTP_USER_AGENT FeedBurner/1.0 (http://www.FeedBurner.com)
      

從日志就可以直覺的看出主要是Google,baidu,微軟msn,網易有道和騰訊搜搜的爬蟲,以及每個爬蟲爬取的請求次數。通過這個簡單的辦法,你就可以有效的窺視每個爬蟲的動向,如果哪個爬蟲不老實,膽敢瘋狂爬取的話,你就可以一眼把它挑出來。

要根據User-Agent資訊來封殺爬蟲是件很容易的事情,主流的Web Server都支援針對User-Agent資訊的設定,JavaEye使用的是lighttpd,是以用以下的lighttpd配置來封殺爬蟲:

C代碼

如何對付網絡爬蟲 - JavaEye和網絡爬蟲鬥争之路
  1. $HTTP["useragent"] =~ "qihoobot|^Java|Commons-HttpClient|Wget|^PHP|Ruby|Python" {   
  2.   url.rewrite = ( "^/(.*)" => "/crawler.html" )   
  3. }  
$HTTP["useragent"] =~ "qihoobot|^Java|Commons-HttpClient|Wget|^PHP|Ruby|Python" {
  url.rewrite = ( "^/(.*)" => "/crawler.html" )
}
      

使用這種方式來封殺爬蟲簡單而有效,JavaEye已經根據User-Agent資訊封殺了70多種網絡爬蟲。而且這種方式可以有效的擋住那些程式員菜鳥編寫的垃圾爬蟲,因為他們一般情況下并不知道聲明User-Agent資訊,是以爬蟲會直接把程式設計語言的名稱或者庫的名稱作為User-Agent發送過來,我們隻要封殺常用程式設計語言和網絡庫的名稱就OK了。

通過以上的兩種方式已經可以基本解決網絡爬蟲造成的困擾,特别是可以解決掉絕大部分并不專門針對你的網站進行爬取的網絡爬蟲。但是如果一個爬蟲有針對性的非要爬取你的網站不可,它也可以通過修改User-Agent資訊的方式僞裝自己,進而避開你的封殺。為了盡最大可能性不暴露自己,它甚至會尋找幾十上百個代理伺服器采取分布式爬取的政策,在這種情況下,我們上面的封殺政策就失效了,必須采取新的手段。

三、善于僞裝的爬蟲

在上面提到,如果爬蟲僞裝自己的User-Agent資訊,就必須尋找新的辦法來封殺爬蟲了。事實上對網站來說,最大的挑戰就是如何準确的甄别一個IP發起的請求,究竟是真實使用者通路還是爬蟲通路呢?

先說點題外話,在很多年以前(2000年),我就做過網站流量統計系統。主流的網站流量統計系統不外乎兩種政策:一種政策是在網頁裡面嵌入一段js,這段js會向特定的統計伺服器發送請求的方式記錄通路量;另一種政策是直接分析伺服器日志,來統計網站通路量。

在理想的情況下,嵌入js的方式統計的網站流量應該高于分析伺服器日志,這是因為使用者浏覽器會有緩存,不一定每次真實使用者通路都會觸發伺服器的處理。但實際情況是,分析伺服器日志得到的網站通路量遠遠高于嵌入js方式,極端情況下,甚至要高出10倍以上。

現在很多網站喜歡采用awstats來分析伺服器日志,來計算網站的通路量,但是當他們一旦采用Google Analytics來統計網站流量的時候,卻發現GA統計的流量遠遠低于awstats,是以開始懷疑GA的準确性。其實GA的統計确實會略低于真實的使用者通路量,但資料的真實性比較靠譜,不會偏差特别大。之是以略低是因為GA的伺服器有時候使用者通路不到,還有一種情況是通路JavaEye的使用者所在公司使用了白名單,他能通路JavaEye卻無法通路GA伺服器,此外也有可能使用者還沒有等到GA加載就跳轉到下一頁了,是以統計量沒有被GA計算。

那麼為什麼GA和awstats統計會有這麼大差異呢? 罪魁禍首就是把自己僞裝成浏覽器的網絡爬蟲。一些網絡爬蟲為了避免被網站以識别User-Agent的方式封殺,就修改了自己的User-Agent資訊,通常僞裝成WindowsXP上的IE6浏覽器,也有僞裝成Firefox浏覽器的。這種情況下awstats無法有效的識别了,是以awstats的統計資料會虛高。不過說句公道話,這也怪不了awstats,隻怪爬蟲太狡猾,不但awstats無法有效識别,就算我們肉眼去檢視日志,也往往無法有效識别。

是以作為一個網站來說,如果希望了解自己的網站真實通路量,希望精确了解網站每個頻道的通路量和通路使用者,開發自己的網站流量統計系統就顯得非常有必要性。JavaEye網站就開發了自己的網站流量統計系統,采用在頁面裡面嵌入js的方式來實作網站流量統計。是以我們可以精确的掌握登入使用者和非登入使用者的比例,不同的通路偏好,JavaEye每個頻道精确的流量和比例,真實的使用者數量和分布等GA無法提供的有價值的資訊。

JavaEye自己的流量統計系統盡管并不是為了甄别爬蟲而編寫的,但是他可以幫助甄别網絡爬蟲。我們知道隻有使用者使用浏覽器通路頁面的時候才會執行js,而爬蟲并不會執行頁面裡面的js,是以rails的production.log裡面出現的IP位址,卻并沒有相應的流量統計系統記錄這個IP位址,我們可以99%的斷定這個IP是個爬蟲。如果爬蟲編寫者專門僞裝真實IP向流量統計伺服器發起請求的話,流量統計系統也有自己的防範作弊的機制,以及資料分析機制來甄别異常的通路請求,這點就不展開讨論了。

總之有了JavaEye流量統計系統提供的真實IP作為參考标準,我們就可以拿日志裡面出現的IP位址進行比較,如果日志裡面某個IP發起了大量的請求,在流量統計系統裡面卻根本找不到,或者即使找得到,可通路量卻隻有寥寥幾個,那麼這無疑就是一個網絡爬蟲,我們可以直接用iptables封殺該C段位址了。

根據這種政策,我們可以重新調整封殺方案。首先統計production.log,統計通路最多的200個C段位址,這僅僅需要一條shell指令:

C代碼

如何對付網絡爬蟲 - JavaEye和網絡爬蟲鬥争之路
  1. 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   
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段位址就是我們需要重點考察的對象,網絡爬蟲就混迹在這200個C段位址之内。它的格式大緻如下,顯示通路請求最多的C段IP位址和請求次數:

C代碼

如何對付網絡爬蟲 - JavaEye和網絡爬蟲鬥争之路
  1. 99650 203.208.60.0   
  2. 55813 123.125.66.0   
  3. 21131 221.235.58.0   
  4. 18360 72.14.199.0   
  5. 14632 121.0.29.0   
  6. 11789 202.165.185.0   
  7. 10539 61.135.216.0   
  8. 10153 65.55.106.0   
  9.  7001 65.55.211.0   
  10.  4240 65.55.207.0   
  11.  3789 219.133.0.0   
  12.  3721 194.8.74.0  
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
      

然後我們還需要流量統計系統提供的真實IP位址的C段位址作為參考,這已經由流量統計系統提供給我們了。

接着我們還需要準備一個白名單清單,比方說Google和百度的爬蟲IP位址段,對于這些爬蟲,我們給予放行,究竟放行哪些爬蟲,就需要完全根據自己網站的情況而定了。例如JavaEye現在的白名單(還在不斷添加中):

C代碼

如何對付網絡爬蟲 - JavaEye和網絡爬蟲鬥争之路
  1. 60.28.204.0     抓蝦   
  2. 61.135.163.0    百度   
  3. 61.135.216.0    有道   
  4. 65.55.106.0     微軟   
  5. 65.55.207.0     微軟   
  6. 65.55.211.0     微軟   
  7. 66.249.66.0     Google   
  8. 72.14.199.0     Google   
  9. 121.0.29.0      阿裡巴巴   
  10. 123.125.66.0    百度   
  11. 124.115.10.0    騰訊搜搜   
  12. 124.115.11.0    騰訊搜搜   
  13. 124.115.12.0    騰訊搜搜   
  14. 203.208.60.0    Google   
  15. 209.85.238.0    Google   
  16. 219.239.34.0    鮮果   
  17. 220.181.50.0    百度   
  18. 220.181.61.0    搜狗  
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    搜狗
      

最後我們還需要準備一個IP位址庫,對于那些被我們揪出來的爬蟲,我們還需要甄别一下他的身份,它究竟是一個惡意的爬蟲,還是一個未被我們放入白名單的合法爬蟲呢?IP位址庫很容易從網際網路下載下傳一份,是以也不展開讨論了。總之有了這些素材,我們要甄别網絡爬蟲就十分簡單了,僅僅十幾行ruby代碼就搞定了:

Ruby代碼

如何對付網絡爬蟲 - JavaEye和網絡爬蟲鬥争之路
  1. whitelist = []   
  2. IO.foreach("#{RAILS_ROOT}/lib/whitelist.txt") { |line| whitelist << line.split[0].strip if line }   
  3. realiplist = []   
  4. IO.foreach("#{RAILS_ROOT}/log/visit_ip.log") { |line|  realiplist << line.strip if line }   
  5. iplist = []   
  6. IO.foreach("#{RAILS_ROOT}/log/stat_ip.log") do |line|   
  7.   ip = line.split[1].strip   
  8.   iplist << ip if line.split[0].to_i > 3000 && !whitelist.include?(ip) && !realiplist.include?(ip)   
  9. end    
  10. Report.deliver_crawler(iplist)  
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)
           

代碼的實作很簡單,就是讀入通路請求次數超過3000次的C段位址,根據經驗來說,超過3000次的通路請求已經非常可疑了。然後去掉白名單裡面的C段位址,再去掉出現在真實通路清單中的IP位址段,最後剩下來的就是高度可疑的C段位址了。對于這些位址查詢IP位址資料庫資訊,再格式化成報告自動給我發送電子郵件。

最後需要人肉的簡單識别,比方說某位址的來源資訊顯示為“Google公司總部”,那麼我就知道這個位址需要添加到白名單裡面。除去這些可以肉眼識别的位址,剩下來的就可以統統幹掉了。

另外,對于這個簡單的程式還需要進一步完善,比方說不是簡單的根據realiplist進行比對和排除,而是給realiplist也建立一個ip段的統計資訊,即使該段位址有真實通路量,仍然需要進一步甄别,用該位址的請求數量除以realiplist裡面的通路數量,如果倍數大于一個閥值比方說1000,就可以斷定仍然是網絡爬蟲。

四、使用浏覽器核心驅動的網絡爬蟲

有人在文章後面的評論裡面提到一種新的爬蟲的爬取方式,就是不用程式去爬取,而是程式設計控制一個真正的浏覽器核心去爬取網站,由于浏覽器核心可以真正執行js,是以會被識别為真實使用者通路,進而避開網站的檢查機制。這種爬蟲是最難以甄别的爬蟲,如果精心編寫,甚至可以欺騙Google的伺服器。由于Safari的webkit浏覽器核心和Firefox的Gecko浏覽器核心都是開源的,是以一個水準比較高的程式員自己動手編寫程式驅動一個真實的浏覽器核心作為爬蟲并不是非常困難的事情。

實際上這種爬蟲我們也遇到過幾次,但也并不難以甄别,隻是需要一定的手工甄别機制,難以用程式全部自動化甄别。我們知道一個網站的真實使用者通路量如果沒有短期的市場推廣活動,那麼會保持一個比較穩定的水準,如果網站的通路量出現一個比較大的跳躍,或者網站頻道之間的通路比例出現突變,就可以99%斷定有此類爬蟲出現了。

那麼要甄别它也很簡單,對真實通路IP進行統計和排序,挑選出來前200名C段IP位址中每天通路量超過3000次的IP段位址,然後去除白名單,最後再用IP位址資料庫去比對。根據經驗來說,一個C段位址每天超過3000次通路已經肯定是一個大公司在通路JavaEye了,可如果該來源C段并非出自像阿裡巴巴,IBM中國公司,搜狐,騰訊這樣的公司位址,就可以99%斷定是網絡爬蟲,直接用iptables幹掉該C段位址。

總之,通過這種方式目前已經可以有效甄别僞裝的網絡爬蟲,以及通過n多國外代理伺服器的分布式網絡爬蟲,不過網站和爬蟲之間的戰争永遠不會結束,我們可以通過每天的日志報告來檢測網站的運作狀況,一旦發現資料報告異常,就知道有新的爬蟲出現,那麼就可以通過日志分析尋找封殺它的新辦法 

繼續閱讀