4.3 爬虫对抗技术
网络爬虫的实质,其实是从网络上“偷”数据。通过网络爬虫,我们可以采集到所需要的资源,但是同样,使用不当也可能会引发一些比较严重的问题。当前随着爬虫技术的不断发展,反爬虫行为也越来越多,本节我们就初步了解一下反爬的相关知识点。
1. 网站为什么要反爬虫
目标网站对爬虫采取反制措施,无非是基于以下几点考虑:
- 爬虫影响服务器性能,对服务器产生骚扰行为,并加大了网站维护者的工作量,除了机器,人工也费钱。
- 网络爬虫也可能会造成用户的隐私泄露。
- 如果没有反爬虫,竞争对手就可以批量复制相关数据,降低自身市场竞争力。
- 爬虫行为在法律上还没有得到有效的界定(擦边球)。
2. 爬虫和反爬虫的相关定义
爬虫:使用任何技术手段,批量获取网站信息的一种方式。关键在于批量。
反爬虫:使用任何技术手段,阻止别人批量获取自己网站信息的一种方式。关键也在于批量。
误伤:在反爬虫的过程中,错误的将普通用户识别为爬虫。误伤率高的反爬虫策略,效果再好也不能用。
拦截:成功地阻止爬虫访问。这里会有拦截率的概念。通常来说,拦截率越高的反爬虫策略,误伤的可能性就越高。因此需要做个权衡。
资源:机器成本与人力成本的总和,人力成本也是资源,而且比机器更重要。
3. 网站反爬虫的手段
(1) Robots.txt
Robots.txt 是一个古老的爬虫协议文件,他的位置位于域名根目录下。譬如 http://example.com/robots.txt 。严格来讲 Robots.txt 并不算一个反爬虫技术,而是一个由爬虫遵守的协议。它通过几个简单的命令告知遵守 Robots.txt 的爬虫哪些可以被爬取,哪些不能。一般的搜索引擎爬虫会遵守这个协议,而对于上升到爬虫技术对抗的层次来说,这个文件毫无意义。
(2) IP层/网络层
网络层是反爬虫技术涉及到的最下层,再下的链路层信息在 IP 报文的传输过程中会被三层交换机丢弃,没有任何意义。IP报文带有的最重要的信息就是IP请求的来源地址,来源地址极难(近乎不可能)伪造的特性,使得这个字段成为反爬虫策略中最重要的字段。
封杀IP/IP段是网站可以执行的最严厉的惩罚。但由于国内的ISP大量的使用了NAT技术,导致大量用户共用IP的情况越来越多,网站在做IP封杀时会越来越谨慎,因为这样做会导致极高的误杀率,以至影响正常用户的网站访问。但是即使如此,源IP也是反爬虫策略中最为核心的数据,反爬策略的执行动作一般都要围绕源IP进行。
应对
- 使用代理服务器(HTTP 代理和 Socks 代理)
- 使用路由器生成动态 ip,可以考虑构建 ADSL 代理池
- 使用高匿代理,如 tor
(3) HTTP 协议层
HTTP 层有几个有趣的 HTTP 头,它们是制定反爬虫策略的常用数据。
X-Forwarded-For
X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。Squid 缓存代理服务器的开发人员最早引入了这一HTTP头字段,并由IETF在HTTP头字段标准化草案中正式提出。
XFF头由普通HTTP代理服务器添加, 在用户通过普通HTTP代理访问网站时, 用户的IP地址会被添加到这个头中。有些新手程序员在写代码时,往往会把这个的IP地址当做用户的真实IP地址使用,从而被爬虫利用。
Referer
Referer是浏览器在页面跳转时带入的HTTP头,指示用户上一个页面的URL,一般来说,网站90%以上的流量应该带有Referer头,在一些常见的反爬策略中,大量的不带Referer头的源IP请求会触发"要求输入验证码"策略。
User-Agent
User-Agent 是一个古老的HTTP头,指示用户浏览器的版本、操作系统等基本信息, UserAgent伪装已经在其他的文章里有过充分的讨论,故本文不再赘述。
应对
- 自建 User-Agent 池
- 添加 Referer
(4) 应用层面(浏览器)
通过 HTTP 传输的数据最终会交由浏览器或者APP去渲染、执行。这里重点讨论基于现代浏览器的应用层反爬、及反反爬技术。
验证码
验证码(CAPTCHA)是一种古老而有效的方式,用来判别请求方是否是人类。从最初的简单数字验证码、到后来的中文验证码,到现代的图片验证码,验证码是应用层最普遍,也最核心的爬虫对抗技术。
应对
- 对于一些简单的数字、字母验证码,可以使用 OCR 工具,或者使用机器算法训练模型,提升识别率。
- 对于复杂的图片验证码,可以专门用人工打码平台来处理。
JS渲染(Ajax / SPA)
众所周知,Ajax技术在2004年左右开始迅速发展,成为重要的浏览器端技术,也让爬虫从静态爬虫转化为动态爬虫。从此,爬取网站的数据不再是简单的一个HTTP请求,然后解析HTML页面就可以了。大量的网站使用ajax来构建网站前端,也使得解析数据变得越来越困难。在网站完全不设防的状态,爬虫也不止需要解析HTML页面,亦需要解析Ajax接口返回的数据。
应对
谷歌浏览器,开发者工具,网路,xhr
接口加密与JS混淆
一般Ajax接口返回的是一个JSON/XML数据格式,除了给爬虫工程师制造一点点的麻烦以外,并没有任何的反爬虫作用,只需一点点的前端逆向能力(利用Chrome Debug工具, 找到网络请求),就可以找到ajax接口,并通过对应的库解析出数据。但是如果前端通过JS混淆、并把ajax接口通过token进行加密的话,事情就变得比较麻烦了。
这种做法的思路是,ajax接口除了正常的HTTP请求参数外,额外还要接受一个Token参数,这个token参数是前端的js脚本通过其他的参数加密出来的,它可能是xor、md5、或者是sha256等等。参数可以是用户名、ip、cookies的sessionid、甚至是用户的操作流程(支付宝的做法)再加上前端把js的函数调用层层嵌套、隐藏、再加上js脚本混淆,令破解者无法方便的逆向出token计算的流程,就可以达到一定的反爬目的。
应对
好好学习 http 原理,学习 js...
数据混淆(投毒)
爬虫的目的是获取到有效的数据。对于许多应用来说,获取到错误的数据往往比获取不到数据更加致命。(想象一下比价网站拿到的都是错误数据的场景)。这个思路的核心就是,当爬虫命中反爬规则之后,使用错误的数据代替正确的数据返回给爬虫,这种方式非常隐蔽,又可以对对手造成足够的麻烦,虽然猥琐、也相当的有效。
应对
组合多种反反爬虫策略,关键是 IP
行为分析
用户的操作轨迹与爬虫的操作轨迹是不同的。举个例子,在电商网站上,用户可能会浏览100个或者更多相似的商品,最终选择一个进行下单。而爬虫的行为可能是浏览100000个商品,且它们之间彼此关联度很低,最终也不会有任何购买动作。从这个维度来说,就可以判断出这个请求来源是客户还是爬虫。 结合其他的反爬手段,就可以对爬虫造成有效干扰。低级的行为分析基于规则,高级的行为分析基于机器学习。对于用户操作比较多的网站来讲,是一种很可靠的反爬手段。
应对
对于基于简单规则反爬的网站,需要组合多种反反爬虫策略,对于电商类网站,需要进行临界值测试。
假链陷阱
假链陷阱作为反爬手段,多见于半静态网站。比如构建一个不可见的a标签, 如果爬虫跟踪所有的页面链接,势必会掉到构造好的陷阱,导致爬虫命中反爬策略。
应对
探测陷阱,在代码之中进行事先检验,比如 nofollow 的 tag,或者 display:none 的 CSS。
# 检测display属性:
document.getElementById('id').style.display
document.getElementsByClassName(’classname')[0].style.display
JS引擎指纹
这种思路是,不同的JS引擎在执行相同的JS语句时,会有不同的结果。 举个例子来说,eval.toString().length,在Safari浏览器中的结果是 37 , 在IE中是39 , 在Chrome 中的结果是33. 通过判断JS引擎的动作和UserAgent中声称的浏览器类型,可以判断是否是伪造浏览器。
应对
学好 js.....