一、调试
发现字体是加密的,猜测是自定义字体。
二、WTF woff?
woff是一种网页采用的字体格式标准,……
查看页面源代码,确认是woff加密
三、绕过
①获取woff文件
随便选择一个标签,发现使用的是PingFangSC-Regular字体,全局搜索这个字体的来源,
发现是由font-face引入。在这个css文件中引入了几个woff文件,把这几个woff文件全部保存下来。共有3个
②如何与汉字映射?
有两种办法可以查看woff文件,一是百度在线字体编辑,二是fontcreator软件。
打开如图:
貌似没有什么逻辑可言。
接下来:
使用Python的fontTools库处理woff文件,处理成xml文件。
查看两个id为2的name,发现name不一样
向下搜索name,
虽然两者的name不一样,但是字形数据却是完全一样的。
这两个name虽然不一致,但是描述的字体却是一个。所以我就断了以name作为key的念头(网站前端换套字体,key就失效了)。
以字形数据作为key,又因为key太长,所以以字形数据的MD5作为key,如下示例
{'62124eeb7f1b3026dbc49ab0e0a60309': {'name': {'unie73e', 'uniebc7', 'unif29f'}, 'value': '糕'}}
key有了,如何获取对应的汉字呢?
#把字体绘制成图片
font = TTFont(path)
font.saveXML('ztiku.xml')
code_list = font.getGlyphOrder()[2:]
im = Image.new("RGB", (1800, 1000), (255, 255, 255))
dr = ImageDraw.Draw(im)
font = ImageFont.truetype(path, 40)
count = 15
array_list = numpy.array_split(code_list, count)
for t in range(count):
new_list = [i.replace("uni", "\\u") for i in array_list[t]]
text = "".join(new_list)
text = text.encode('utf-8').decode('unicode_escape')
dr.text((0, 50 * t), text, font=font, fill="#000000")
im.save("tmp.jpg")
图片如下:
字体的识别可以使用OCR识别,或调用腾讯、百度……api。我使用的是手机文字提取。
提取结果如下:
1234567890店中美家馆小车大市公酒行国品发电金心业商司超生装园场食有新限天面工服海华水房饰城乐汽香部利子老艺花专东肉菜学福饭人百餐茶务通味所山区门药银农龙停尚安广鑫一容动南具源兴鲜记时机烤文康信果阳理锅宝达地儿衣特产西批坊州牛佳化五米修爱北养卖建材三会鸡室红站德王光名丽油院堂烧江社合星货型村自科快便日民营和活童明器烟育宾精屋经居庄石顺林尔县手厅销用好客火雅盛体旅之鞋辣作粉包楼校鱼平彩上吧保永万物教吃设医正造丰健点汤网庆技斯洗料配汇木缘加麻联卫川泰色世方寓风幼羊烫来高厂兰阿贝皮全女拉成云维贸道术运都口博河瑞宏京际路祥青镇厨培力惠连马鸿钢训影甲助窗布富牌头四多妆吉苑沙恒隆春干饼氏里二管诚制售嘉长轩杂副清计黄讯太鸭号街交与叉附近层旁对巷栋环省桥湖段乡厦府铺内侧元购前幢滨处向座下県凤港开关景泉塘放昌线湾政步宁解白田町溪十八古双胜本单同九迎第台玉锦底后七斜期武岭松角纪朝峰六振珠局岗洲横边济井办汉代临弄团外塔杨铁浦字年岛陵原梅进荣友虹央桂沿事津凯莲丁秀柳集紫旗张谷的是不了很还个也这我就在以可到错没去过感次要比觉看得说常真们但最喜哈么别位能较境非为欢然他挺着价那意种想出员两推做排实分间甜度起满给热完格荐喝等其再几只现朋候样直而买于般豆量选奶打每评少算又因情找些份置适什蛋师气你姐棒试总定啊足级整带虾如态且尝主话强当更板知已无酸让入啦式笑赞片酱差像提队走嫩才刚午接重串回晚微周值费性桌拍跟块调糕
接下来就是构建映射关系:
def get_mapping():
with open('load.css', 'r') as f:
css = f.read()
with open('word.txt', 'r', encoding='utf-8') as f:
word = f.read()
mapping = {}
woff_link = re.findall(re.compile(r',url\("(.*)\.woff"\);'), css) # 提取css中的所有woff
woff_link = ['https:' + i + '.woff' for i in list(set(woff_link))]
for i in range(len(woff_link)):
res = requests.get(woff_link[i])
with open(f'{i}.woff', 'wb') as f:
f.write(res.content)
font = TTFont(f'{i}.woff')
content = font.getGlyphOrder()[2:] # 前两个无效
for j in range(len(content)):
md5_value = hashlib.md5(font['glyf'].glyphs.get(content[j]).data).hexdigest()
if md5_value not in mapping:
mapping[md5_value] = {'name': {content[j]}, 'value': word[j]} #以set作为name的value
else:
mapping[md5_value]['name'].add(content[j])
return mapping
接下来是测试时间:
def get_value(i, mapping):
for k, v in mapping.items():
if i in v['name']:
return v['value']
return i
def process(mapping):
with open('dazhongdianping.json', 'r', encoding='utf-8') as f:
info = json.loads(f.read())
test_str = info['reviewAllDOList'][0]['reviewDataVO']['reviewBody']
#test_str:今<svgmtsi class="review"></svgmtsi>带母<svgmtsi class="review"></svgmtsi>大<svgmtsi class="review"></svgmtsi>去吃早<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>板,实际<svgmtsi class="review"></svgmtsi>在<svgmtsi class="review"></svgmtsi>年<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>吃过了,当时对红米肠<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>鹅惊<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>。这次<svgmtsi class="review"></svgmtsi>本<svgmtsi class="review"></svgmtsi>很担心<svgmtsi class="review"></svgmtsi>胯……<br />[薄荷]<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>:虽然南宁现在<svgmtsi class="review"></svgmtsi>档食肆不少,<svgmtsi class="review"></svgmtsi>金悦<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>称<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>面大<svgmtsi class="review"></svgmtsi>,尤<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>洗手间<svgmtsi class="review"></svgmtsi>感应<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>龙头<svgmtsi class="review"></svgmtsi>暖水,牙签<svgmtsi class="review"></svgmtsi>带牙缝刷,算<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>细节讲究了。<br />[<svgmtsi class="review"></svgmtsi>务铃]<svgmtsi class="review"></svgmtsi>务:<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>一周订<svgmtsi class="review"></svgmtsi>,今<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>钟到,在<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>等了一<svgmtsi class="review"></svgmtsi>儿,<svgmtsi class="review"></svgmtsi>务<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>贴周到。等<svgmtsi class="review"></svgmtsi>时<svgmtsi class="review"></svgmtsi>动<svgmtsi class="review"></svgmtsi>供<svgmtsi class="review"></svgmtsi>水;电梯有<svgmtsi class="review"></svgmtsi>帮按<svgmtsi class="review"></svgmtsi>;点菜<svgmtsi class="review"></svgmtsi>根据<svgmtsi class="review"></svgmtsi>数<svgmtsi class="review"></svgmtsi>醒菜量;<svgmtsi class="review"></svgmtsi>菜快;烤乳鸽有帮切<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>件;粥<svgmtsi class="review"></svgmtsi>有<svgmtsi class="review"></svgmtsi>帮<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>份;打包帮装<svgmtsi class="review"></svgmtsi>,打包盒<svgmtsi class="review"></svgmtsi>袋子<svgmtsi class="review"></svgmtsi>有酒店logo。<br />菜品味道均在水准以<svgmtsi class="review"></svgmtsi>,吃<svgmtsi class="review"></svgmtsi>出<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>自制<svgmtsi class="review"></svgmtsi>不<svgmtsi class="review"></svgmtsi>冷冻<svgmtsi class="review"></svgmtsi>品。比如灌汤包<svgmtsi class="review"></svgmtsi>薄汁多,即使<svgmtsi class="review"></svgmtsi>褶子处趁热吃<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>软<svgmtsi class="review"></svgmtsi>,灌汤鲜甜不腻。咸水<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>薄,炸<svgmtsi class="review"></svgmtsi>通透,内里自然有空腔,馅料有虾米<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>味。<svgmtsi class="review"></svgmtsi>值<svgmtsi class="review"></svgmtsi>推<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>「<svgmtsi class="review"></svgmtsi>鹅」<svgmtsi class="review"></svgmtsi>「马<svgmtsi class="review"></svgmtsi>糕」。<svgmtsi class="review"></svgmtsi>鹅<svgmtsi class="review"></svgmtsi>道地<svgmtsi class="review"></svgmtsi>三肥七瘦,炭火逼出大部<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>脂后留一<svgmtsi class="review"></svgmtsi>不厚<svgmtsi class="review"></svgmtsi>看<svgmtsi class="review"></svgmtsi>到<svgmtsi class="review"></svgmtsi>脂肪,鹅<svgmtsi class="review"></svgmtsi>瘦<svgmtsi class="review"></svgmtsi>不柴,淋<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>鹅汁,脆<svgmtsi class="review"></svgmtsi>加<svgmtsi class="review"></svgmtsi>脂<svgmtsi class="review"></svgmtsi>,辅以鹅<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>丰腴及汁水<svgmtsi class="review"></svgmtsi>咸<svgmtsi class="review"></svgmtsi>,令<svgmtsi class="review"></svgmtsi>回味[调<svgmtsi class="review"></svgmtsi>]。马<svgmtsi class="review"></svgmtsi>糕<svgmtsi class="review"></svgmtsi>发<svgmtsi class="review"></svgmtsi>甜,像<svgmtsi class="review"></svgmtsi>式<svgmtsi class="review"></svgmtsi>戚<svgmtsi class="review"></svgmtsi>,<svgmtsi class="review"></svgmtsi>红糖<svgmtsi class="review"></svgmtsi>焦甜味更有<svgmtsi class="review"></svgmtsi>次感。<br /><svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>母<svgmtsi class="review"></svgmtsi>大<svgmtsi class="review"></svgmtsi>吃<svgmtsi class="review"></svgmtsi>很满<svgmtsi class="review"></svgmtsi>,<svgmtsi class="review"></svgmtsi><svgmtsi class="review"></svgmtsi>稍嫌小贵[囧]。
res = re.sub('<svgmtsi class=\\"review\\">', '', test_str)
res = re.sub(';</svgmtsi>', '', res)
res = re.sub('<.*?>', '', res)
res = res.replace('&#x', 'uni')
wait_replace = re.findall(re.compile(r'uni[0-9a-z]{4}'), res)
for i in wait_replace:
res = res.replace(i, get_value(i, mapping))
return res
if __name__ == '__main__':
mapping = get_mapping()
res = process(mapping)
print(res)
res: