持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情
⛳️ 实战场景
本次字体反爬的目标场景是:乐居,地址如下所示:
https://house.leju.com/as/new/#wt_source=pc_csss_mf_zxlp
以上页面是随机打开的,你可以选择自己的城市进行测试。
使用开发者工具,先找到对应的数字,查看是否所见即所得。
很明显的一个字体反爬,数字由 8733 转变为 7100 ,既然已经发现是数字产生了变化,那接下来的事情就非常容易了。
我们抓取一下字体文件,查看其内部具体包含哪些字体编码。
结果发现字体文件竟然是已字节流形式写到了前台,这样我们后续获取字体文件,就转变成了字节读取与解析。
通过工具查看字体文件之后,发现除字体外,还存在一些中文字符被替换的情况,我们在页面实测一下。
测试之后,中文字符在列表页未启用,估计在其它页面,这里不做过多探究。
查看字体文件是否一致
捕获多次刷新数据,得到下图内容。
对比结果之后,可以了解到中文字符的编码无变化,仅数字产生变化,但是数字对应的英文又是确定的,这里其实已经解决了该案例。
⛳️ 乐居实战场景
字体文件的解析,参考我们 Python 爬虫 120 例子中的其它博客即可,本文仅对字体文件的爬取做解析。
import requests
import io
from lxml import etree
import base64
from fontTools.ttLib import TTFont
detail_url = 'https://house.leju.com/as/new/#wt_source=pc_csss_mf_zxlp'
res = requests.get(detail_url)
tree = etree.HTML(res.text)
style = tree.xpath("//style/text()")
font_face = style[0]
font_char = font_face.split("src: url(data:font/truetype;charset=utf-8;base64,")[1].split(") format('woff');")[0]
# print(font_char)
# 转换为字体文件
font_file_io = base64.b64decode(font_char)
print(type(font_file_io))
# 加载字体二进制流
font = TTFont(io.BytesIO(font_file_io))
print(font)
# 测试一下字体文件
font_map = font['cmap'].getBestCmap()
print(font_map)
运行代码的输出如下所示。
此时问题已经成功解决。
@[toc]
⛳️ 易 实战场景 车
本次字体反爬案例对应的是【易Python脱敏车】点评频道,该站点使用了字体反爬技术,并且是中文字符反爬,可以重点研究下。
站点地址如下所示(全角字符)
https://dianping.yiche.com/
打开目标站点任意链接之后,可以通过开发者工具发现,其文字部分存在大量的混淆字符。
既然已经发现了字体混淆,那接下来我们再夯实一下字符矢量图相关知识,下载易车的一个字体文件。
字体文件是通过 unicode 编码,然后对应字体文件。
浏览器实现原理是通过传递字符的字节码,转换成 unicode 编号,然后在字体文件中找到字体矢量图,如果没有字体文件,会在系统自带的字体中寻找矢量图。
上图中 uni6211 对应的就是汉字 我 的编码。
⛳️ 易 实战编码 车
有了多篇字体反爬的经验,我们很容易发现本次的目标站点使用了固定的字体文件,名称为 yc-ft.woff
,其中包含了 473 个特殊汉字。
接下来只需要将字体文件编码和汉字的对一个关系读取出来即可。
from fontTools.ttLib import TTFont
font = TTFont('fonts/yc-ft.woff')
print(font)
font_map = font['cmap'].getBestCmap()
print(font_map)
网页响应的源码格式如下所示:
<em class="iconfont"></em>车也
其中 
就是对应的字符,然后 e3d0
对应到字体矢量图中,对应的是 提 字。
📢📢📢📢📢📢 💗 你正在阅读 【梦想橡皮擦】 的博客 👍 阅读完毕,可以点点小手赞一下 🌻 发现错误,直接评论区中指正吧 📆 橡皮擦的第 673 篇原创博客