支付宝字体反爬

支付宝字体解码

支付宝余额的字体是自定义的字体库,CSS3支持自定义字体。

转为字体文件

获取到的JSON文件:

1
{"success":true,"result":{"balanceAmountStr":"<span class=\"df-integer home-mfund-d53498\">&#xe07f;&#xe39c;&#xe013;&#xe4ce;<span class=\"df-decimal\">.&#xe409;&#xe07f;</span></span>元","fontContent":{"value":"d4+MRoAAAB4nGNgYgCD/80MRgwYIDyYgQEALegCYQA=","contentType":"DATA_BASE64","fontFormat":"woff","fontStyle":"home-mfund-d53498"}},"token":"A0fGyRY1NzWaEq4KBAEBCGt1eSUMD82M"}

Value可以BASE64后存为字体文件

1
2
3
4
5
fontdata = base64.b64decode(response_all)
with open('source.otf', 'wb')as f:
f.write(fontdata)
f.close()

注: OTF和WOFF均为字体文件,有的WOFF文件需要先转为OTF才行,Python的开源库woff2otf可以做到。https://github.com/hanikesn/woff2otf

打开字体

Windows下可以用Font Creator软件打开。打开后可以看到每个Unicode对应的Num是多少。观察可以发现,每个数字其实是矢量图。

对比

这里的OTF字体文件可以通过fontTools库来进行解析,但支付宝的解析不到CODE,所以要先转为XML文件。

1
2
source_font = TTFont('source.otf')
source_font.saveXML('source_xml')

解析成XML文件后,可以看到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.33">
<GlyphOrder>
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
<GlyphID id="0" name="glyph00000"/>
···
</GlyphOrder>
<cmap>
<tableVersion version="0"/>
<cmap_format_4 platformID="3" platEncID="1" language="0">
<map code="0xe013" name="glyph00001"/><!-- ???? -->
<map code="0xe045" name="glyph00007"/><!-- ???? -->
<map code="0xe07f" name="glyph00006"/><!-- ???? -->
<map code="0xe2b8" name="glyph00004"/><!-- ???? -->
<map code="0xe39c" name="glyph00002"/><!-- ???? -->
<map code="0xe3cf" name="glyph00008"/><!-- ???? -->
<map code="0xe409" name="glyph00009"/><!-- ???? -->
<map code="0xe4ce" name="glyph00003"/><!-- ???? -->
<map code="0xe59b" name="glyph00005"/><!-- ???? -->
<map code="0xe5f1" name="glyph00010"/><!-- ???? -->
</cmap_format_4>

由此可以看到 Unicode对应的是第几个数字,用软件打开后看到第几位的数字为什么,由此可以得到Unicode对应的Num。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
base_dict = {'glyph00001': 1, 'glyph00002': 6, 'glyph00003': 7, 'glyph00004': 3, 'glyph00005': 5,
'glyph00006': 8, 'glyph00007': 2, 'glyph00008': 9, 'glyph00009': 4, 'glyph00010': 0}
bs=BeautifulSoup(data,'lxml')
cmap=bs.find('cmap')
# cmap_format_4=cmap.find('cmap_format_4')
map=cmap.find_all('map')
code_dict={}
for i in map:
code=i['code'][1:]
glyph=i['name']
num=base_dict[glyph]
code_dict[code]=num
code_dict=json.dumps(code_dict)
print(code_dict)

然后就可以解析出来JSON文件中Unicode对应的金额数字了。

知乎猫眼字体爬取
字体反爬
猫眼字体反爬