HTML防数据采集

1,162 阅读4分钟

什么是防采集

就是我们想利用爬虫工具采集某个网站的数据(前提当然是公开合法数据),但网站不想给你采集而设置的技术阻挡措施。

常见的防止采集方案

  • 利用输入验证码框验证,在采集某些网站过程中,要求你输入验证码,否则就卡住进行不下去。这是网站最常用且最基础的防采措施之一,它要求你必须你手动输入验证码里的数字和字母,才能继续看到更多信息或者进行下一步,以此来判断你是机器人还是真人。
  • 滑动图片进行拼图验证,它要求你必须滑动拼图到它指定的位置,才能通过验证进行下一步操作。
  • 登录验证,这类网站通常需要登录才能看到更丰富的信息,否则只会展现非常有限的内容。
  • 数据加密防采集,我们在网页上看到的内容是真实的,但我们打开源代码看,这段文字被已经被加密分离,这样当我们用爬虫工具进行数据采集时,所采集下来的数据就是各种乱码,法整合成一段完整的文字。
  • 反馈虚假数据,这种防止采集的方案是把虚假的数据传递给爬虫工具,从而防止数据被采集。
  • 禁止访问网页,主要还是看网站的防采机制设计,如果触发了,通常的结果就是全面封锁和禁止。比如封你的账号、封你的IP地址。一旦被封锁,网站会自动给你错误页面或无法让你正常浏览。

如何利用HTML和自定义字体(web-font)来实现数据防采集

web-font是CSS3中的一种标记 @font-face,在@font-face声明里,你可以声明一种字体,指定这种字体字体库文件从网络某个地址下载或直接引用本地的自定义字体文件。例如在css中做如下声明:

@font-face {
	font-family: "icomoon";
	src: url("fonts/icomoon.woff") format("woff"),
	url("fonts/icomoon.ttf") format("truetype"),
	url("fonts/icomoon.eot") format("embedded-opentype"),
	url("fonts/icomoon.svg") format("svg");
}

这样就成功引入了icomoon这个自定义字体。

防采集原理:

使用web-font可以从网络加载字体,因此我们可以自己创建一套字体,设置自定义的字符映射关系表。 例如设置1f345是映射字符9,1f371是映射字符2,以此类推。 当需要显示字符9时,网页的源码只会是1f345,被采集的也只会是1f345,并不是9,使采集者采集不到正确的数据。而对于正常访问的用户则没有影响。对于中文的防采集不适合使用web-font这种方法,因为中文的字体库太大。而对于数字,英文则适合使用此方法实现防采集。

实例流程:

1.创建指定字符的自定义字体 首先选择一款字体(免费且不受版权影响的字体),下载好字体可以去FONTEK这个网站快捷转格式上传ttf文件,点击下方的生成,将字体文件转为svg格式。 制作svg.png 2.选择需要使用的字符及设置字体映射关系 打开网址:icomoon,选择左上角“import icons”上传刚刚生成的svg字体,然后选择要加密的字符进行加密,这里我选择0-9数字进行加密,选择完成后点击右下角Generate Font按钮。 选择加密字符.png 修改映射.png

把名字也按映射关系修改,设置映射关系后,点击右下角download下载字体。然后将字体文件放到项目中,并在css中声明引入的字体。

@font-face {
	font-family: "icomoon";
	src: url("fonts/icomoon.woff") format("woff"),
			 url("fonts/icomoon.ttf") format("truetype"),
			 url("fonts/icomoon.eot") format("embedded-opentype"),
			 url("fonts/icomoon.svg") format("svg");
}

然后需要定义一个css的class,font-family使用这个web-font

.number{
	font-family: icomoon;
}

然后根据之前修改的映射表在HTML中使用各自数字对应的映射如下

<div class="number">
	&#x1f345 &#x1f371 &#x1f30f &#x1f3c6
</div>

完整HTML代码如下:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title></title>
	<style type="text/css">
          @font-face {
              font-family: "icomoon";
              src: url("fonts/icomoon.woff") format("woff"),
              url("fonts/icomoon.ttf") format("truetype"),
              url("fonts/icomoon.eot") format("embedded-opentype"),
              url("fonts/icomoon.svg") format("svg");
          }
          .number{
              font-family: icomoon !important;
          }
	</style>
	</head>
	<body>
		<div class="number">
			&#x1f345 &#x1f371 &#x1f30f &#x1f3c6
		</div>
	</body>
</html>

运行结果如下: 加密结果.png 采集者只能获取到类似&#x1f345的数据,并不能知道&#x1f345映射的字符是什么,实现了数据防采集。当然采集者可以通过分析,知道每一个映射代表的意思,从而进行采集后转换处理。 我们可以创建多个不同的字体文件和映射表。每次访问都随机使用一种,并定期更新一批字体文件和映射表,加大采集的难度。 这样采集者需要把所有的字体文件和映射表都分析并做转换处理,才可能采集到数据,这样采集的成本将会大大增加。(这里前端所展示的数据一般都是从后端接口获取的,所以可以把映射关系放到后端进行处理,前端只负责展示编码即可)