web项目乱码_数据反爬之web字体应用

f64ad9c2f3c9908e5cb356f8bee6b7bd.gif

互联网医院研发部-柴进

前言

提起web字体前端工程师应该都比较熟悉,通过它可以实现UI视觉稿中的特殊字体,让页面文字展示更加的个性化。而对于后端工程师来说web字体还有其他应用场景:数据安全领域的反数据爬取(后续简称“反爬”)

实例分析

我们以猫眼电影PC端电影票价格为例,获取某部影片的相关影院信息如下图所示,乍看起来与普通页面并没什么区别。

44b0161c7972261af70996d6d15d0ef4.png

通过F12打开审查元素的界面就能发现并不像看起来那样简单,定位元素发现价格「38」是类似「口口」的乱码而不是数字。

baaea1603f9879b355b466238d6560f2.png

为什么页面显示的内容与审查元素时完全不同呢?

带着这个疑问我们直接查看一下页面源代码,观察下HTML中价格数据会有什么变化。

341cc9c55861a098f93656e05a5bfaaa.png

查看源码我们发现价格「38」变成了类似乱码的字符「」,这到底是什么呢?

查阅相关资料我们了解到这其实是HTML、XML等标准通用标记语言(SGML)的转义序列,严格意义上来说并不是一种「编码」格式。通常以[]开头[;]结尾,用来表示字符值的引用(Numeric characterreference,简称NCR)。以[]开头后接十进制数字,以[]开头后接十六进制数字,数字取值为目标字符集Unicodecode point

从HTML 4开始,NCR以Unicode为准,并且与HTML文档编码格式无关。举个例子:「中国」二字的 Unicode 字符为「U+4E2D」和「U+56FD」,换算成十进制为「20013」和「22269」,而十六进制为「4E2D」和「56FD」,在HTML中用NCR十六进制表示则为「中」和「国」。

猫眼电影通过NCR的方式将「38」转换为十六进制符号「」,浏览器获取页面后渲染成「38」。但这只能解释源码中的NCR字符,而无法解释在页面上显示的是「38」,审查元素时却是「口口」。

6832f42ac8ccd6f7f9caacf8e8ae7afb.png

在审查元素时我们发现价格元素有个「.stonefont」类名,并且「font-family」属性为「stonefont」字体,这显然不是常规字体。通过点击类名对应的「cinemas?mov_=1217023」文件,我们发现「stonefont」是「@font-face」自定义的字体,配置了对应的字体文件

978ad1660972b5272d1a4d69905dff1a.png

到这里我们就找到了答案,浏览器获取含有NCR格式数据的HTML文档,通过CSS的方式将文档中的「」转换并渲染成「38」。

为了验证假设,我们下载「@font-face」中的woff格式的字体文件,并用字体工具「FontCreator」打开检查,正如前面所说E31A代表3,EA9F代表8。

98fedb1adbce56ad77cab7422b970a26.png

以上就是猫眼电影针对价格反爬的实现方案,通过web字体文件与NCR字符映射的方式来实现数据的安全加密,并达到看到与下载内容不一致的效果,从而实现数据安全的目的,接下来让我们回到后端开发。

方案梳理

我们来思考下如何搭建一套这样的系统?经过前文的铺垫,我们对需要做的事情应该有了大致的了解,前端展示上至少需要两部分内容:

1、字体文件。

2、与字体文件对应的NCR字符串。

如何制作字体文件?字体文件是什么样子的?我们用python提供的类库fontTools将woff的字体文件解析成XML格式,由于解析后的文件内容较多,我们仅挑选关键部分来说明。

e6845e205bc33544940897005438c434.png

这部分内容描述了字体文件在画布上相关联的点坐标,name属性就是该文字的映射编码,后面的属性xMin,yMin,xMax,yMax是描述画布作用域的x轴与y轴最小值、最大值的坐标点,contour标记了具体的像素点的集合。

e883e42f196780a8305c8b6533e94746.png

我们可通过修改name值来做到动态的改变文字与编码的映射关系,也可以通过微调pt标签的x和y属性来改变文字的形状。至此我们就完成了字体文件的生成,同时我们也得到了文字与NCR字符的映射关系。

将生成的字体文件以及对应的NCR映射关系同步给前端,前端需要替换「@font-face」中的字体文件,最终完成页面内容的动态反爬处理,实现维护项目数据安全的目的。

小结

文章最后让我们来回顾一下整体反爬方案的实现流程:

b90ed19a2d152e38e026c2f491c3a6a7.png

当用户发起获取带有价格数据的请求时,前端获取带有NCR数据的HTML的同时,去获取字体文件。后端收到请求后,将初始文本数据用NCR编码替换后返回给前端,再给前端返回对应字体文件。前端根据字体文件渲染对应的文字样式,最终用户看到对应的页面内容。

    至此我们初步完成了字体反爬的后端实现,后续还有很多可以优化的内容,由于篇幅有限就不做赘述了,感兴趣的同学可以随时关注相关内容的更新。

731a47eb5d19073b144286d3d0aa66cf.png

  • 一起学习nginx(二)

  • 堆排序及其应用

  • 一起学习nginx(一)

  • Vue项目开发入过的坑

  • 京东互医架构解耦设计的思考

  • 从无到有-打造页面监控系统

daa6079bf7eaccf2eb658498c2b1721c.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值