前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >字体反爬之汽车之家

字体反爬之汽车之家

作者头像
老肥码码码
发布2020-01-17 11:22:21
1.4K0
发布2020-01-17 11:22:21
举报
文章被收录于专栏:算法与数据之美

前几天我们说到这个猫眼的字体反爬,其自定义字体定义的都是数字,而今天我们要尝试破解的是汽车之家的汉字字体反爬,现在就来一探究竟吧!

可以看到其中的“更”字在查看元素的时候显示为小框,可见这就是该网站的一种反爬措施了。

我们先找其自定义字体文件,我们在网页源代码中搜索font-face,就能够在其中有该文件的链接。

这是一个ttf文件,我们采用FontCreator软件来观察。字体文件导入之后的效果如下:

如果每个页面都是相同的自定义字体文件,那我们可以直接构造映射并完成对字体的反反爬。现实果然很残酷,每个不同的页面都有不同的字体文件,但是幸运的是,每个字体文件包含的汉字数目和类型是完全相同的。再打开一个网页上的字体文件来观察。

只是变换了name而已,那岂不是跟猫眼的数字字体反爬一模一样了吗。

我们利用fontTools,把这两个字体文件给存储为xml来看看这个字体对象是如何定义的吧~我们以“右”这个字为例,

是不是能找到一些规律呢?同一汉字的对象是不相同的,但是区别是微小的,对象中每个坐标的差值较小,这样我们可以通过限定对象的坐标值差值在一定范围内就可以认为是两个相同的汉字了。

下面是判断字体对象是否表示同一个字的比较函数:

代码语言:javascript
复制
def compare(c1,c2):
    """
    输入:某俩个对象字体的坐标列表
    输出:bool类型,True则可视为是同一个字
    """
    if len(c1)!=len(c2):
        return False
    else:
        for i in range(len(c1)):
            if abs(c1[i][0]-c2[i][0])<50 and abs(c1[i][1]-c2[i][1])<50:
                pass
            else:
                return False
        return True

然后,利用相同的思路,下载新的ttf字体文件,将其与先有的base.ttf文件进行比较,若两个name表示相同的汉字,则构造新的字典,并将网页中的&#xecc3; 等字样根据新的字典变换成汉字。具体代码如下:

代码语言:javascript
复制
def decrypt_font(font1,font2,response):
    """
    输入:base字体,新字体以及网页源代码
    输出:字体解密后的网页源代码
    """
    word_list=['九','呢','着','地','得','的','五','六','低','右','一','二','远','更','了','好','三','多','小','长','是','坏','十','近','少','八','很','四','短','上','七','下','不','和','高','左','矮','大']
    uniname_list1=['uniEC1F', 'uniEC21', 'uniEC39', 'uniEC3B', 'uniEC55', 'uniEC67', 'uniEC71', 'uniEC81', 'uniEC82', 'uniEC8B', 'uniEC9D', 'uniECAE', 'uniECB7', 'uniECB8', 'uniECD3', 'uniECE4', 'uniECED', 'uniECFE', 'uniED00', 'uniED09', 'uniED18', 'uniED1A', 'uniED34', 'uniED36', 'uniED46', 'uniED50', 'uniED61', 'uniED6A', 'uniED7C', 'uniED96', 'uniED97', 'uniEDB2', 'uniEDC3', 'uniEDCC', 'uniEDCD', 'uniEDDD', 'uniEDE8', 'uniEDF9']
    uniname_list2=font2.getGlyphNames()[1:]
    base_dict=dict(zip(uniname_list1,word_list))
    
    # 保存每个字符的坐标信息,分别存入coordinate_list1和coordinate_list2
    coordinate_list1=[]     
    for uniname in uniname_list1:
        # 获取字体对象的横纵坐标信息
        coordinate=font1['glyf'][uniname].coordinates 
        coordinate_list1.append(list(coordinate))

    coordinate_list2=[]
    for i in uniname_list2:
        coordinate=font2['glyf'][i].coordinates
        coordinate_list2.append(list(coordinate))

    index2=-1
    new_dict={}
    for name2 in coordinate_list2:
        index2+=1
        index1=-1
        for name1 in coordinate_list1:           
            index1+=1
            if compare(name1,name2):
                new_dict[uniname_list2[index2]]=base_dict[uniname_list1[index1]]
                
    for uniname in uniname_list2:
        pattern='&#x'+uniname[3:].lower()+';'
        response=re.sub(pattern,new_dict[uniname],response)
    return response

其中word_list和uniname_list1是通过FontCreator软件一一对应记录下来的,即构造了一个base字典,作为参照。

通过之前几篇JS解密、app抓包和字体反爬,我们可以看到,在分析网页分析代码的时候需要利用好多种多样的工具来帮助我们完成所要信息的爬取。选对工具,才能事半功倍~

喜欢就点个赞吧❤

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法与数据之美 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档