字体反爬之猫眼电影

虽然每个woff文件字体的顺序和字体的unicode值不同,但是同一个数字的字体笔画是相同的。
根据这个不变的关系,我们可以构造两个映射关系(unicode–>字体笔画,字体笔画–>真实数字),最终可以获得真实的票房价格。

阅读步骤

  • 效果演示
  • 思路整体
  • 项目地址
  • 关键函数
  • 总结

效果演示

在这里插入图片描述

思路整体

  • 字体的笔画
    <TTGlyph name="uniF754" xMin="0" yMin="0" xMax="511" yMax="707">
      <contour>
        <pt x="47" y="622" on="1"/>
        <pt x="47" y="707" on="1"/>
        ...
        <pt x="398" y="622" on="1"/>
      </contour>
      <instructions/>
    </TTGlyph>
  • 失败的思路

一开始我想的是把woff文件中的字体按照坐标绘制出来,然后通过ocr识别。这样做的好处是如果字体数量很多,直接调用ocr会节省很大的人力成本。而且不用关心字体顺序改变或者字体映射关系改变带来的影响。
但是由于自身技能的限制最终失败了。有兴趣的大佬可以指导下小弟。

  • 成功的思路

经过多次测试发现猫眼电影虽然每次请求可能会返回不同的字体文件,但是同一个数字的笔画(contour)是不变的。
因此我们可以先用一个默认的字体文件,找到数字与笔画的映射关系,然后再同猫眼电影返回的字体笔画对比,这样就能找到正确的数字。字体关系如下

FONTS={
    'path':'static/fonts/9d91f36ccaab7f2398cfc7bdd93300b82076.woff',
    'font_map':{
        'uniF754':7,
        'uniEA82':6,
        'uniEA38':0,
        'uniEFE6':3,
        'uniE132':9,
        'uniF2A2':4,
        'uniE1B4':1,
        'uniF753':8,
        'uniE381':5,
        'uniF0FF':2
    }
}

项目地址

猫眼电影

关键函数

  • 虽然每个woff文件的字体顺序和unicode值不一样,但是同一个字体的笔画是一样的,按照这个思路我们可以写一个数字与笔画的映射关系,然后就能通过其他woff的字体找到具体的数字了。
  • 字体与笔画的映射函数
    def parser_contour(self, font_xml):
        for k, v in self.font_map.items():
            try:
                element = font_xml.xpath('//TTGlyph[@name="{}"]'.format(k))[0]
                contours=[lxml.html.tostring(e).decode('utf-8').strip() for e in element.xpath('./contour/pt')]
                self.contour_to_font[md5(json.dumps(contours))]=v
            except Exception:
                raise Exception('{}字体改版,请重新更新settings中的配置,key:{},val:{}'.format(self.path,k,v))
  • unicode与笔画的映射函数
    def parser_map(self, font_xml):
        for element in font_xml.xpath('//TTGlyph'):
            try:
                name = ''.join(element.xpath('@name')[0])
                contours = [lxml.html.tostring(e).decode('utf-8').strip() for e in element.xpath('./contour/pt')]
                self.uni_to_contour[name.upper()] = md5(json.dumps(contours))
            except Exception as e:
                raise Exception('{}字体改版,请重新更新settings中的配置,error:{}'.format(self.path, e))

总结

  • 字体反爬的关键是找到映射关系,而这个映射关系最好是稳定的。
  • 对于woff文件来说,不变的是字体的笔画。
发布了33 篇原创文章 · 获赞 21 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u013356254/article/details/89707587