美文网首页
如~家 web字体映射解决

如~家 web字体映射解决

作者: 朝朝朝朝朝落 | 来源:发表于2022-08-09 18:46 被阅读0次
WX20220810-184212.png

采集web客房数据,遇到如下问题:
价格和咱们想要的各种字段全部是"&#x。。。。
id='8dc0da944fce4151997b817ff0c8bf69'>"这样的看似乱码的串


WX20220808-185131.png

先想到了混淆,猜想一个码对应一个数字或汉字,实际上汉字确实一一对应一个码,数字是好几个对应1个,无法确定有多少个,手动找肯定不行,


WX20220808-190529@2x.png

各种调试也无济于事,发现network有个这样一项,引起我的注意:


WX20220808-190352.png

我用的Chrome,那就打开最后一个url:


WX20220808-191616@2x.png

发现uni后面的4位和网页的&#x后4位相似,搜索我手动对的都能找到,但是还是一头雾水,看看woff,svg,ttf,是啥玩意:


WX20220808-191836@2x.png WX20220808-191854@2x.png WX20220808-191905@2x.png

百度后大概明白了是字体映射,核心是.woff文件,下载之,打开它(http://font.qqe2.com/
和我手动的能对上几个:

WX20220808-193010@2x.png

我们看到每个下面有一行1个unixxxx,上面是一堆$xxxx...,先找到unixxxx:用fontTools(pip install fontTools),我还发现.woff这个url会变,所以要先获取这个url:

from fontTools.ttLib import TTFont
headers = {
    'authority': 'www.bthhotels.com',
    'accept': 'text/css,*/*;q=0.1',
    'accept-language': 'zh-CN,zh;q=0.9',
    'cache-control': 'no-cache',
    'pragma': 'no-cache',
    'referer': 'https://www.bthhotels.com/hotel/0210Q2?beginDate=2022-08-05&endDate=2022-08-06',
    'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"macOS"',
    'sec-fetch-dest': 'style',
    'sec-fetch-mode': 'no-cors',
    'sec-fetch-site': 'same-origin',
    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36',
}

response = requests.get('https://www.bthhotels.com/ajax/getpricestyle', headers=headers)
text=response.text
woff_url=re.findall('url..(https://images.bthhotels.com/PriceImg/Iconfont/.*?.woff).. format', text)[0]

woff_path = 'tmp.woff'
f = urllib.request.urlopen(woff_url)
data = f.read()
with open(woff_path, "wb") as code:
    code.write(data)

font = TTFont('tmp.woff')
font.saveXML('tmp2.xml')

看一下.xml文件:


WX20220808-194254@2x.png WX20220808-194411@2x.png

然后找到每个$xxxx:

#必须先首次全部对应上这些(实际对应的是字形参数),后面.woff url变了,但每个字符形状不变,用这些参数去对应变化后的url的码,听不懂没关系,直接copy能run就行
base_font = TTFont('/Users/kongdechao/Downloads/91d11e23e6ad47ec.woff') 
base_num_list = ['`','.',2,0,8,9,6,1,7,3,4,5]
base_unicode_list = ['x','uniE520','uniF7AA','uniF2D3','uniF1FD','uniE3F6','uniF4B6',
                     'uniF8AF','uniEBF3','uniF106','uniE896','uniEC83',]

# font = TTFont('f6cd52acc25945f2.woff')

unicode_list = font['cmap'].tables[0].ttFont.getGlyphOrder()
nu_list = []
 #新woff 数字list
for i in range(1, 13):
    glyph = font['glyf'][unicode_list[i]]
    for j in range(12):
        base_glyph = base_font['glyf'][base_unicode_list[j]]
        if glyph == base_glyph:
            nu_list.append(base_num_list[j])
            break
#所有对应的 uni
with open('tmp.xml',) as f:
    text=f.read() 
d_uni={}
unicode_list=[i for i in unicode_list if '0000' not in i]
for i in unicode_list:
    uni=re.findall(f'<map code=.(.*?). name=\"{i}\"/>', text)
    uni=list(set(uni))
    for j in uni:
        j=j.replace('0x','').upper()
        d_uni[j]=base_num_list[unicode_list.index(i)]
WX20220809-100614@2x.png

第二天,果然.woff变了,试下代码,没问题:

WX20220809-095305@2x.png

检查一下


WX20220809-142405@2x.png

还有,response里的汉字都变成了&#x。。。这是障眼法,不是css映射,只要如此这般就行了

    
from html.parser import HTMLParser

def uni_(s):
    h = HTMLParser()
    s=h.unescape(s)
    return s
WX20220810-184037.png

相关文章

网友评论

      本文标题:如~家 web字体映射解决

      本文链接:https://www.haomeiwen.com/subject/iizwwrtx.html