写点什么

【媳妇当车模频道】汽车字体反爬一键解决,之家之家

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

    阅读完需:约 5 分钟

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


⛳️ 汽车 实战场景 之家

本次要采集的案例是字体反爬经典场景,而且是国内较早使用字体反爬的站点,字体反爬的学习可以反复琢磨这个站点。


这一次选择了一个养眼的频道进行采集,测试地址可以打开下述网址。


https://club.autohome.com.cn/bbs/thread/c0fa2ed11729f413/101926632-1.html#pvareaid=102410
复制代码


随机选择一段文字,找到其源码位置,可以看到源码中是无法直接读取到的,呈现的结果如下所示。



由前面的几篇博客铺垫,我们能很快抓取一个字体文件到本地进行分析。



这次的字体包中没有数字,妥妥的都是一些中文字符。

⛳️ 字体加密反爬编码时间

由于通过开发者工具查看字符都是下述符号 ,那只能通过 requests 模块进行一下数据的采集,查看代码情况。


import requestsfrom lxml import etree
headers = { "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36", "Referer": "https://club.autohome.com.cn"}
res = requests.get('https://club.autohome.com.cn/bbs/thread/c0fa2ed11729f413/101926632-1.html', headers=headers)
tree = etree.HTML(res.text)
ret = tree.xpath('//div[@class="tz-paragraph"]//text()')print(ret)
复制代码


运行代码得到下述结果集,其中出现了 unicode 编码就是我们后续解题的关键点了。



上文空缺出来的参数,如果对比查看就能找到规则。


  • \ude9e:一;

  • \ued4e:了;

  • ……


这些编码都可以转换为字体文件中的编码,我们尝试读取一下。


from fontTools.ttLib import TTFontimport io

file_woff = './fonts/wKgHGFsUz1OAZg_zAABj9FfA3vw19..ttf'with open(file_woff, 'rb') as font_file: font = TTFont(io.BytesIO(font_file.read())) # 转换成字体对象
print(font)

font_obj = font['cmap']

font_tables = font['cmap'].tablesuni_list = font['cmap'].tables[0].ttFont.getGlyphOrder()# ['.notdef', 'uniED4C', 'uniED9E', 'uniECEB', 'uniEC37', 'uniEC89', 'uniEDCA', 'uniEC28', 'uniED68', 'uniECB5', 'uniED07', 'uniEC53', 'uniED94', 'uniEDE6', 'uniED32', 'uniED84', 'uniECD1', 'uniEC1D', 'uniEC6F', 'uniEDB0', 'uniECFC', 'un# iED4E', 'uniEC9B', 'uniECED', 'uniEC39', 'uniED7A', 'uniEDCC', 'uniED18', 'uniEC65', 'uniECB7', 'uniEDF7', 'uniEC55', 'uniED96', 'uniECE2', 'uniED34', 'uniEC81', 'uniEDC1', 'uniEC1F', 'uniED60']print(uni_list)
复制代码


如果字体编码顺序一直没有发生变化,那本文已经建立对比字典之后,就解决了,但是之家站点每次刷新,字体文件的索引和顺序都发生了变化。



自然是变化的,那每次刷新页面的时候都 优先获取网页字体文件,然后在获取编码,二者得到之后,可以用 PIL 库将其绘制到一张图片中。


from fontTools.ttLib import TTFontfrom PIL import ImageFont, Image, ImageDraw


# 图片宽度和高度img_size = 512
font_img = ImageFont.truetype(file_woff, 300)
for cmap_code, glyph_name in font.getBestCmap().items(): # print(cmap_code,glyph_name)
# 实例化一个图片对象 img = Image.new('1', (img_size, img_size), 255)
# 绘制图片 draw = ImageDraw.Draw(img) # 将编码读取成字节 txt = chr(cmap_code)
x, y = draw.textsize(txt, font=font_img)
draw.text(((img_size - x) // 2, (img_size - y) // 2), txt, font=font_img, fill=0)
img.show()
复制代码


运行代码就会得到下图所示图片,有空白的文字图片,在对接一个简易的 OCR 识别模块,一个小小的动态字体反爬程序就完成了~



发布于: 3 小时前阅读数: 6
用户头像

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

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

评论

发布
暂无评论
【媳妇当车模频道】汽车字体反爬一键解决,之家之家_Python_梦想橡皮擦_InfoQ写作社区