首先需要获取动态字体,第七题的字体文件在接口返回值里面
import base64
from io import BytesIO
from bs4 import BeautifulSoup
import requests
from fontTools.ttLib import TTFont # pip install fonttools
headers = {
'User-Agent': 'yuanrenxue.project'
}
res = requests.get(f'http://match.yuanrenxue.com/api/match/7?page=1', headers=headers)
data = res.json()
data_list = data["data"]
# print(data_list)
woff = data["woff"]
with open("7.woff", "wb") as f:
f.write(base64.b64decode(woff))
font = TTFont("7.woff")
font.saveXML("7x.xml")
打开字体xml文件,多次测试之后发现,这个字体文件也是动态的,但是glyf
对应的一直是0-9之间的数字,注意:对应顺序是动态的
但是on
对应的这一列一直是不变的
glyf = font.getGlyphSet()
glyf_name = font.getGlyphNames()
on_dict = {}
for index, name in enumerate(glyf_name[1:]):
# 读取 glyf 表, 获取各字形对应的 on 值
on_data = font['glyf'][name].flags
# 字符串拼接
on_key = "".join([str(n) for n in on_data])
# 组合字典
on_dict[on_key] = name
print(on_dict)
可以得到如下对应关系:
整理之后:
old_map = {'10100100100101010010010010': 'unia146',
'111111111111111': 'unia396',
'10010101001110101011010101010101000100100': 'unia426',
'101010101101010001010101101010101010010010010101001000010': 'unia618',
'100110101001010101011110101000': 'unia928',
'1111111': 'unib387',
'10101100101000111100010101011010100101010100': 'unib542',
'1110101001001010110101010100101011111': 'unic368',
'1001101111': 'unic472',
'10101010100001010111010101101010010101000': 'unic832'
}
这里注意的是,key不变,变的是value,但value代表的数字是不变的,如
'1111111': 'unib387'
'1111111': 'unib173'
实际上都是数字7:
'1111111': 7
'1111111': 7
可以使用: 字体处理工具,查看字体文件里面的对应关系
完整代码:
import base64
from io import BytesIO
from bs4 import BeautifulSoup
import requests
from fontTools.ttLib import TTFont # pip install fonttools
headers = {
'User-Agent': 'yuanrenxue.project'
}
new_map = {
'111': '',
'10100100100101010010010010': '0',
'1001101111': '1',
'100110101001010101011110101000': '2',
'10101100101000111100010101011010100101010100': '3',
'111111111111111': '4',
'1110101001001010110101010100101011111': '5',
'10101010100001010111010101101010010101000': '6',
'1111111': '7',
'101010101101010001010101101010101010010010010101001000010': '8',
'10010101001110101011010101010101000100100': '9'
}
name_list = ['极镀ギ紬荕', '爷灬霸气傀儡', '梦战苍穹', '傲世哥', 'мaη肆風聲', '一刀メ隔世', '横刀メ绝杀', 'Q不死你R死你',
'魔帝殤邪', '封刀不再战', '倾城孤狼', '戎马江湖',
'狂得像风', '影之哀伤', '謸氕づ独尊', '傲视狂杀',
'追风之梦', '枭雄在世', '傲视之巅', '黑夜刺客', '占你心为王', '爷来取你狗命', '御风踏血', '凫矢暮城',
'孤影メ残刀', '野区霸王', '噬血啸月', '风逝无迹', '帅的睡不着', '血色杀戮者', '冷视天下', '帅出新高度',
'風狆瑬蒗', '灵魂禁锢', 'ヤ地狱篮枫ゞ', '溅血メ破天', '剑尊メ杀戮', '塞外う飛龍', '哥‘K纯帅',
'逆風祈雨',
'恣意踏江山', '望断、天涯路', '地獄惡灵', '疯狂メ孽杀', '寂月灭影', '骚年霸称帝王', '狂杀メ无赦',
'死灵的哀伤',
'撩妹界扛把子', '霸刀☆藐视天下', '潇洒又能打', '狂卩龙灬巅丷峰', '羁旅天涯.', '南宫沐风', '风恋绝尘',
'剑下孤魂', '一蓑烟雨', '领域★倾战', '威龙丶断魂神狙', '辉煌战绩', '屎来运赚', '伱、Bu够档次',
'九音引魂箫',
'骨子里的傲气', '霸海断长空', '没枪也很狂', '死魂★之灵']
values = {}
for index in range(1, 6):
res = requests.get(f'https://match.yuanrenxue.cn/api/match/7?page={index}', headers=headers)
data = res.json()
# 用二进制流的方式保存字体文件
# font_bytes = BytesIO(base64.b64decode((data.get("woff")).encode()))
# font = TTFont(font_bytes)
with BytesIO(base64.b64decode((data.get("woff")).encode())) as font_web_bytes:
font = TTFont(font_web_bytes)
with BytesIO() as font_local_bytes:
font.saveXML(font_local_bytes) # 保存成xml格式的文件到二进制流(内存中)
# 获取字体文件的二进制数据 font_local_bytes.getvalue()
ids = BeautifulSoup(font_local_bytes.getvalue(), 'xml').find('glyf').find_all('TTGlyph')
# 映射数字关系
gid = {}
for g in ids:
gid[g['name']] = new_map[''.join(b['on'] for b in g.find_all('pt'))]
# {'.notdef': '', 'unia139': '1', 'unia249': '6', 'unib485': '9', 'unib752': '0', 'unib792': '4', 'unib812': '2', 'unib856': '5', 'unib935': '7', 'unic165': '8', 'unic586': '3'}
for i, d in enumerate(data['data']):
values[name_list[i + 1 + (index - 1) * 10]] = int(
''.join(gid[dd.replace('&#x', 'uni')] for dd in d['value'].strip().split(' ')))
print(max(values, key=lambda v: values[v]))
参考学习链接:
https://blog.youkuaiyun.com/Yy_Rose/article/details/126704652
https://blog.youkuaiyun.com/user_from_future/article/details/130259277