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

如~家 web字体映射解决

作者: 朝朝朝朝朝落 | 来源:发表于2022-08-10 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