- 浏览: 15960 次
最新评论
转载文章
http://robbin.iteye.com/blog/451014
因为搜索引擎的流行,网络爬虫已经成了很普及网络技术,除了专门做搜索的Google,Yahoo,微软,百度以外,几乎每个大型门户网站都有自己的搜索
引擎,大大小小叫得出来名字得就几十种,还有各种不知名的几千几万种,对于一个内容型驱动的网站来说,受到网络爬虫的光顾是不可避免的。
一些智能的搜索引擎爬虫的爬取频率比较合理,对网站资源消耗比较少,但是很多糟糕的网络爬虫,对网页爬取能力很差,经常并发几十上百个请求循环重复抓取,这种爬虫对中小型网站往往是毁灭性打击,特别是一些缺乏爬虫编写经验的程序员写出来的爬虫破坏力极强。曾经有一次我在JavaEye 的 日志里面发现一个User-Agent是Java的爬虫一天之内爬取了将近100万次动态请求。这是一个用JDK标准类库编写的简单爬取网页程序,由于 JavaEye网站内部链接构成了回环导致程序陷入了死循环。对于JavaEye这种百万PV级别的网站来说,这种爬虫造成的访问压力会非常大,会导致网 站访问速度缓慢,甚至无法访问。
此外,相当数量的的网页爬虫目的是盗取目标网站的内容。比方说JavaEye网站就曾经被两个竞争对手网站爬取论坛帖子,然后在自己的论坛里面用机器人发帖,因此这种爬虫不仅仅影响网站访问速度,而且侵犯了网站的版权。
对于一个原创内容丰富,URL结构合理易于爬取的网站来说,简直就是各种爬虫的盘中大餐,很多网站的访问流量构成当中,爬虫带来的流量要远远超过 真实用户访问流量,甚至爬虫流量要高出真实流量一个数量级。像JavaEye网站虽然设置了相当严格的反爬虫策略,但是网站处理的动态请求数量仍然是真实 用户访问流量的2倍。可以肯定的说,当今互联网的网络流量至少有2/3的流量爬虫带来的。因此反爬虫是一个值得网站长期探索和解决的问题。
一、手工识别和拒绝爬虫的访问
有相当多的爬虫对网站会造成非常高的负载,因此识别爬虫的来源IP是很容易的事情。最简单的办法就是用netstat检查80端口的连接:
这行shell可以按照80端口连接数量对来源IP进行排序,这样可以直观的判断出来网页爬虫。一般来说爬虫的并发连接非常高。
如果使用lighttpd做Web Server,那么就更简单了。lighttpd的mod_status提供了非常直观的并发连接的信息,包括每个连接的来源IP,访问的URL,连接状 态和连接时间等信息,只要检查那些处于handle-request状态的高并发IP就可以很快确定爬虫的来源IP了。
拒绝爬虫请求既可以通过内核防火墙来拒绝,也可以在web server拒绝,比方说用iptables拒绝:
直接封锁爬虫所在的C网段地址。这是因为一般爬虫都是运行在托管机房里面,可能在一个C段里面的多台服务器上面都有爬虫,而这个C段不可能是用户宽带上网,封锁C段可以很大程度上解决问题。
有些人提出一种脑残的观点,说我要惩罚这些爬虫。我专门在网页里面设计动态循环链接页面,让爬虫掉进陷阱,死循环爬不出来,其实根本用不着设置陷 阱,弱智爬虫对正常网页自己就爬不出来,这样做多此一举不说,而且会让真正的搜索引擎降低你的网页排名。而且运行一个爬虫根本不消耗什么机器资源,相反, 真正宝贵的是你的服务器CPU资源和服务器带宽,简单的拒绝掉爬虫的请求是反爬虫最有效的策略。
二、通过识别爬虫的User-Agent信息来拒绝爬虫
有很多爬虫并不会以很高的并发连接爬取,一般不容易暴露自己;有些爬虫的来源IP分布很广,很难简单的通过封锁IP段地址来解决问题;另外还有很 多各种各样的小爬虫,它们在尝试Google以外创新的搜索方式,每个爬虫每天爬取几万的网页,几十个爬虫加起来每天就能消耗掉上百万动态请求的资源,由 于每个小爬虫单独的爬取量都很低,所以你很难把它从每天海量的访问IP地址当中把它准确的挖出来。
这种情况下我们可以通过爬虫的User-Agent信息来识别。每个爬虫在爬取网页的时候,会声明自己的User-Agent信息,因此我们就可 以通过记录和分析User-Agent信息来挖掘和封锁爬虫。我们需要记录每个请求的User-Agent信息,对于Rails来说我们可以简单的在 app/controllers/application.rb里面添加一个全局的before_filter,来记录每个请求的User-Agent信 息:
然后统计每天的production.log,抽取User-Agent信息,找出访问量最大的那些User-Agent。要注意的是我们只关注 那些爬虫的User-Agent信息,而不是真正浏览器User-Agent,所以还要排除掉浏览器User-Agent,要做到这一点仅仅需要一行 shell:
统计结果类似这样:
从日志就可以直观的看出每个爬虫的请求次数。要根据User-Agent信息来封锁爬虫是件很容易的事情,lighttpd配置如下:
使用这种方式来封锁爬虫虽然简单但是非常有效,除了封锁特定的爬虫,还可以封锁常用的编程语言和HTTP类库的User-Agent信息,这样就可以避免很多无谓的程序员用来练手的爬虫程序对网站的骚扰。
还有一种比较常见的情况,就是某个搜索引擎的爬虫对网站爬取频率过高,但是搜索引擎给网站带来了很多流量,我们并不希望简单的封锁爬虫,仅仅是希望降低爬虫的请求频率,减轻爬虫对网站造成的负载 ,那么我们可以这样做:
对百度的爬虫请求延迟10秒钟再进行处理,这样就可以有效降低爬虫对网站的负载了。
三、通过网站流量统计系统和日志分析来识别爬虫
有些爬虫喜欢修改User-Agent信息来伪装自己,把自己伪装成一个真实浏览器的User-Agent信息,让你无法有效的识别。这种情况下我们可以通过网站流量系统记录的真实用户访问IP来进行识别。
主流的网站流量统计系统不外乎两种实现策略:一种策略是在网页里面嵌入一段js,这段js会向特定的统计服务器发送请求的方式记录访问量;另一种 策略是直接分析服务器日志,来统计网站访问量。在理想的情况下,嵌入js的方式统计的网站流量应该高于分析服务器日志,这是因为用户浏览器会有缓存,不一 定每次真实用户访问都会触发服务器的处理。但实际情况是,分析服务器日志得到的网站访问量远远高于嵌入js方式,极端情况下,甚至要高出10倍以上。
现在很多网站喜欢采用awstats来分析服务器日志,来计算网站的访问量,但是当他们一旦采用Google Analytics来统计网站流量的时候,却发现GA统计的流量远远低于awstats,为什么GA和awstats统计会有这么大差异呢?罪魁祸首就是 把自己伪装成浏览器的网络爬虫。这种情况下awstats无法有效的识别了,所以awstats的统计数据会虚高。
其实作为一个网站来说,如果希望了解自己的网站真实访问量,希望精确了解网站每个频道的访问量和访问用户,应该用页面里面嵌入js的方式来开发自 己的网站流量统计系统。自己做一个网站流量统计系统是件很简单的事情,写段服务器程序响应客户段js的请求,分析和识别请求然后写日志的同时做后台的异步 统计就搞定了。
通过流量统计系统得到的用户IP基本是真实的用户访问,因为一般情况下爬虫是无法执行网页里面的js代码片段的。所以我们可以拿流量统计系统记录 的IP和服务器程序日志记录的IP地址进行比较,如果服务器日志里面某个IP发起了大量的请求,在流量统计系统里面却根本找不到,或者即使找得到,可访问 量却只有寥寥几个,那么无疑就是一个网络爬虫。
分析服务器日志统计访问最多的IP地址段一行shell就可以了:
然后把统计结果和流量统计系统记录的IP地址进行对比,排除真实用户访问IP,再排除我们希望放行的网页爬虫,比方Google,百度,微软msn爬虫等等。最后的分析结果就就得到了爬虫的IP地址了。以下代码段是个简单的实现示意:
分析服务器日志里面请求次数超过3000次的IP地址段,排除白名单地址和真实访问IP地址,最后得到的就是爬虫IP了,然后可以发送邮件通知管理员进行相应的处理。
四、网站的实时反爬虫防火墙实现策略
通过分析日志的方式来识别网页爬虫不是一个实时的反爬虫策略。如果一个爬虫非要针对你的网站进行处心积虑的爬取,那么他可能会采用分布式爬取策 略,比方说寻找几百上千个国外的代理服务器疯狂的爬取你的网站,从而导致网站无法访问,那么你再分析日志是不可能及时解决问题的。所以必须采取实时反爬虫 策略,要能够动态的实时识别和封锁爬虫的访问。
要自己编写一个这样的实时反爬虫系统其实也很简单。比方说我们可以用memcached来做访问计数器,记录每个IP的访问频度,在单位时间之 内,如果访问频率超过一个阀值,我们就认为这个IP很可能有问题,那么我们就可以返回一个验证码页面,要求用户填写验证码。如果是爬虫的话,当然不可能填 写验证码,所以就被拒掉了,这样很简单就解决了爬虫问题。
用memcache记录每个IP访问计数,单位时间内超过阀值就让用户填写验证码,用Rails编写的示例代码如下:
这段程序只是最简单的示例,实际的代码实现我们还会添加很多判断,比方说我们可能要排除白名单IP地址段,要允许特定的User-Agent通过,要针对登录用户和非登录用户,针对有无referer地址采取不同的阀值和计数加速器等等。
此外如果分布式爬虫爬取频率过高的话,过期就允许爬虫再次访问还是会对服务器造成很大的压力,因此我们可以添加一条策略:针对要求用户填写验证码 的IP地址,如果该IP地址短时间内继续不停的请求,则判断为爬虫,加入黑名单,后续请求全部拒绝掉。为此,示例代码可以改进一下:
我们可以定义一个全局的过滤器,对所有请求进行过滤,出现在黑名单的IP地址一律拒绝。对非黑名单的IP地址再进行计数和统计:
如果某个IP地址单位时间内访问频率超过阀值,再增加一个计数器,跟踪他会不会立刻填写验证码,如果他不填写验证码,在短时间内还是高频率访问, 就把这个IP地址段加入黑名单,除非用户填写验证码激活,否则所有请求全部拒绝。这样我们就可以通过在程序里面维护黑名单的方式来动态的跟踪爬虫的情况, 甚至我们可以自己写个后台来手工管理黑名单列表,了解网站爬虫的情况。
这个策略已经比较智能了,但是还不够好!我们还可以继续改进:
1、用网站流量统计系统来改进实时反爬虫系统
还记得吗?网站流量统计系统记录的IP地址是真实用户访问IP,所以我们在网站流量统计系统里面也去操作memcached,但是这次不是增加计 数值,而是减少计数值。在网站流量统计系统里面每接收到一个IP请求,就相应的cache.decrement(key)。所以对于真实用户的IP来说, 它的计数值总是加1然后就减1,不可能很高。这样我们就可以大大降低判断爬虫的阀值,可以更加快速准确的识别和拒绝掉爬虫。
2、用时间窗口来改进实时反爬虫系统
爬虫爬取网页的频率都是比较固定的,不像人去访问网页,中间的间隔时间比较无规则,所以我们可以给每个IP地址建立一个时间窗口,记录IP地址最 近12次访问时间,每记录一次就滑动一次窗口,比较最近访问时间和当前时间,如果间隔时间很长判断不是爬虫,清除时间窗口,如果间隔不长,就回溯计算指定 时间段的访问频率,如果访问频率超过阀值,就转向验证码页面让用户填写验证码。
最终这个实时反爬虫系统就相当完善了,它可以很快的识别并且自动封锁爬虫的访问,保护网站的正常访问。不过有些爬虫可能相当狡猾,它也许会通过大 量的爬虫测试来试探出来你的访问阀值,以低于阀值的爬取速度抓取你的网页,因此我们还需要辅助第3种办法,用日志来做后期的分析和识别,就算爬虫爬的再 慢,它累计一天的爬取量也会超过你的阀值被你日志分析程序识别出来。
总之我们综合运用上面的四种反爬虫策略,可以很大程度上缓解爬虫对网站造成的负面影响,保证网站的正常访问。
一些智能的搜索引擎爬虫的爬取频率比较合理,对网站资源消耗比较少,但是很多糟糕的网络爬虫,对网页爬取能力很差,经常并发几十上百个请求循环重复抓取,这种爬虫对中小型网站往往是毁灭性打击,特别是一些缺乏爬虫编写经验的程序员写出来的爬虫破坏力极强。曾经有一次我在JavaEye 的 日志里面发现一个User-Agent是Java的爬虫一天之内爬取了将近100万次动态请求。这是一个用JDK标准类库编写的简单爬取网页程序,由于 JavaEye网站内部链接构成了回环导致程序陷入了死循环。对于JavaEye这种百万PV级别的网站来说,这种爬虫造成的访问压力会非常大,会导致网 站访问速度缓慢,甚至无法访问。
此外,相当数量的的网页爬虫目的是盗取目标网站的内容。比方说JavaEye网站就曾经被两个竞争对手网站爬取论坛帖子,然后在自己的论坛里面用机器人发帖,因此这种爬虫不仅仅影响网站访问速度,而且侵犯了网站的版权。
对于一个原创内容丰富,URL结构合理易于爬取的网站来说,简直就是各种爬虫的盘中大餐,很多网站的访问流量构成当中,爬虫带来的流量要远远超过 真实用户访问流量,甚至爬虫流量要高出真实流量一个数量级。像JavaEye网站虽然设置了相当严格的反爬虫策略,但是网站处理的动态请求数量仍然是真实 用户访问流量的2倍。可以肯定的说,当今互联网的网络流量至少有2/3的流量爬虫带来的。因此反爬虫是一个值得网站长期探索和解决的问题。
一、手工识别和拒绝爬虫的访问
有相当多的爬虫对网站会造成非常高的负载,因此识别爬虫的来源IP是很容易的事情。最简单的办法就是用netstat检查80端口的连接:
- netstat -nt | grep youhostip:80 | awk '{print $5}' | awk -F ":" '{print $1}' | sort | uniq -c | sort -r -n
这行shell可以按照80端口连接数量对来源IP进行排序,这样可以直观的判断出来网页爬虫。一般来说爬虫的并发连接非常高。
如果使用lighttpd做Web Server,那么就更简单了。lighttpd的mod_status提供了非常直观的并发连接的信息,包括每个连接的来源IP,访问的URL,连接状 态和连接时间等信息,只要检查那些处于handle-request状态的高并发IP就可以很快确定爬虫的来源IP了。
拒绝爬虫请求既可以通过内核防火墙来拒绝,也可以在web server拒绝,比方说用iptables拒绝:
直接封锁爬虫所在的C网段地址。这是因为一般爬虫都是运行在托管机房里面,可能在一个C段里面的多台服务器上面都有爬虫,而这个C段不可能是用户宽带上网,封锁C段可以很大程度上解决问题。
有些人提出一种脑残的观点,说我要惩罚这些爬虫。我专门在网页里面设计动态循环链接页面,让爬虫掉进陷阱,死循环爬不出来,其实根本用不着设置陷 阱,弱智爬虫对正常网页自己就爬不出来,这样做多此一举不说,而且会让真正的搜索引擎降低你的网页排名。而且运行一个爬虫根本不消耗什么机器资源,相反, 真正宝贵的是你的服务器CPU资源和服务器带宽,简单的拒绝掉爬虫的请求是反爬虫最有效的策略。
二、通过识别爬虫的User-Agent信息来拒绝爬虫
有很多爬虫并不会以很高的并发连接爬取,一般不容易暴露自己;有些爬虫的来源IP分布很广,很难简单的通过封锁IP段地址来解决问题;另外还有很 多各种各样的小爬虫,它们在尝试Google以外创新的搜索方式,每个爬虫每天爬取几万的网页,几十个爬虫加起来每天就能消耗掉上百万动态请求的资源,由 于每个小爬虫单独的爬取量都很低,所以你很难把它从每天海量的访问IP地址当中把它准确的挖出来。
这种情况下我们可以通过爬虫的User-Agent信息来识别。每个爬虫在爬取网页的时候,会声明自己的User-Agent信息,因此我们就可 以通过记录和分析User-Agent信息来挖掘和封锁爬虫。我们需要记录每个请求的User-Agent信息,对于Rails来说我们可以简单的在 app/controllers/application.rb里面添加一个全局的before_filter,来记录每个请求的User-Agent信 息:
然后统计每天的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
统计结果类似这样:
- 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)
从日志就可以直观的看出每个爬虫的请求次数。要根据User-Agent信息来封锁爬虫是件很容易的事情,lighttpd配置如下:
- $HTTP[ "useragent" ] =~ "qihoobot|^Java|Commons-HttpClient|Wget|^PHP|Ruby|Python" {
- url.rewrite = ( "^/(.*)" => "/crawler.html" )
- }
使用这种方式来封锁爬虫虽然简单但是非常有效,除了封锁特定的爬虫,还可以封锁常用的编程语言和HTTP类库的User-Agent信息,这样就可以避免很多无谓的程序员用来练手的爬虫程序对网站的骚扰。
还有一种比较常见的情况,就是某个搜索引擎的爬虫对网站爬取频率过高,但是搜索引擎给网站带来了很多流量,我们并不希望简单的封锁爬虫,仅仅是希望降低爬虫的请求频率,减轻爬虫对网站造成的负载 ,那么我们可以这样做:
对百度的爬虫请求延迟10秒钟再进行处理,这样就可以有效降低爬虫对网站的负载了。
三、通过网站流量统计系统和日志分析来识别爬虫
有些爬虫喜欢修改User-Agent信息来伪装自己,把自己伪装成一个真实浏览器的User-Agent信息,让你无法有效的识别。这种情况下我们可以通过网站流量系统记录的真实用户访问IP来进行识别。
主流的网站流量统计系统不外乎两种实现策略:一种策略是在网页里面嵌入一段js,这段js会向特定的统计服务器发送请求的方式记录访问量;另一种 策略是直接分析服务器日志,来统计网站访问量。在理想的情况下,嵌入js的方式统计的网站流量应该高于分析服务器日志,这是因为用户浏览器会有缓存,不一 定每次真实用户访问都会触发服务器的处理。但实际情况是,分析服务器日志得到的网站访问量远远高于嵌入js方式,极端情况下,甚至要高出10倍以上。
现在很多网站喜欢采用awstats来分析服务器日志,来计算网站的访问量,但是当他们一旦采用Google Analytics来统计网站流量的时候,却发现GA统计的流量远远低于awstats,为什么GA和awstats统计会有这么大差异呢?罪魁祸首就是 把自己伪装成浏览器的网络爬虫。这种情况下awstats无法有效的识别了,所以awstats的统计数据会虚高。
其实作为一个网站来说,如果希望了解自己的网站真实访问量,希望精确了解网站每个频道的访问量和访问用户,应该用页面里面嵌入js的方式来开发自 己的网站流量统计系统。自己做一个网站流量统计系统是件很简单的事情,写段服务器程序响应客户段js的请求,分析和识别请求然后写日志的同时做后台的异步 统计就搞定了。
通过流量统计系统得到的用户IP基本是真实的用户访问,因为一般情况下爬虫是无法执行网页里面的js代码片段的。所以我们可以拿流量统计系统记录 的IP和服务器程序日志记录的IP地址进行比较,如果服务器日志里面某个IP发起了大量的请求,在流量统计系统里面却根本找不到,或者即使找得到,可访问 量却只有寥寥几个,那么无疑就是一个网络爬虫。
分析服务器日志统计访问最多的IP地址段一行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
然后把统计结果和流量统计系统记录的IP地址进行对比,排除真实用户访问IP,再排除我们希望放行的网页爬虫,比方Google,百度,微软msn爬虫等等。最后的分析结果就就得到了爬虫的IP地址了。以下代码段是个简单的实现示意:
- 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次的IP地址段,排除白名单地址和真实访问IP地址,最后得到的就是爬虫IP了,然后可以发送邮件通知管理员进行相应的处理。
四、网站的实时反爬虫防火墙实现策略
通过分析日志的方式来识别网页爬虫不是一个实时的反爬虫策略。如果一个爬虫非要针对你的网站进行处心积虑的爬取,那么他可能会采用分布式爬取策 略,比方说寻找几百上千个国外的代理服务器疯狂的爬取你的网站,从而导致网站无法访问,那么你再分析日志是不可能及时解决问题的。所以必须采取实时反爬虫 策略,要能够动态的实时识别和封锁爬虫的访问。
要自己编写一个这样的实时反爬虫系统其实也很简单。比方说我们可以用memcached来做访问计数器,记录每个IP的访问频度,在单位时间之 内,如果访问频率超过一个阀值,我们就认为这个IP很可能有问题,那么我们就可以返回一个验证码页面,要求用户填写验证码。如果是爬虫的话,当然不可能填 写验证码,所以就被拒掉了,这样很简单就解决了爬虫问题。
用memcache记录每个IP访问计数,单位时间内超过阀值就让用户填写验证码,用Rails编写的示例代码如下:
- ip_counter = Rails.cache.increment(request.remote_ip)
- if !ip_counter
- Rails.cache.write(request.remote_ip, 1, :expires_in => 30.minutes)
- elsif ip_counter > 2000
- render :template => 'test' , :status => 401 and return false
- end
这段程序只是最简单的示例,实际的代码实现我们还会添加很多判断,比方说我们可能要排除白名单IP地址段,要允许特定的User-Agent通过,要针对登录用户和非登录用户,针对有无referer地址采取不同的阀值和计数加速器等等。
此外如果分布式爬虫爬取频率过高的话,过期就允许爬虫再次访问还是会对服务器造成很大的压力,因此我们可以添加一条策略:针对要求用户填写验证码 的IP地址,如果该IP地址短时间内继续不停的请求,则判断为爬虫,加入黑名单,后续请求全部拒绝掉。为此,示例代码可以改进一下:
- before_filter :ip_firewall , :except => :test
- def ip_firewall
- render :file => "#{RAILS_ROOT}/public/403.html" , :status => 403 if BlackList.include?(ip_sec)
- end
我们可以定义一个全局的过滤器,对所有请求进行过滤,出现在黑名单的IP地址一律拒绝。对非黑名单的IP地址再进行计数和统计:
- ip_counter = Rails.cache.increment(request.remote_ip)
- if !ip_counter
- Rails.cache.write(request.remote_ip, 1, :expires_in => 30.minutes)
- elsif ip_counter > 2000
- crawler_counter = Rails.cache.increment("crawler/#{request.remote_ip}" )
- if !crawler_counter
- Rails.cache.write("crawler/#{request.remote_ip}" , 1, :expires_in => 10.minutes)
- elsif crawler_counter > 50
- BlackList.add(ip_sec)
- render :file => "#{RAILS_ROOT}/public/403.html" , :status => 403 and return false
- end
- render :template => 'test' , :status => 401 and return false
- end
如果某个IP地址单位时间内访问频率超过阀值,再增加一个计数器,跟踪他会不会立刻填写验证码,如果他不填写验证码,在短时间内还是高频率访问, 就把这个IP地址段加入黑名单,除非用户填写验证码激活,否则所有请求全部拒绝。这样我们就可以通过在程序里面维护黑名单的方式来动态的跟踪爬虫的情况, 甚至我们可以自己写个后台来手工管理黑名单列表,了解网站爬虫的情况。
这个策略已经比较智能了,但是还不够好!我们还可以继续改进:
1、用网站流量统计系统来改进实时反爬虫系统
还记得吗?网站流量统计系统记录的IP地址是真实用户访问IP,所以我们在网站流量统计系统里面也去操作memcached,但是这次不是增加计 数值,而是减少计数值。在网站流量统计系统里面每接收到一个IP请求,就相应的cache.decrement(key)。所以对于真实用户的IP来说, 它的计数值总是加1然后就减1,不可能很高。这样我们就可以大大降低判断爬虫的阀值,可以更加快速准确的识别和拒绝掉爬虫。
2、用时间窗口来改进实时反爬虫系统
爬虫爬取网页的频率都是比较固定的,不像人去访问网页,中间的间隔时间比较无规则,所以我们可以给每个IP地址建立一个时间窗口,记录IP地址最 近12次访问时间,每记录一次就滑动一次窗口,比较最近访问时间和当前时间,如果间隔时间很长判断不是爬虫,清除时间窗口,如果间隔不长,就回溯计算指定 时间段的访问频率,如果访问频率超过阀值,就转向验证码页面让用户填写验证码。
最终这个实时反爬虫系统就相当完善了,它可以很快的识别并且自动封锁爬虫的访问,保护网站的正常访问。不过有些爬虫可能相当狡猾,它也许会通过大 量的爬虫测试来试探出来你的访问阀值,以低于阀值的爬取速度抓取你的网页,因此我们还需要辅助第3种办法,用日志来做后期的分析和识别,就算爬虫爬的再 慢,它累计一天的爬取量也会超过你的阀值被你日志分析程序识别出来。
总之我们综合运用上面的四种反爬虫策略,可以很大程度上缓解爬虫对网站造成的负面影响,保证网站的正常访问。
评论
21 楼
wankunde
2012-09-26
弱弱的求教一下,
代码,写成下面不是更简单吗啊?为什么要sort 两次呢???
- 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
代码,写成下面不是更简单吗啊?为什么要sort 两次呢???
- grep HTTP_USER_AGENT production.log | grep -v -E 'MSIE|Firefox|Chrome|Opera|Safari|Gecko'
- | sort -u -r -n | head -n 100 > bot.log
20 楼
wankunde
2012-09-26
弱弱的求教一下,
代码,写成下面不是更简单吗啊?为什么要sort 两次呢???
- 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
代码,写成下面不是更简单吗啊?为什么要sort 两次呢???
19 楼
liuwei_blog
2012-09-24
好,学习了
通过网站流量统计系统和日志分析来识别爬虫还有缺陷:
在爬之前,可以手工查出流量统计地址,在爬的时候,一边爬,一边向那个地址发送请求,不运行 js 就可以伪装成真流量。
我觉得验证码 + 黑名单方式是最有效的,结合白名单和延迟处理。
通过网站流量统计系统和日志分析来识别爬虫还有缺陷:
在爬之前,可以手工查出流量统计地址,在爬的时候,一边爬,一边向那个地址发送请求,不运行 js 就可以伪装成真流量。
我觉得验证码 + 黑名单方式是最有效的,结合白名单和延迟处理。
18 楼
elmar
2012-09-24
如果有人吧这个东西拿过去改改,发现爬虫就301到javaeye上,robin会不会疯掉啊?
17 楼
elmar
2012-09-24
用google appengine的fetchURL的虫子呢?
16 楼
Jacarri_Chan
2012-09-24
NB.. 膜拜.........
15 楼
greatwqs
2011-11-12
playfish 写道
呵呵,这篇文章真是给优化爬虫跟反反爬虫多给足了参考依据啊。。
不过有一点,robbin提到的用js的执行来判断是否是真实的用户在访问,这一点我觉得还是有缺陷的,比如说用rhino就能让java程序执 行JavaScript代码,更现实一点的,用htmlunit这个工具,它是一个用来测试html的单元测试工具,可以完全模拟浏览器的访问,简单封装 一下就能做成一个爬虫来用了,JavaScript代码都能执行,所以js的判断这块还得考虑。
道高一尺, 魔高一丈.
14 楼
asme2u
2010-10-12
好文!前段时间刚给公司开发过一个伪装User-Agent和伪造refer的爬虫-_-!,忏悔一下
13 楼
sdh5724
2010-08-09
哈, 说的很不错。 不过, 我们手段比你做的复杂多了。做的很辛苦。
12 楼
liuclean
2010-06-24
很受启发,受教了!
11 楼
jasongreen
2010-04-19
哎~~~,素质啊,爬虫不可怕,可怕的是爬完直接转载,而不是带来链接。
直接封C网网段的方法太狠了。
直接封C网网段的方法太狠了。
10 楼
jasongreen
2010-04-19
最近在研究crawler,打算试试拿javaeye试刀呢,结果没爬一会就401了。
<h3>
您所在的IP地址对JavaEye网站访问过于频繁,为了判断您的访问是真实用户,请您填写验证码,谢谢!
</h3>
看了下验证码,扭曲的很性感。很想知道验证码扭曲的算法。
之前爬了下博客园,发现居然 etag,last-modified,compress,一律没有实现。无语啊。爬他都觉得累。
<h3>
您所在的IP地址对JavaEye网站访问过于频繁,为了判断您的访问是真实用户,请您填写验证码,谢谢!
</h3>
看了下验证码,扭曲的很性感。很想知道验证码扭曲的算法。
之前爬了下博客园,发现居然 etag,last-modified,compress,一律没有实现。无语啊。爬他都觉得累。
9 楼
jasongreen
2010-04-19
robbin太牛叉了,能想到的你都想到了,想不到的你也想到了。
8 楼
tkivdrip
2009-10-21
还有很多东西需要积累····学习了
7 楼
oliver_peng
2009-09-10
可以设置iptable如果短时间创建连接的数目超过限制就拒绝TCP连接,虽然不能够实现很复杂的验证逻辑,但相对在Rail中处理开销要小很多。
6 楼
anky_end
2009-08-25
BarryWei 写道
呵 Robbin够牛的
但是我要感慨 为什么呢 文章发表于17号 在此之后不到24个小时 有至少上万的网站已经转载了这篇文章
这是好事 但还是要感慨 因为大部分的网站 没有标明来源……
我们的素质 也就如此
看来还有太多的事情等待着我们……
但是我要感慨 为什么呢 文章发表于17号 在此之后不到24个小时 有至少上万的网站已经转载了这篇文章
这是好事 但还是要感慨 因为大部分的网站 没有标明来源……
我们的素质 也就如此
看来还有太多的事情等待着我们……
爬的快嘛。。。
5 楼
playfish
2009-08-24
呵呵,这篇文章真是给优化爬虫跟反反爬虫多给足了参考依据啊。。
不 过有一点,robbin提到的用js的执行来判断是否是真实的用户在访问,这一点我觉得还是有缺陷的,比如说用rhino就能让java程序执行 JavaScript代码,更现实一点的,用htmlunit这个工具,它是一个用来测试html的单元测试工具,可以完全模拟浏览器的访问,简单封装一 下就能做成一个爬虫来用了,JavaScript代码都能执行,所以js的判断这块还得考虑。
4 楼
pangbuddy
2009-08-24
哈哈,优化Crawler有参考了
3 楼
hax
2009-08-24
这些策略也可以用来抵御外挂(比如开心网的停车和偷菜外挂),嘿嘿。
2 楼
forchenyun
2009-08-23
膜拜大牛啊
发表评论
- 浏览: 4054286 次
- 性别:
- 来自: 北京
文章分类
评论排行榜
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。若作者同意转载,必须以超链接形式标明文章原始出处和作者。
© 2003-2012 ITeye.com. All rights reserved. [ 京ICP证110151号 京公网安备110105010620 ]
相关推荐
博客链接指向的是一个ITeye上的博客文章,该文章可能详细介绍了这一实现过程,包括示例代码和实际应用。 【标签】:“源码”意味着我们将接触到具体的编程代码,这可能是解决这个问题的关键。而“工具”可能指的是...
2、每发布一篇转载文章:可获得2分; 3、博主的文章每被评论一次:可获得1分; 4、每发表一次评论:可获得1分(自己给自己评论、博主回复评论不获得积分); 5、博文阅读次数每超过100次:可获得1分,阅读...
2. 转载归属声明:规定转载文章时是否需要注明原作者的名称和作品的来源,这对保护原作者的著作权至关重要。 3. 使用性质的界定:明确转载是否为商业用途,如果转载方希望将作品用于商业目的,通常需要获得原作者...
优化原创、投稿、转载文章的申明。默认及原创文章显示作者侧栏小工具,原创文章在文章底部显示文章版权申明。投稿和转载,都不显示侧栏作者小工具、文章列表和文章标题下也不再示头像和作者名字,但在文章底部显示...
优化原创、投稿、转载文章的申明。默认及原创文章显示作者侧栏小工具,原创文章在文章底部显示文章版权申明。投和转载,都不显示侧栏作者小工具、文章列表和文章标题下也不再示头像和作者名字,但在文章底部显示文章...
PPP提供了一种在点对点的链路上封装多协议数据报(IP、IPX和AppleTalk)的标准方法。它不仅能支持IP地址的动态分配和管理;同步(面向位的同步数据块的传送)或异步(起始位+数据位+奇偶校验...转载文章供大家共同学习
1、随笔/文章 可创建多个分类,原创或转载文章,强大的富文本编辑器,丰富的表情图标,便捷的文件上传工具。 2、相册 可创建无限多个相册,可上传无限张图片。 3、音频 可创建多个分类,收藏自己喜欢的歌手和专辑。...
千帆采编软件是用来批量转载文章并能精编内容直接发布到网站的工具。默认支持主流文章发布系统,安装方便,配置简单,无需学习,一用就会。不用配置模板,符合编辑工作流程,可做伪创;能监控列表源,第一时间转载...
在IT行业中,网络内容的分享和传播是常见现象,但如何正确、完整地转载他人的文章,特别是技术类文章,避免格式混乱,是一项需要注意的技巧。这篇教程将带你了解如何在CSDN(China Software Developer Network)这个...
title~default-0-96019462-blog-125852782.pc_relevant_multi_platform_whitelistv1&spm=1001.2101.3001.4242.1&utm_relevant_index=3 的转载文章所提到的资源。即单层一维离散小波变换DWT的Mallat算法C++和MATLAB...
呵呵,这个主要是针对文章转载的,国内现在又很多不良站长,喜欢转载别人的文章,转载本事件好事,可是很多人文章是转载了,可是转载文章之后,很多人把文章出处、转载地址统统给抹杀掉了,非常的让人愤慨。...
千帆采编软件是用来批量转载文章并能精编内容直接发布到网站的工具。默认支持主流文章发布系统,安装方便,配置简单,无需学习,一用就会。不用配置模板,符合编辑工作流程,可做伪创;能监控列表源,第一时间转载...
例如,原创文章可能会比转载文章更受欢迎,特定领域的文章可能会吸引相关领域的用户。 文章还提到了分类变量,这通常是指在数据分析中不连续、有明确分类的变量,如性别、职业、教育水平等。在文章推荐系统中,分类...
"任阅" 网络小说阅读器,实现追书推荐收藏、书籍/标签检索、模拟翻书的翻页效果、缓存书籍、日夜间模式、书签、txt/pdf/epub书籍阅读、字体/主题/亮度设置、Wifi传书等功能~ ...注:本文为转载文章。
千帆采编软件是用来批量转载文章并能精编内容直接发布到网站的工具。默认支持主流文章发布系统,安装方便,配置简单,无需学习,一用就会。不用配置模板,符合编辑工作流程,可做伪创;能监控列表源,第一时间转载...
用于摘要汇总的深化模型>数据集:CNN_DailyMail1.1一般信息: 该数据集总共有近290条文章和126万个故事-问题对:90,000个CNN新闻和380,000个故事-问题对200,000个新故事和880,000个故事-问题对通常,新闻文章与几篇...
初期,有自动推送系统支持,但后来需要手动选择并转载文章,这对我的选材能力提出了挑战。我需要关注头条、二头条、各类要闻以及首页和侧边栏的推广位,确保内容的时效性和吸引力。通过CMS系统、海纳转载系统和后台...