写点什么

【字体反爬】目标站点 5Lq65Lq66L2m(Base64 加密),Python 反爬系列再次更新

作者:梦想橡皮擦
  • 2022 年 7 月 22 日
  • 本文字数:1662 字

    阅读完需:约 5 分钟

📢📢📢📢📢📢💗 你正在阅读 【梦想橡皮擦】 的博客👍 阅读完毕,可以点点小手赞一下🌻 发现错误,直接评论区中指正吧📆 橡皮擦的第 <font color=red>661</font> 篇原创博客


Python 爬虫实战场景,人

本次要采集的站点是 double 人车,目标站点如下所示:


d3d3LnJlbnJlbmNoZS5jb20=/cn/dazhong/?plog_id=6aa04cde5309dd233f85bd47a996c423
复制代码


域名使用的是 base64 加密


该站点也是字体反爬经典案例,其呈现不是以乱码形式展现,而是源码差异,具体如下图所示。



可以看到 2020 在源码中为 5050380390 ,非常有趣的一种字体反爬手段。


检查其 css 样式,发现下图字体设置。



切换到网络视图,抓取字体请求,得到如下内容,又是一个 woff 字体文件,在文件名上右键,然后在来源面板打开,可以预览字体内容。




可以看到最下面的数字顺序是混乱的。



得到这个逻辑之后,就可以通过字体文件进行替换操作了。

⛳️ 实战编码,人

随机下载一个字体文件到本地,然后打开之后,查看编码,使用的工具是 FontCreator,打开之后,可以看到索引和文字的对应关系如下。



0 对应的是 zero ,其余的字体对应关系都发生了变化,这也是后续我们解决该字体加密的核心逻辑。


而且在实测中发现字体文件只有第一次网页加载时,才会重新下载,后续都是直接从缓存读取,这就给了我们偷懒的机会。



接下来我们重点解决一下字体加密部分代码。


获取网页字体类名


import requestsfrom lxml import etreeres = requests.get('https://d3d3LnJlbnJlbmNoZS5jb20=/cn/dazhong/?plog_id=6aa04cde5309dd233f85bd47a996c423')els = etree.HTML(res.text)class_name = els.xpath('//h3/@class')[0]
复制代码


通过 class_name 获取字体文件的二进制流。


在获取字体文件的时候,先判断一下本地文件夹中是否存在该文件,如果有,直接使用即可。


import requestsfrom lxml import etree
from fontTools.ttLib import TTFontimport ioimport os
res = requests.get('https://d3d3LnJlbnJlbmNoZS5jb20=/cn/dazhong/?plog_id=6aa04cde5309dd233f85bd47a996c423')els = etree.HTML(res.text)class_name = els.xpath('//h3/@class')[0]
# 本地保存文件file_woff = './tmp/renPython脱敏处理_font/{0}.woff'.format(class_name)if not os.path.exists(os.path.dirname(file_woff)): os.makedirs(os.path.dirname(file_woff))
url = 'https://misc.rrcimg.com/ttf/{0}.woff'.format(class_name)resp = requests.get(url)
# 判断文件是否存在,不存在创建if not os.path.exists(file_woff): print("创建文件") with open(file_woff, 'wb') as f: f.write(resp.content)
# 读取文件with open(file_woff, 'rb') as font_file: font = TTFont(io.BytesIO(font_file.read())) # 转换成字体对象
print(font)
# 获取 cmapfont_obj = font['cmap']# 获取 cmap tablefont_tables = font['cmap'].tablesuni_list = font['cmap'].tables[0].ttFont.getGlyphOrder()
print(uni_list)
复制代码


此时得到如下内容:


['.notdef', 'zero', 'four', 'five', 'three', 'seven', 'one', 'two', 'six', 'nine', 'eight']
复制代码


找到字体文件的对应关系,编写对应的转换,这里我们直接复制一段网站文本进行测试。


替换前:本田-凌派 5048款 490Turbo CVT豪华版替换后:本田-凌派 2019款 180Turbo CVT豪华版
复制代码


接下来核心逻辑会写在代码中,可以边看边学习。



# 将英文替换为数字cn_num_list = [eng_list[_] for _ in uni_list]print(cn_num_list) # 转换后的正确数字顺序
# 将数字对应关系生成zip_num_list = dict(zip(cn_num_list, num_list))print(zip_num_list)
# 假设读取到的文本是 本田-凌派 5048款 490Turbo CVT豪华版input_txt = '本田-凌派 5048款 490Turbo CVT豪华版'print("转换前",input_txt)# 文本进行转换,当字符是数字时transfor_str = [_ if not _.isdigit() else zip_num_list[_] for _ in input_txt]print("转换后",''.join(transfor_str))
复制代码


<kbd>



</kbd>

宣传时间

📣📣📣📣📣📣右下角有个大拇指,点赞的漂亮加倍


发布于: 1 小时前阅读数: 10
用户头像

爬虫 100 例作者,蓝桥签约作者,博客专家 2021.02.06 加入

6 年产品经理+教学经验,3 年互联网项目管理经验; 互联网资深爱好者; 沉迷各种技术无法自拔,导致年龄被困在 25 岁; CSDN 爬虫 100 例作者。 个人公众号“梦想橡皮擦”。

评论

发布
暂无评论
【字体反爬】目标站点5Lq65Lq66L2m(Base64加密),Python反爬系列再次更新_Python_梦想橡皮擦_InfoQ写作社区