反爬虫思路与解决办法(综合)

随之大数据的火热,网络上各种网页抓取/爬虫工具蜂拥而来,因而,网页数据成了大家竞争掠夺的资源,但网站运营者却要开始保护自己的数据资源,以避免被竞争对手获取到自己的数据,防止更大的商业损失。下面总结一下反爬虫策略及其应对方法。

一、什么是爬虫和反爬虫

爬虫和反爬虫作为相生相克的死对头,无论爬虫多厉害,都是能被复杂的反爬虫机制发现,同样的,无论反爬虫机制多么缜密,都是能被高级的网络爬虫所攻破,胜负的关键就看双方的资源投入多少了。为了更好地理解爬虫和反爬虫机制,下面有一些定义:

爬虫:使用任何技术手段,批量获取网站信息的一种方式。关键在于批量。 反爬虫:使用任何技术手段,阻止别人批量获取自己网站信息的一种方式。关键也在于批量。

误伤:在反爬虫的过程中,错误的将普通用户识别为爬虫。误伤率高的反爬虫策略,效果再好也不能用。

拦截:成功地阻止爬虫访问。这里会有拦截率的概念。通常来说,拦截率越高的反爬虫策略,误伤的可能性就越高。因此需要做个权衡。

所以,我们可以知道,爬虫有一个最基本的特征就是批量,而反爬虫机制也是根据这个特征来做判断的,但反爬虫还是一个权衡利弊的选择,既要较低的误伤率,又要较高的拦截率,这也是它的漏洞。关于网站为什么以及如何制定反爬虫策略,可以看携程酒店技术部总结的关于反爬虫的心得体会。

二、反爬虫方法及其应对

一般网站从三个方面反爬虫:请求网站访问时的请求头Headers,用户行为,目标网站的目录和数据加载方式。前两个方面可以说是反爬虫策略中最为常见的,而第三个则是应用ajax(异步加载)的方式加载页面目录或者内容,增大爬虫在对目标网站形成访问之后获取数据的难度。

但是仅仅检验一下请求头或者做几个ip限制显然无法达到网站运营者对anti-spam的要求,所以更进一步的反制措施也不少。最主要的大概有:Cookie限制,验证码反爬虫,以及Noscript。

2.1 通过Headers反爬虫

从用户请求的Headers反爬虫是最常见的反爬虫策略。由于正常用户访问网站时是通过浏览器访问的,所以目标网站通常会在收到请求时校验Headers中的User-Agent字段,如果不是携带正常的User-Agent信息的请求便无法通过请求。还有一部分网站为了防盗链,还会校验请求Headers中的Referer字段。 如果遇到了这类反爬虫机制,可以直接在自己写的爬虫中添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;另外通过对请求的抓包分析,将Referer值修改为目标网站域名,就能很好的绕过。

2.2 基于用户行为反爬虫

还有一些网站会通过用户的行为来检测网站的访问者是否是爬虫,例如同一IP短时间内多次访问同一页面,或者同一账户短时间内多次进行相同操作。 大多数网站都是前一种情况,对于这种情况有两种策略:

1)使用代理ip。例如可以专门写一个在网上抓取可用代理ip的脚本,然后将抓取到的代理ip维护到代理池中供爬虫使用,当然,实际上抓取的ip不论是免费的还是付费的,通常的使用效果都极为一般,如果需要抓取高价值数据的话也可以考虑购买宽带adsl拨号的VPS,如果ip被目标网站被封掉,重新拨号即可。

2)降低请求频率。例如每个一个时间段请求一次或者请求若干次之后sleep一段时间。由于网站获取到的ip是一个区域网的ip,该ip被区域内的所有人共享,因此这个间隔时间并不需要特别长

对于第二种情况,可以在每次请求后随机间隔几秒再进行下一次请求。对于有逻辑漏洞的网站,可以通过请求几次,退出登录,重新登录,继续请求来绕过同一账号短时间内不能多次进行相同请求的限制,如果能有多个账户,切换使用,效果更佳。

2.3 动态页面的反爬虫

上述的几种情况大多都是出现在静态页面,但是对于动态网页,我们需要爬取的数据是通过ajax请求得到,或者通过JavaScript生成的。首先用Firebug或者HttpFox对网络请求进行分析。如果能够找到ajax请求,也能分析出具体的参数和响应的具体含义,我们就能采用上面的方法,直接利用requests或者urllib2模拟ajax请求,对响应的json进行分析得到需要的数据。

能够直接模拟ajax请求获取数据固然是极好的,但是有些网站把ajax请求的所有参数全部加密了。我们根本没办法构造自己所需要的数据的请求。还有一些严防死守的网站,除了加密ajax参数,它还把一些基本的功能都封装了,全部都是在调用自己的接口,而接口参数都是加密的。

遇到这样的网站,我们就不能用上面的方法了,通过selenium+phantomJS框架,调用浏览器内核,并利用phantomJS执行js来模拟人为操作以及触发页面中的js脚本。从填写表单到点击按钮再到滚动页面,全部都可以模拟,不考虑具体的请求和响应过程,只是完完整整的把人浏览页面获取数据的过程模拟一遍。用这套框架几乎能绕过大多数的反爬虫,因为它不是在伪装成浏览器来获取数据(上述的通过添加

Headers一定程度上就是为了伪装成浏览器),它本身就是浏览器,phantomJS就是一个没有界面的浏览器,只是操控这个浏览器的不是人。

2.4 Cookie限制

和Headers校验的反爬虫机制类似,当用户向目标网站发送请求时,会再请求数据中携带Cookie,网站通过校验请求信息是否存在Cookie,以及校验Cookie的值来判定发起访问请求的到底是真实的用户还是爬虫,第一次打开网页会生成一个随机cookie,如果再次打开网页这个Cookie不存在,那么再次设置,第三次打开仍然不存在,这就非常有可能是爬虫在工作了。

而Cookie校验和Headers的区别在于,用户发送的Headers的内容形式是固定的可以被轻易伪造的,Cookie则不然。原因是由于,我们在分析浏览器请求网站访问的过程中所分析得到的Cookie往往都是经过相关的js等过程已经改变了domain的Cookie,假如直接手动修改爬虫携带的Cookie去访问对应的网页,由于携带的Cookie已经是访问之后的domain而不是访问之前的domain,所以是无法成功模拟整个流程的,这种情况必然导致爬虫访问页面失败。 分析Cookie,可能会携带大量的随机哈希字符串,或者不同时间戳组合的字符串,并且会根据每次访问更新domain的值。对这种限制,首先要在对目标网站抓包分析时,必须先清空浏览器的Cookie,然后在初次访问时,观察浏览器在完成访问的过程中的请求细节(通常会在这一过程中发生若干次301/302转跳,每次转跳网站返回不同的Cookie给浏览器然后在最后一次转跳中请求成功)。在抓包完成对请求细节的分析之后,再在爬虫上模拟这一转跳过程,然后截取Cookie作为爬虫自身携带的Cookie,这样就能够绕过Cookie的限制完成对目标网站的访问了。

2.5 验证码限制

这是一个相当古老但却不失有效性的反爬虫策略。更早的时候,这种验证码可以通过OCR技术进行简单的图像识别破解,但是现在来说,验证码的干扰线,噪点已经多到肉眼都无法轻易识别的地步。所以目前而言,由于OCR技术发展不力,验证码技术反而成为了许多网站最有效的手段之一。

验证码除了识别难题之外,还有另外一个值得注意的问题。现在有许多网站都在使用第三方验证码服务。当用户打开目标网站的登录页面时,登录页面显示的验证码是从第三方(比如阿里云)提供的链接加载的,这时候我们在模拟登录的时候,需要多一步从网页提供的第三方链接抓取验证码的步骤,而这一步常常暗含着陷阱。以阿里云提供的验证码服务为例,登录页面的源代码会显示阿里云提供的第三方链接,但是当匹配出这个链接进行验证码抓取的时候我们会发现验证码是无效的。当仔细分析抓包的请求数据之后,发现正常浏览器在请求验证码时,会多带一个ts参数,而这个参数是由当前时间戳产生的,但是并不是完全的时间戳,而是时间戳四舍五入保留九位数字之后的字符串,对待这种第三方服务只能是细心加运气,三分天注定七分不信命来猜一发了。还有另外一种特殊的第三方验证码,所谓的拖动验证,只能说,互联网创业有三种模式2b,2c,2vc。