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

举报
梦想橡皮擦 发表于 2022/05/23 18:02:52 2022/05/23
【摘要】 📢📢📢📢📢📢💗 你正在阅读 【梦想橡皮擦】 的博客👍 阅读完毕,可以点点小手赞一下🌻 发现错误,直接评论区中指正吧📆 橡皮擦的第 664 篇原创博客 ⛳️ 汽车 实战场景 之家本次要采集的案例是字体反爬经典场景,而且是国内较早使用字体反爬的站点,字体反爬的学习可以反复琢磨这个站点。这一次选择了一个养眼的频道进行采集,测试地址可以打开下述网址。https://club.au...

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

⛳️ 汽车 实战场景 之家

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

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

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

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

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

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

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

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

import requests
from 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 TTFont
import 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'].tables
uni_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 TTFont
from 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 识别模块,一个小小的动态字体反爬程序就完成了~

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

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。