关于反爬虫

最近从网上看到的反爬虫帖子,记录下来。你们也能够观看视频回放,“现场”围观。javascript

1、为何要反爬虫

一、爬虫占总PV比例较高,这样浪费钱(尤为是三月份爬虫)。html

三月份爬虫是个什么概念呢?每一年的三月份咱们会迎接一次爬虫高峰期。前端

最初咱们百思不得其解。直到有一次,四月份的时候,咱们删除了一个url,而后有个爬虫不断的爬取url,致使大量报错,测试开始找咱们麻烦。咱们只好特地为这个爬虫发布了一次站点,把删除的url又恢复回去了。java

可是当时咱们的一个组员表示很不服,说,咱们不能干掉爬虫,也就罢了,还要专门为它发布,这实在是太没面子了。因而出了个主意,说:url能够上,可是,绝对不给真实数据。node

因而咱们就把一个静态文件发布上去了。报错中止了,爬虫没有中止,也就是说对方并不知道东西都是假的。这个事情给了咱们一个很大的启示,也直接成了咱们反爬虫技术的核心:变动。python

后来有个学生来申请实习。咱们看了简历发现她爬过携程。后来面试的时候确认了下,果真她就是四月份害咱们发布的那个家伙。不过由于是个妹子,技术也不错,后来就被咱们招安了。如今已经快正式入职了。程序员

后来咱们一块儿讨论的时候,她提到了,有大量的硕士在写论文的时候会选择爬取OTA数据,并进行舆情分析。由于五月份交论文,因此嘛,你们都是读过书的,大家懂的,前期各类DotA,LOL,到了三月份了,来不及了,赶忙抓数据,四月份分析一下,五月份交论文。面试

就是这么个节奏。ajax

二、公司可免费查询的资源被批量抓走,丧失竞争力,这样少赚钱。浏览器

OTA的价格能够在非登陆状态下直接被查询,这个是底线。若是强制登录,那么能够经过封杀帐号的方式让对方付出代价,这也是不少网站的作法。可是咱们不能强制对方登陆。那么若是没有反爬虫,对方就能够批量复制咱们的信息,咱们的竞争力就会大大减小。

竞争对手能够抓到咱们的价格,时间长了用户就会知道,只须要去竞争对手那里就能够了,不必来携程。这对咱们是不利的。

三、爬虫是否涉嫌违法? 若是是的话,是否能够起诉要求赔偿?这样能够赚钱。

这个问题我特地咨询了法务,最后发现这在国内仍是个擦边球,就是有可能能够起诉成功,也可能彻底无效。因此仍是须要用技术手段来作最后的保障。

2、反什么样的爬虫

一、十分低级的应届毕业生

开头咱们提到的三月份爬虫,就是一个十分明显的例子。应届毕业生的爬虫一般简单粗暴,根本无论服务器压力,加上人数不可预测,很容易把站点弄挂。

顺便说下,经过爬携程来获取offer这条路已经行不通了。由于咱们都知道,第一个说漂亮女人像花的人,是天才。而第二个。。。大家懂的吧?

二、十分低级的创业小公司

如今的创业公司愈来愈多,也不知道是被谁忽悠的而后你们创业了发现不知道干什么好,以为大数据比较热,就开始作大数据。

分析程序全写差很少了,发现本身手头没有数据。

怎么办?写爬虫爬啊。因而就有了不可胜数的小爬虫,出于公司生死存亡的考虑,不断爬取数据。

三、不当心写错了没人去中止的失控小爬虫

携程上的点评有的时候可能高达60%的访问量是爬虫。咱们已经选择直接封锁了,它们依然孜孜不倦地爬取。

什么意思呢?就是说,他们根本爬不到任何数据,除了http code是200之外,一切都是不对的,但是爬虫依然不中止这个极可能就是一些托管在某些服务器上的小爬虫,已经无人认领了,依然在辛勤地工做着。

四、成型的商业对手

这个是最大的对手,他们有技术,有钱,要什么有什么,若是和你死磕,你就只能硬着头皮和他死磕。

五、抽风的搜索引擎

你们不要觉得搜索引擎都是好人,他们也有抽风的时候,并且一抽风就会致使服务器性能降低,请求量跟网络攻击没什么区别。

3、什么是爬虫和反爬虫

由于反爬虫暂时是个较新的领域,所以有些定义要本身下。咱们内部定义是这样的:

  • 爬虫:使用任何技术手段,批量获取网站信息的一种方式。关键在于批量。

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

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

  • 拦截:成功地阻止爬虫访问。这里会有拦截率的概念。一般来讲,拦截率越高的反爬虫策略,误伤的可能性就越高。所以须要作个权衡。

  • 资源:机器成本与人力成本的总和。

这里要切记,人力成本也是资源,并且比机器更重要。由于,根据摩尔定律,机器愈来愈便宜。而根据IT行业的发展趋势,程序员工资愈来愈贵。所以,让对方加班才是王道,机器成本并非特别值钱。

4、知己知彼:如何编写简单爬虫

要想作反爬虫,咱们首先须要知道如何写个简单的爬虫。

目前网络上搜索到的爬虫资料十分有限,一般都只是给一段python代码。python是一门很好的语言,可是用来针对有反爬虫措施的站点作爬虫,真的不是最优选择。

更讽刺的是,一般搜到的python爬虫代码都会使用一个lynx的user-agent。大家应该怎么处理这个user-agent,就不用我来讲了吧?

一般编写爬虫须要通过这么几个过程:

  • 分析页面请求格式

  • 建立合适的http请求

  • 批量发送http请求,获取数据

举个例子,直接查看携程生产url。在详情页点击“肯定”按钮,会加载价格。假设价格是你想要的,那么抓出网络请求以后,哪一个请求才是你想要的结果呢?

答案出乎意料的简单,你只须要用根据网络传输数据量进行倒序排列便可。由于其余的迷惑性的url再多再复杂,开发人员也不会舍得加数据量给他。

5、知己知彼:如何编写高级爬虫

那么爬虫进阶应该如何作呢?一般所谓的进阶有如下几种:

分布式

一般会有一些教材告诉你,为了爬取效率,须要把爬虫分布式部署到多台机器上。这彻底是骗人的。分布式惟一的做用是:防止对方封IP。封IP是终极手段,效果很是好,固然,误伤起用户也是很是爽的。

模拟JavaScript

有些教程会说,模拟javascript,抓取动态网页,是进阶技巧。可是其实这只是个很简单的功能。由于,若是对方没有反爬虫,你彻底能够直接抓ajax自己,而无需关心js怎么处理的。若是对方有反爬虫,那么javascript必然十分复杂,重点在于分析,而不只仅是简单的模拟。

换句话说:这应该是基本功。

PhantomJs

这个是一个极端的例子。这个东西本意是用来作自动测试的,结果由于效果很好,不少人拿来作爬虫。可是这个东西有个硬伤,就是:效率。此外PhantomJs也是能够被抓到的,出于多方面缘由,这里暂时不讲。 

6、不一样级别爬虫的优缺点

越是低级的爬虫,越容易被封锁,可是性能好,成本低。越是高级的爬虫,越难被封锁,可是性能低,成本也越高。

当成本高到必定程度,咱们就能够无需再对爬虫进行封锁。经济学上有个词叫边际效应。付出成本高到必定程度,收益就不是不少了。

那么若是对双方资源进行对比,咱们就会发现,无条件跟对方死磕,是不划算的。应该有个黄金点,超过这个点,那就让它爬好了。毕竟咱们反爬虫不是为了面子,而是为了商业因素。

7、如何设计一个反爬虫系统(常规架构)

有个朋友曾经给过我这样一个架构:

一、对请求进行预处理,便于识别;
二、识别是不是爬虫;
三、针对识别结果,进行适当的处理;

当时我以为,听起来彷佛颇有道理,不愧是架构,想法就是和咱们不同。后来咱们真正作起来反应过来不对了。由于:

若是能识别出爬虫,哪还有那么多废话?想怎么搞它就怎么搞它。若是识别不出来爬虫,你对谁作适当处理?

三句话里面有两句是废话,只有一句有用的,并且还没给出具体实施方式。那么:这种架构(师)有什么用?

由于当前存在一个架构师崇拜问题,因此不少创业小公司以架构师名义招开发。给出的title都是:初级架构师,架构师自己就是个高级岗位,为何会有初级架构。这就至关于:初级将军/初级司令。

最后去了公司,发现十我的,一个CTO,九个架构师,并且可能你本身是初级架构师,其余人仍是高级架构师。不过初级架构师还不算坑爹了,有些小创业公司还招CTO作开发呢。

传统反爬虫手段

一、后台对访问进行统计,若是单个IP访问超过阈值,予以封锁。

这个虽然效果还不错,可是其实有两个缺陷,一个是很是容易误伤普通用户,另外一个就是,IP其实不值钱,几十块钱甚至有可能买到几十万个IP。因此整体来讲是比较亏的。不过针对三月份呢爬虫,这点仍是很是有用的。

二、后台对访问进行统计,若是单个session访问超过阈值,予以封锁。

这个看起来更高级了一些,可是其实效果更差,由于session彻底不值钱,从新申请一个就能够了。

三、后台对访问进行统计,若是单个userAgent访问超过阈值,予以封锁。

这个是大招,相似于抗生素之类的,效果出奇的好,可是杀伤力过大,误伤很是严重,使用的时候要很是当心。至今为止咱们也就只短暂封杀过mac下的火狐。

四、以上的组合

组合起来能力变大,误伤率降低,在遇到低级爬虫的时候,仍是比较好用的。

由以上咱们能够看出,其实爬虫反爬虫是个游戏,RMB玩家才最牛逼。由于上面提到的方法,效果均通常,因此仍是用JavaScript比较靠谱。

也许有人会说:javascript作的话,不是能够跳掉前端逻辑,直接拉服务吗?怎么会靠谱呢?由于啊,我是一个标题党啊。JavaScript不只仅是作前端。跳过前端不等于跳过JavaScript。也就是说:咱们的服务器是nodejs作的。

思考题:咱们写代码的时候,最怕碰到什么代码?什么代码很差调试?

eval

eval已经臭名昭著了,它效率低下,可读性糟糕。正是咱们所须要的。

goto

js对goto支持并很差,所以须要本身实现goto。

混淆

目前的minify工具一般是minify成abcd之类简单的名字,这不符合咱们的要求。咱们能够minify成更好用的,好比阿拉伯语。为何呢? 由于阿拉伯语有的时候是从左向右写,有的时候是从右向左写,还有的时候是从下向上写。除非对方雇个阿拉伯程序员,不然非头疼死不可。

不稳定代码

什么bug不容易修?不容易重现的bug很差修。所以,咱们的代码要充满不肯定性,每次都不同。

代码演示

下载代码自己,能够更容易理解。这里简短介绍下思路:

  1. 纯JAVASCRIPT反爬虫DEMO,经过更改链接地址,来让对方抓取到错误价格。这种方法简单,可是若是对方针对性的来查看,十分容易被发现。

  2. 纯JAVASCRIPT反爬虫DEMO,更改key。这种作法简单,不容易被发现。可是能够经过有意爬取错误价格的方式来实现。

  3. 纯JAVASCRIPT反爬虫DEMO,更改动态key。这种方法可让更改key的代价变为0,所以代价更低。

  4. 纯JAVASCRIPT反爬虫DEMO,十分复杂的更改key。这种方法,可让对方很难分析,若是加了后续提到的浏览器检测,更难被爬取。

到此为止。

前面咱们提到了边际效应,就是说,能够到此为止了。后续再投入人力就得不偿失了。除非有专门的对手与你死磕。不过这个时候就是为了尊严而战,不是为了商业因素了。

浏览器检测

针对不一样的浏览器,咱们的检测方式是不同的。

  • IE 检测bug;

  • FF 检测对标准的严格程度;

  • Chrome 检测强大特性。

8、我抓到你了——而后该怎么办

不会引起生产事件——直接拦截

可能引起生产事件——给假数据(也叫投毒)

此外还有一些发散性的思路。例如是否是能够在响应里作SQL注入?毕竟是对方先动的手。不过这个问题法务没有给具体回复,也不容易和她解释。所以暂时只是设想而已。

一、技术压制

咱们都知道,DotA AI里有个de命令,当AI被击杀后,它获取经验的倍数会提高。所以,前期杀AI太多,AI会一身神装,没法击杀。

正确的作法是,压制对方等级,可是不击杀。反爬虫也是同样的,不要一开始就搞太过度,逼人家和你死磕。

二、心理战

挑衅、怜悯、嘲讽、猥琐。

以上略过不提,你们领会精神便可。

三、放水

这个多是是最高境界了。

程序员都不容易,作爬虫的尤为不容易。可怜可怜他们给他们一小口饭吃吧。没准过几天你就由于反爬虫作得好,改行作爬虫了。

好比,前一阵子就有人找我问我会不会作爬虫。。。。。我这么善良的人,能说不会吗????