论坛首页 入门技术论坛

(轉)关于网络爬虫的

浏览 9860 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-07-22   最后修改:2010-07-22
由于搜索引擎的泛滥,网络爬虫如今已经成为全球互联网的一大公害。除了专门做搜索的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网段地址,例如:

iptables -A INPUT -i eth0 -j DROP -p tcp --dport 80 -s 84.80.46.0/24



除此之外还可以采取一些辅助的解决办法,比方说在web server上面限制每IP并发连接数量,如果超过一定的并发连接数量,就直接返回拒绝请求的页面。例如lighttpd可以这样配置:

$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信息:

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:

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的记录到日志文件里面去。或者你也可以直接把输出内容发送到你的邮箱里面去。

最终的爬虫统计结果类似下面这样:

  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配置来封杀爬虫:

$HTTP["useragent"] =~ "qihoobot|^Java|Commons-HttpClient|Wget|^PHP|Ruby|Python" {
  url.rewrite = ( "^/(.*)" => "/crawler.html" )
   发表时间:2010-10-02  
IR导论里介绍关于网络爬虫,礼貌性是很重要的一点,不过很多国内小作坊做的爬虫都无视这个。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics