互联网网站的反爬虫策略浅析

news/2024/5/20 15:47:56/文章来源:https://blog.csdn.net/chongshi3083/article/details/100805179

因为搜索引擎的流行,网络爬虫已经成了很普及网络技术,除了专门做搜索的Google,Yahoo,微软,百度以外,几乎每个大型门户网站都有自己的搜索引擎,大大小小叫得出来名字得就几十种,还有各种不知名的几千几万种,对于一个内容型驱动的网站来说,受到网络爬虫的光顾是不可避免的。

一些智能的搜索引擎爬虫的爬取频率比较合理,对网站资源消耗比较少,但是很多糟糕的网络爬虫,对网页爬取能力很差,经常并发几十上百个请求循环重复抓取,这种爬虫对中小型网站往往是毁灭性打击,特别是一些缺乏爬虫编写经验的程序员写出来的爬虫破坏力极强,造成的网站访问压力会非常大,会导致网站访问速度缓慢,甚至无法访问。

手工识别和拒绝爬虫的访问

相当多的爬虫对网站会造成非常高的负载,因此识别爬虫的来源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拒绝:

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

直接封锁爬虫所在的C网段地址。这是因为一般爬虫都是运行在托管机房里面,可能在一个C段里面的多台服务器上面都有爬虫,而这个C段不可能是用户宽带上网,封锁C段可以很大程度上解决问题。

通过识别爬虫的User-Agent信息来拒绝爬虫

有很多爬虫并不会以很高的并发连接爬取,一般不容易暴露自己;有些爬虫的来源IP分布很广,很难简单的通过封锁IP段地址来解决问题;另外还有很多各种各样的小爬虫,它们在尝试Google以外创新的搜索方式,每个爬虫每天爬取几万的网页,几十个爬虫加起来每天就能消耗掉上百万动态请求的资源,由于每个小爬虫单独的爬取量都很低,所以你很难把它从每天海量的访问IP地址当中把它准确的挖出来。

这种情况下我们可以通过爬虫的User-Agent信息来识别。每个爬虫在爬取网页的时候,会声明自己的User-Agent信息,因此我们就可以通过记录和分析User-Agent信息来挖掘和封锁爬虫。我们需要记录每个请求的User-Agent信息,对于Rails来说我们可以简单的在app/controllers/application.rb里面添加一个全局的before_filter,来记录每个请求的User-Agent信息:

logger.info "HTTP_USER_AGENT #{request.env["HTTP_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信息,这样就可以避免很多无谓的程序员用来练手的爬虫程序对网站的骚扰。

还有一种比较常见的情况,就是某个搜索引擎的爬虫对网站爬取频率过高,但是搜索引擎给网站带来了很多流量,我们并不希望简单的封锁爬虫,仅仅是希望降低爬虫的请求频率,减轻爬虫对网站造成的负载,那么我们可以这样做:

$HTTP["user-agent"] =~ "Baiduspider+" {connection.delay-seconds = 10 }

对百度的爬虫请求延迟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地址段加入黑名单,除非用户填写验证码激活,否则所有请求全部拒绝。这样我们就可以通过在程序里面维护黑名单的方式来动态的跟踪爬虫的情况,甚至我们可以自己写个后台来手工管理黑名单列表,了解网站爬虫的情况。

关于这个通用反爬虫的功能,我们开发一个开源的插件:https://github.com/csdn-dev/limiter

这个策略已经比较智能了,但是还不够好!我们还可以继续改进:

1、用网站流量统计系统来改进实时反爬虫系统

还记得吗?网站流量统计系统记录的IP地址是真实用户访问IP,所以我们在网站流量统计系统里面也去操作memcached,但是这次不是增加计数值,而是减少计数值。在网站流量统计系统里面每接收到一个IP请求,就相应的cache.decrement(key)。所以对于真实用户的IP来说,它的计数值总是加1然后就减1,不可能很高。这样我们就可以大大降低判断爬虫的阀值,可以更加快速准确的识别和拒绝掉爬虫。

2、用时间窗口来改进实时反爬虫系统

爬虫爬取网页的频率都是比较固定的,不像人去访问网页,中间的间隔时间比较无规则,所以我们可以给每个IP地址建立一个时间窗口,记录IP地址最近12次访问时间,每记录一次就滑动一次窗口,比较最近访问时间和当前时间,如果间隔时间很长判断不是爬虫,清除时间窗口,如果间隔不长,就回溯计算指定时间段的访问频率,如果访问频率超过阀值,就转向验证码页面让用户填写验证码。

最终这个实时反爬虫系统就相当完善了,它可以很快的识别并且自动封锁爬虫的访问,保护网站的正常访问。不过有些爬虫可能相当狡猾,它也许会通过大量的爬虫测试来试探出来你的访问阀值,以低于阀值的爬取速度抓取你的网页,因此我们还需要辅助第3种办法,用日志来做后期的分析和识别,就算爬虫爬的再慢,它累计一天的爬取量也会超过你的阀值被你日志分析程序识别出来。

总之我们综合运用上面的四种反爬虫策略,可以很大程度上缓解爬虫对网站造成的负面影响,保证网站的正常访问。

robbin  2009-08-17发表  2013-02-20更新  2483次浏览

3条评论

  • 王恒Frank
    王恒Frank  2013-03-18

    嗯,我也想过,目前计算的是全部IP只计算数量的话是1024M(java int 2字节)
    不过还是想在一台机器上完成准确统计IP访问次数的统计
    想法是,按照IPv4的划分,第一阶段按照第一段地址划分,比如192.168.1.1就划归到192中去
    某个数字统计次数达到某个阀值,在将某个数字进入第二阶段统计,精确到第二段,如将其放入192->168中统计...如此一来可以节省部分内存,但开销依然很大。

    robbin 评论:
    可以用分布式的memcached或者redis。

    王恒Frank 评论:
    博主分享的反爬虫策略我看了两遍,相当完善,赞!
    博主的策略中使用了memcached计数,是否key就是IP地址呢?如果是IP地址,对于每天访问量较大(高并发,每日访问量在5000W+级以上)的网站是否会不适用呢?
    谢谢博主的分享,学习到很多东西。

  • robbin
    robbin  2013-02-27

    可以用分布式的memcached或者redis。

    王恒Frank 评论:
    博主分享的反爬虫策略我看了两遍,相当完善,赞!
    博主的策略中使用了memcached计数,是否key就是IP地址呢?如果是IP地址,对于每天访问量较大(高并发,每日访问量在5000W+级以上)的网站是否会不适用呢?
    谢谢博主的分享,学习到很多东西。

  • 王恒Frank
    王恒Frank  2013-02-27

    博主分享的反爬虫策略我看了两遍,相当完善,赞!
    博主的策略中使用了memcached计数,是否key就是IP地址呢?如果是IP地址,对于每天访问量较大(高并发,每日访问量在5000W+级以上)的网站是否会不适用呢?
    谢谢博主的分享,学习到很多东西。

转载于:https://my.oschina.net/taisha/blog/119200

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_893959.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Awesome项目搜索网站

简介 最近突发奇想开发了一个Awesome项目搜索网站&#xff0c;整个网站看起来样子长这样。 为什么要开发一个这个呢&#xff1f;因为Github上有很多Awesome类型的项目&#xff0c;其实就是针对某一种类型的项目做一个聚合&#xff0c;然后使用markdown展示出来。但是感觉这样的…

网站搭建与部署(一)——云服务器使用

一、 购买云服务器 网上各种云服务器&#xff0c;看阿里云有免费试用版&#xff0c;就选择了阿里云。 二、 连接云服务器&#xff0c;这里有两种连接方式&#xff1a;Workbench远程连接和通过桌面连接。 1、 Workbench远程连接 不知道密码的可以选择重置密码 2、 桌面连接&a…

网站搭建与部署(二)——Nginx部署服务与代理

这里我用的后端语言是node.js&#xff0c;所以需要先安装node.js、mysql以及数据库工具Navicat。重点是Nginx的使用。 一、安装Nginx。 1、Nginx官网下载&#xff0c;这里我选择的是windows版本。 2、解压之后&#xff0c;双击nginx.exe&#xff0c;控制台一闪而过&#xff0c…

解决关闭浏览器后再打开,访问网站仍然自动登陆的问题

情况描述&#xff1a; 今天被授权以管理员身份登录管理系统&#xff0c;录入一些信息&#xff0c;但因为Chrome设置的是保存Cookie&#xff0c;并且先登录了自己的账号&#xff0c;所以即便关掉浏览器再打开&#xff0c;仍然是以自己的账号自动登录&#xff0c;而页面的注销按…

matplotlib/pandas/BeautifulSoup/wordcloud等在前程无忧网站爬取、分析上的应用(代码)

文章详细分析内容发布于个人公众号。谢谢大家关注&#xff1a; ID: DataDreamInitiate 公众号名称&#xff1a;数据分析X小硕 此处仅放爬虫及分析代码。有问题可公众号或博客回复讨论&#xff0c;谢谢&#xff01; 以下为搜索页面信息抓取、信息初步清理、岗位详细信息抓取…

不能通过IP地址访问网站的解决方案

在服务器的IIS中添加网站&#xff0c;端口设为8081.然后通过IIS能够直接浏览网站。 但是在我电脑上访问网站:http://xxxx.xxxx.xxxx.xxx/index.aspx 以IP的形式始终访问不了网站。 原因&#xff1a;windows防火墙一般只开放了80端口。通过其他端口访问服务器是被拒绝的。 解…

IIS配置网站出现404

HTTP 404或Not Found错误信息是HTTP的其中一种“标准回应信息”&#xff08;HTTP状态码&#xff09;&#xff0c;此信息代表客户端在浏览网页时&#xff0c;服务器无法正常提供信息&#xff0c;或是服务器无法回应且不知原因。 一般这种错误首先想到的就是请求的文件不存在。但…

GitHub Action自动完成华工疫情打卡、网站自动签到

AutoAction简介 该github工程主要是为了解决疫情期间华工需要不断地申报自身健康而建立,工程中使用GitHub Action来实现每天自动打卡工作。准备工作 1.一个github账号 2.一个163邮箱账号&#xff1a;用于发送签到成功邮件&#xff0c;推荐添加&#xff0c;为了方便验证是否签…

Latex 相关网站

公式王 在线进行公式图片识别&#xff0c;转换为 Latex 语法。 网址为 https://gongshi.wang/

B2C电商平台如何做SEO优化以提高流量?

B2C电子商城建设随着电商行业的发展而快速被搭建&#xff0c;B2C商城系统网站对于流量的需求也是很大的&#xff0c;有了流量才能去进行转化&#xff0c;从而获得更多的客户&#xff0c;获取更多的市场份额。想要提高流量就要从自然搜索的优化技巧入手&#xff0c;只有掌握了优…

教你免费且快速地搭建个人网站

今日科技快讯 针对近日坊间流传的“我们天天在看你的微信”一说&#xff0c;微信团队今天发表声明重申三条用户隐私原则&#xff1a;1、微信不留存任何用户的聊天记录&#xff0c;聊天内容只存储在用户的手机、电脑等终端设备上&#xff1b;2、微信不会将用户的任何聊天内容用于…

直接从网站下载视频的方法

直接从网站下载视频的方法 很多时候浏览器插件搞不定的事情就要自己动动手嘛。 1. 没加密的网页 开发者工具里找太费眼睛了 最快捷的方法就是用 you-get 直接下载 这里需要先安装python&#xff0c;站里就有许多帖子&#xff0c;我就不赘述了 有了python之后&#xff0c;我们…

在基于Form验证的SharePoint网站中实现用户口令过期策略

最近&#xff0c;公司有一个项目&#xff0c;是基于SharePoint的一个网站&#xff0c;采用Form验证&#xff0c;验证提供程序采用SqlMenbershipProvider。完成后交给用户测试&#xff0c;用户又提出新要求&#xff1a;要实现口令30天过期功能&#xff0c;超过30天的用户登录后自…

如何做网站迁移?网站搬家

网站迁移&#xff1a;指的是从本地迁移至生产服务器&#xff0c;或者是换台服务器。 迁移方法&#xff1a; 网站整体打包&#xff0c;复制到新到服务器。数据库通过phpmyadmin或者mysql命令行热备份。或者是关闭mysql服务器。直接拷贝数据库文件。将数据库恢复至新服务器修改新…

爬虫实例4(抓取12306网站余票信息)

简介 本实验主要是抓取2020-5-5成都东到西安北所有车次的信息&#xff0c;12306网站设置了反爬机制&#xff0c;要构造Headers才能获取数据&#xff0c;本文对获取的数据先进行了split()分割&#xff0c;将每趟列车的信息分割出来&#xff0c;然后通过与网站数据的对比找出哪些…

爬虫实例6(获取哔哩哔哩网站《后浪》弹幕并可视化显示)(pyecharts词云,pandas库)

声明&#xff0c;只用于学习研究爬虫 1.《后浪》弹幕词云 最近小视频《后浪》挺火&#xff0c;该视频是国家一级演员何冰登台演讲&#xff0c;认可、赞美与寄语年轻一代&#xff1b;对他们说&#xff1a;“你们有幸遇见这样的时代&#xff0c;但时代更有幸遇见这样的你们。”…

网站下载工具有哪些?

Teleport Ultra.exe 链接&#xff1a;https://pan.baidu.com/s/1LhrnKJdyjCKprALz6AbmWw 提取码&#xff1a;n3dw 注&#xff1a;本软件仅用于学习&#xff0c;禁止其它用途。

图标素材网站

素材图标 http://www.iconfont.cn/ 收藏和取消收藏 http://www.iconfont.cn/search/index?searchTypeicon&q%E6%94%B6%E8%97%8F&page1&fromCollection1

SEO书籍《这就是搜索引擎:核心技术详解》要点解读

经朋友的推荐&#xff0c;去年买了一本SEO书籍-《这就是搜索引擎&#xff1a;核心技术详解》&#xff0c;断断续续用了几个月的时间看完这本seo书籍。感觉还是蛮好的&#xff0c;此书涉及的内容广而不深&#xff0c;通俗易懂&#xff0c;适合广大站长朋友看&#xff0c;当然&am…

2014谷歌算法更新,再次降低全球网站PR值

2014谷歌算法更新了&#xff0c;即去年2月份后再次降低了全球网站PR值。2013全年全球网站的评价PR值已经从6.175降到现在为5.935。 这次GOOGLE即上次蜂鸟算法后又一次大的调整算法。据说&#xff0c;此次谷歌新算法调整&#xff0c;会针对全球网站降低PR值&#xff0c;同时&am…