字体文件混淆是常见反爬手段,我这里指的是使用1份或多份网站自定义字体(通常是woff),导致爬下来的字符编码不能解析,即所见非所得。
1、例子
比如大众点评,选哪儿,网站自定义了woff文件字体,前端展示的文字与代码不对应,如下面村字:
2、解决思路
1、首先,不会有一个网站会真的自己设计一种字体(如果有可以手打对照表),一般都是将现有的字体进行位置调换形成一份新的字体。所以,第一步就是要找到这份字体的源字体。
2、找到源字体之后,将其解析出来字的点坐标。将点坐标和对应的文字做成一个字典,坐标为key
,暂时叫做base_font_dict
。
3、每次爬取之前,先根据情况下载当前的字体文件(有的网站隔3天更新,但是同一页面使用3种不同字体,有的则会每一个页面的字体不一样)。然后对下载的字体文件也做类似第2步的解析,也可以得到每个字的点坐标和被混淆过的混淆编码
。
4、紧跟着第3步,用每一个字体的坐标从base_font_dict
找到对应的文字,以混淆编码
为key
,和对应的文字做成一个dict,暂时叫做woff_font_dict
。
5、最后,在爬取过程使用混淆编码
从woff_font_dict
找到对应的文字。
3、工具
1、查找网站混淆编码
的源字体,可以用‘What The Font’ Chrome浏览器插件,注意要看被混淆的文字周围的字体,不过一般都是雅黑。
2、字体编辑器 ‘High-Logic FontCreator’,就可以查看字体究竟是什么样的,下图:
3、字体编辑包‘fontTools’,用于将字体文件解析成xml文件。然后用‘BeautifulSoup’提取坐标文件,坐标提取出来画图是这样的:
4、代码
以下是处理字体文件的代码:
from fontTools.ttLib.ttFont import TTFont
import re
from bs4 import BeautifulSoup
import requests
# 抽取每一个字的坐标点信息
def takeXY(points):
pts = points.find_all('pt')
x = []
y = []
for pt in pts:
x.append(re.findall('x="(.*?)"', str(pt