让前端飞iOS独立开发者

Web 端反爬虫技术方案

2018-08-10  本文已影响13人  杭城小刘

对于内容型的公司,数据的安全性很重要。对于内容公司来说,数据的重要性不言而喻。比如你一个做在线教育的平台,题目的数据很重要吧,但是被别人通过爬虫技术全部爬走了?如果核心竞争力都被拿走了,那就是凉凉。再比说有个独立开发者想抄袭你的产品,通过抓包和爬虫手段将你核心的数据拿走,然后短期内做个网站和 App,短期内成为你的劲敌。

爬虫手段

制定出Web 端反爬技术方案

本人从这2个角度(网页所见非所得、查接口请求没用)出发,制定了下面的反爬方案。

# 比如需要正确显示的数据为“19950220”

1. 先按照自己需求利用相应的规则(数字乱序映射,比如正常的0对应还是0,但是乱序就是 0 <-> 1,1 <-> 9,3 <-> 8,...)制作自定义字体(ttf)
2. 根据上面的乱序映射规律,求得到需要返回的数据 19950220 -> 17730220
3. 对于第一步得到的字符串,依次遍历每个字符,将每个字符根据按照线性变换(y=kx+b)。线性方程的系数和常数项是根据当前的日期计算得到的。比如当前的日期为“2018-07-24”,那么线性变换的 k 为 7,b 为 24。
4. 然后将变换后的每个字符串用“3.1415926”拼接返回给接口调用者。(为什么是3.1415926,因为对数字伪造反爬,所以拼接的文本肯定是数字的话不太会引起研究者的注意,但是数字长度太短会误伤正常的数据,所以用所熟悉的 Π)

​```
1773 -> “1*7+24” + “3.1415926” + “7*7+24” + “3.1415926” + “7*7+24” + “3.1415926” + “3*7+24” -> 313.1415926733.1415926733.141592645
02 -> "0*7+24" + "3.1415926" + "2*7+24" -> 243.141592638
20 -> "2*7+24" + "3.1415926" + "0*7+24" -> 383.141592624
​```

# 前端拿到数据后再解密,解密后根据自定义的字体 Render 页面
1. 先将拿到的字符串按照“3.1415926”拆分为数组
2. 对数组的每1个数据,按照“线性变换”(y=kx+b,k和b同样按照当前的日期求解得到),逆向求解到原本的值。
3. 将步骤2的的到的数据依次拼接,再根据 ttf 文件 Render 页面上。

下面以 Node.js 为例讲解后端需要做的事情

比如后端返回的是323.14743.14743.1446,根据我们约定的算法,可以的到结果为1773

反爬升级版

个人觉得如果一个前端经验丰富的爬虫开发者来说,上面的方案可能还是会存在被破解的可能,所以在之前的基础上做了升级版本

  1. 组合拳1: 字体文件不要固定,虽然请求的链接是同一个,但是根据当前的时间戳的最后一个数字取模,比如 Demo 中对4取模,有4种值 0、1、2、3。这4种值对应不同的字体文件,所以当爬虫绞尽脑汁爬到1种情况下的字体时,没想到再次请求,字体文件的规则变掉了 😂
  2. 组合拳2: 前面的规则是字体问题乱序,但是只是数字匹配打乱掉。比如 1 -> 4, 5 -> 8。接下来的套路就是每个数字对应一个 unicode 码 ,然后制作自己需要的字体,可以是 .ttf、.woff 等等。
网页检察元素得到的效果
接口返回数据

这几种组合拳打下来。对于一般的爬虫就放弃了。

反爬手段再升级

上面说的方法主要是针对数字做的反爬手段,如果要对汉字进行反爬怎么办?接下来提供几种方案

  1. 方案1: 对于你站点频率最高的词云,做一个汉字映射,也就是自定义字体文件,步骤跟数字一样。先将常用的汉字生成对应的 ttf 文件;根据下面提供的链接,将 ttf 文件转换为 svg 文件,然后在下面的“字体映射”链接点进去的网站上面选择前面生成的 svg 文件,将svg文件里面的每个汉字做个映射,也就是将汉字专为 unicode 码(注意这里的 unicode 码不要去在线直接生成,因为直接生成的东西也就是有规律的。我给的做法是先用网站生成,然后将得到的结果做个简单的变化,比如将“e342”转换为 “e231”);然后接口返回的数据按照我们的这个字体文件的规则反过去映射出来。

  2. 方案2: 将网站的重要字体,将 html 部分生成图片,这样子爬虫要识别到需要的内容成本就很高了,需要用到 OCR。效率也很低。所以可以拦截掉一部分的爬虫

  3. 方案3: 看到携程的技术分享“反爬的最高境界就是 Canvas 的指纹,原理是不同的机器不同的硬件对于 Canvas 画出的图总是存在像素级别的误差,因此我们判断当对于访问来说大量的 canvas 的指纹一致的话,则认为是爬虫,则可以封掉它”。

    本人将方案1实现到 Demo 中了。

关键步骤

  1. 先根据你们的产品找到常用的关键词,生成词云
  2. 根据词云,将每个字生成对应的 unicode 码
  3. 将词云包括的汉字做成一个字体库
  4. 将字体库 .ttf 做成 svg 格式,然后上传到 icomoon 制作自定义的字体,但是有规则,比如 “年” 对应的 unicode 码“\u5e74” ,但是我们需要做一个 恺撒加密 ,比如我们设置 偏移量 为1,那么经过恺撒加密 “年”对应的 unicode 码是“\u5e75” 。利用这种规则制作我们需要的字体库
  5. 在每次调用接口的时候服务端做的事情是:服务端封装某个方法,将数据经过方法判断是不是在词云中,如果是词云中的字符,利用规则(找到汉字对应的 unicode 码,再根据凯撒加密,设置对应的偏移量,Demo 中为1,将每个汉字加密处理)加密处理后返回数据
  6. 客户端做的事情:
    • 先引入我们前面制作好的汉字字体库
    • 调用接口拿到数据,显示到对应的 Dom 节点上
    • 如果是汉字文本,我们将对应节点的 css 类设置成汉字类,该类对应的 font-family 是我们上面引入的汉字字体库
//style.css
@font-face {
  font-family: "NumberFont";
  src: url('http://127.0.0.1:8080/Util/analysis');
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

@font-face {
  font-family: "CharacterFont";
  src: url('http://127.0.0.1:8080/Util/map');
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h2 {
  font-family: "NumberFont";
}

h3,a{
  font-family: "CharacterFont";
}
接口效果
审查元素效果

传送门

字体制作的步骤ttf转svg字体映射规则

实现的效果

  1. 页面上看到的数据跟审查元素看到的结果不一致
  2. 去查看接口数据跟审核元素和界面看到的三者不一致
  3. 页面每次刷新之前得出的结果更不一致
  4. 对于数字和汉字的处理手段都不一致

这几种组合拳打下来。对于一般的爬虫就放弃了。

数字反爬-网页显示效果、审查元素、接口结果情况1
数字反爬-网页显示效果、审查元素、接口结果情况2
数字反爬-网页显示效果、审查元素、接口结果情况3
数字反爬-网页显示效果、审查元素、接口结果情况4
汉字反爬-网页显示效果、审查元素、接口结果情况1
汉字反爬-网页显示效果、审查元素、接口结果情况2

前面的 ttf 转 svg 网站当 ttf 文件太大会限制转换,让你购买,下面贴出个新的链接。

ttf转svg

Demo 地址

效果演示

运行步骤

//客户端。先查看本机 ip 在 Demo/Spider-develop/Solution/Solution1.js 和 Demo/Spider-develop/Solution/Solution2.js  里面将接口地址修改为本机 ip

$ cd Demo
$ ls
REST        Spider-release  file-Server.js
Spider-develop  Util        rule.json
$ node file-Server.js 
Server is runnig at http://127.0.0.1:8080/

//服务端 先安装依赖
$ cd REST/
$ npm install
$ node app.js 
上一篇 下一篇

猜你喜欢

热点阅读