微信号:gh_7b30a45c1595

介绍:致力于营造国内一流的应用服务器的爱好者技术讨论,服务器相关资讯新闻分享,业界开源商用服务器相关动态,服务器端程序员职业发展相关的圈子; 以JAVA技术为基础扩展其它语言,讨论tomcat,JAVA EE规范,JVM,操...

Tomcat的爬虫请求识别 与 Crawler Session Manager Valve(Valve源码分析之六)

2017-02-19 14:49 feiying

我们前面讨论的应用服务器的请求大多数都是自然的浏览器客户端的人工请求,所谓的人工请求,就是我们按照正常的逻辑由人工完成一些业务,点击浏览器,最终由浏览器发送请求;

这种是最正常的,但我们经常会忽略一种请求,就是机器发出的请求,例如爬虫程序;


对于爬虫程序,会逐个通过http协议,对你的网站进行遍历,其目的是把你的网站的页面都搜集过来,形成html,作为索引存储到搜索引擎的本地库中;

我们经常用的功能,例如百度快照,就是这么回事;


关于爬虫怎么爬的,我们本文不会介绍,这属于另一个专题,本文会介绍爬虫程序在服务器一般怎么进行识别,而需要重视的事,如果robots.txt限制的较为松散,那么一旦爬虫请求特别多的话,会产生大量的session,那么作为Tomcat应用服务器是怎么解决这个问题的;


1.服务器一般如何识别爬虫请求

对于爬虫程序,首先不得不说一个标识,就是robots.txt,该文件的内容就是什么内容不会被爬虫爬到,是一个限制文件,我们来看看其目录位置:



robots.txt相当于一个约定俗称的东西,类似于护照一样,作为搜索引擎的爬虫程序,首先应该去访问你这个站点的robots.txt,其格式如下:



例子为:



该网站的robots.txt针对于百度的spider进行限制;


但是,robots.txt可以这么说的,是一个君子协定,这就是如同上公交车给老人让座一样,是一个传统美德,但是你要是不让座的话,谁也不能把你怎么样,所以,这只针对于大型爬虫程序,例如百度,google这种,下图就是一些知名的爬虫搜索引擎:


但是,对于一些“野爬虫”,有的爬虫几乎对robots.txt视而不见,这就造成了“君子协定不君子”的局面了;

对于这种情况,服务器端有必要进行一些识别了,一般就是基于http头的user-agent来进行判断,user-agent是http请求头的一个选项,该选项一般能识别出客户端的cpu,操作系统,浏览器内核版本等一系列的信息:


如上述的一串信息,代表是windows NT下的safari浏览器进行访问的;


常用的user-agent还有:

IE 11
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko

IE 9.0
User-Agent:Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;

Firefox 4.0.1 – Windows
User-Agent:Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1

Chrome 17.0 – MAC
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11


傲游(Maxthon)
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)

搜狗浏览器 1.x
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)

。。。


值得注意的是,目前是移动时代,PC机的浏览器发出的user-agent和目前的平板电脑上的发出的user-agent还不一样;


我们看到前面的user-agent的定义,不同浏览器定义不同,一般爬虫程序都是机器生成,一般不会写user-agent,只管爬,所以对于服务器来讲,可以通过这个字段去看你的请求到底是不是爬虫程序;


但我们前面也说了,如果真是“野爬虫”,那么人家故意伪造这个字段也很容易;

所以,可以这么说吧,虽然服务器端可以通过user-agent去判断,但也不是很灵;

而对于该方法的增强是,再通过IP去反查其host的爬虫搜索引擎的地址,和一些核心的地址进行比对,如在程序中用nslookup:


然后该IP地址你可以和n个著名的ip端进行比对,如下面这些:


当然了,该方法对于“野爬虫”还是无效;


最后一个手段,也是近年来比较流行的技术,如机器学习技术等,例如下面的一连串的访问:

www.feiying.com/pages/1

www.feiying.com/pages/2

www.feiying.com/pages/3

.....

www.feiying.com/pages/1000

像这样的连续访问,只有傻子看不出来,肯定是爬虫程序,这种方式就有点攻防识别的意味了,不属于本文讨论的范畴;


2.Tomcat中的Crawler Session Manager Valve思路

Tomcat中基于爬虫请求采用user-agent的方式的客户端请求进行了简单的识别,其主要目的是为了减少session的创建,否则大量的爬虫请求很有可能在瞬间会创建成百上千个session,一下子把Tomcat的session就压垮了;

Crawler Session Manager Valve

Introduction

Web crawlers can trigger the creation of many thousands of sessions as they crawl a site which may result in significant memory consumption. 


This Valve ensures that crawlers are associated with a single session 

这句话最为关键,

Crawler Session Manager Valve 的作用就是当发现你的请求是爬虫请求,会将爬虫请求关联为一个session;

- just like normal users - regardless of whether or not they provide a session token with their requests.

This Valve may be used at the EngineHost or Context level as required. Normally, this Valve would be used at the Engine level.

If used in conjunction with Remote IP valve then the Remote IP valve should be defined before this valve to ensure that the correct client IP address is presented to this valve.

Tomcat搞出来一个Valve,这个Valve是主要配置在Context节点的,针对于一个应用有效,但同时也可以配置在Engine和Host中;

我们先看看属性:

Attributes

The Crawler Session Manager Valve supports the following configuration attributes:

Attribute Description
className

Java class name of the implementation to use. This MUST be set to org.apache.catalina.valves.CrawlerSessionManagerValve.

你要觉得CrawlerSessionManagerValve 实现不好,你也可以自己搞一个进行实现;

crawlerUserAgents

Regular expression (using java.util.regex) that the user agent HTTP request header is matched against to determine if a request is from a web crawler. If not set, the default of .*[bB]ot.*|.*Yahoo! Slurp.*|.*Feedfetcher-Google.* is used.

可以通过正则表达式过滤的usergent,当符合该字段的useragent,可以看作为爬虫请求;

sessionInactiveInterval

The minimum time in seconds that the Crawler Session Manager Valve should keep the mapping of client IP to session ID in memory without any activity from the client. The client IP / session cache will be periodically purged of mappings that have been inactive for longer than this interval. If not specified the default value of 60 will be used.

爬虫程序关联的一个session的超时时间;

来看看源码是怎么实现的,我们主要来看看invoke方法:


其主要实现为通过一个isBot的标识,该标识为是否是爬虫请求的标识,Tomcat通过这个Valve,简单的通过user-agent是否有无来判断是爬虫请求不,当如果不写user-agent的话,说明就是爬虫请求,当存在user-agent的话,和配置的crawlerUserAgents 进行匹配,如果匹配了,也说明是爬虫请求;


如果Tomcat认定该请求是爬虫请求,那么就会从一个缓存中clientIpSessionId中去查看该爬虫请求是否访问过(使用的key是clientIP),如果访问过的话,拿出其已经缓存的session,并设置到Request中,如果没有,新创建session,并设置超时时间;


因此,当配置了这个Valve之后,主要是爬虫请求,以IP为key值,那么对应的session就是一个;


总结:

本文首先讲了讲服务器如何识别爬虫请求的几个办法,可以说是都不是特别理想,除了最后的通过机器学习的手段去做,成功几率会高一些;

而Tomcat搞出了一个Crawler Session Manager Valve去识别爬虫请求,其目的是为了减少大量Session的创建,根据IP对应一个Session;

而Tomcat的这个手段是就是通过user-agent的字段识别,手段相对单一,可以这么说吧,还是比较“low”的,对于一些“野爬虫”估计识别够呛,需要你自定义增强去实现,例如给Tomcat搞个机器学习插件的Valve去做!


 
应用服务器技术讨论圈 更多文章 JAVA EE守护者关于向Oracle总裁拉里·埃里森请愿推动JAVA EE规范的原文与翻译 聊聊JAVA EE最近这点事 聊聊JAVA EE最近这点事 Tomcat的基于不同用户定制化的web应用 监听器 UserConfig (Listener&n Tomcat的基于不同用户定制化的web应用 监听器 UserConfig (Listener&n
猜您喜欢 前端开发者喜欢的20个学习文档 Web测试方法(流程) 程序媛的碎碎念 天生丽质偏自弃:为什么有些三文鱼总一副不想活的样子?|科学人 “Kubernetes 大咖秀” 来了!K8S 代码贡献#6 美国 Googl