Web防爬

Posted by 李小武 on April 17, 2016

爬虫与防爬是一个永无止境的斗争。

爬虫识别

防爬的首先要识别爬虫请求,这也是最难的一步。如何从大量的正常用户请求中精准识别爬虫请求,是整个防爬过程中很关键的环节,因为后面的策略都是围绕爬虫请求展开,如果爬虫识别错误,会对业务和真实用户造成干扰。

与正常用户相比,爬虫的请求多少会留下一些蛛丝马迹。

IP

最容易想到的是IP黑名单,可以通过手动/自动的方式把识别出来的IP地址添加到黑名单作为爬虫来源。由于很多内部网络的出口IP就那么几个,如果被误加到黑名单很可能导致大量的请求识别错误,所以黑名单方式还是要对名单内IP做严格控制把关,避免造成大量识别错误。

请求参数

请求中除了一些对结果产生影响的核心参数外,有可能还有一些非核心参数(请求头、统计、标记、默认值或某次新加入的参数)。这些非核心参数也不错的切入点,因为如果不是正常的请求,很可能这些非核心参数设置的不太合理,通过识别参数,也能以单次请求维度来识别爬虫。

用户

如果请求中带用户信息(如uid),那爬虫的识别准确率将大大提高,对于登录场景这似乎不是问题。非登录情况,似乎有些难办,不过还是有办法近似看成用户的登录的。

对于web应用,可以用cookie记录一个用户的唯一身份,每次请求带上身份信息;如果是移动设备,可以取设备id信息作为用户身份信息。不过cookie可以清除再生成,设备id信息也是有方案伪造,所以这个方式不一定100%能识别用户,还是有一定的风险。

行为分析

有了每个用户的请求行为,那基于行为分析来识别爬虫又能把识别成功率提高一个档次。

首先想到基于单用户的请求频率,这个最容易理解,不过还要结合业务场景和用户身份。每个用户的请求频率很可能跟用户的身份(活跃度,级别,标签,时间)有关系 ,不能一概而论。还有就是业务场景,比如下单的请求,频率太高大部分情况下是有问题的,但对搜索场景可能就没有问题。有的时候也可以根据前端的交互大概估算出用户的请求频率的,如表单填写耗时或ajax前端强制刷新频率。

除了请求频率,还可以结合业务场景分析用户一段时间内请求。举个买火车票的例子:这个场景下,用户的出发/到达/日期相对固定。最多会选择临近的城市或者临近日期,基本的范围还是能确定的。如果发现一个用户不时换出发/到达/日期搜索火车票,那就明显很有爬虫嫌疑了嘛。甚至还可以根据用户的下单历史来就诊防爬结果。

爬虫识别不是一锤子买卖,需要各个维度加权综合考虑,才能做到精准识别。

防爬

道高一尺魔高一丈。

爬虫和防爬一定是处于长期的斗争中并长久存在。

既然暴露在web上,想要干掉爬虫是不太可能的,毕竟最最笨还能人肉爬嘛(笑)。但是我们还是能做一些事情提高爬虫的门槛:

请求加密: 至少爬虫不能随意窜改参数想怎么爬就怎么爬。

强制登录: 是不是人,先登录后再说。即使破解了登录,账号的成本还是比较高的,而且基于登录用户信息去分析行为,也能更好识别爬虫。

请求关联: 每次请求都要基于上一次的结果数据,这样爬虫就不能伪造请求想爬那个就爬哪个了。

如何处理爬虫请求

拦截

拦截在越靠近端越好,理论上7层网络,除了物理层都可以做拦截,不过成本肯定不一样。如果能在前端,或者nginx拦截,最好不要让请求打到应用。

假如爬虫的请求量不大,比如整体请求的10%以下,并且没有对系统性能造成影响,不建议对爬虫请求做拦截。爬虫也不傻嘛,被拦截了肯定要破解你的防爬策略,何不装装傻,让它去爬呢?

当然也不能光看着爬虫肆虐。

混淆

对确定是爬虫的请求,对请求结果做混淆也不错的选择。让他去爬,给一个不确定的结果。

关小黑屋

关小黑屋相当于对拦截做不同的策略,如一段时间不能访问,然后在从小黑屋放出了。这样即使拦截错误,也不会一棍子把用户打死。