破解字体反爬

743 阅读6分钟

最近听旁边几个开发都在聊买车的事情,于是到汽车之家的论坛踩了一踩....基于程序员的惯性,顺溜的就摁下了F12,就看到了这?这岂不是做了字体反爬的手段嘛,于是故事就开始了。

第一步

首先,我们需要获取到整体的文章数据

  • 发送请求
  • 接收数据
  • 解析数据
import requests 
from lxml import etree  

# 构建url
url = "https://club.autohome.com.cn/bbs/thread/665330b6c7146767/80787515-1.html"

# 构建请求头
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"}

# 发送请求,获取响应
res = requests.get(url=url,headers=headers)

# 获取的网页源码(html)
res_html = res.text

# 使用xpath 解析数据
html = etree.HTML(res_html)
content_list = html.xpath('//div[@class="tz-paragraph"]//text()')
print(content_list)

打印结果是

['从新款大G发布的', '\uedff', '瞬间,当时给我第', '\uedff', '时间的感觉,我就已经深深的爱上了,我觉', '\ued83', '大G是每', '\uedff', '个男人梦,而我也同样的不会例外,所以说在选车方面,我也有过', '\uedff', '些矛盾,毕竟在200W左', '\uec5d', '可以选择的余地太', '\uec25', '了,比如宾利,还有添越,都可以选择,在年轻的时候实在是开够了轿车,从宝马7系,到现在的GLS,当你开上越野车的时候,就再也不想开轿车,后来想', '\uedff', '想比较也已经30', ....  '\uec25', ',也不能总当水军了,我要去霍霍大波浪小姐姐了']

从输出结果,我们可以发现,其中有一些编码,但是先将这个问题放一边。

第二步

我们先来看如何将这个列表里面的元素拼接成一个文本字符串,使用str.join(iterable)即可

content_str = "".join(content_list)
print(content_str)

-----------------------------------------------------------------------------------------------------
'从新款大G发布的\uedff瞬间,当时给我第\uedff时间的感觉,我就已经深深的爱上了,我觉\ued83大G是每\uedff个男人梦,而我也同样的不会例外,所以说在选车方面,我也有过\uedff些矛盾,毕竟在200W左\uec5d可以选择的余地太\uec25了,比如宾利,还有添越,都可以选择,在年轻的时候实在是开够了轿车,从宝马7系,到现在的GLS,当你开上越野车的时候,就再也不想开轿车,后来想\uedff想比较也已经30\uec25岁了,也应该原自己的\uedff个梦想啦,儿时的老爷车,方方正正的,实在是太喜欢这个火柴盒啦,最终还是决定\ued22手。再决定\ued22手大G的期间跑过了几次4S店,没车!没车!没车!或者就是让我再等等,我这个人的性格就是什么\uec89,喜欢的必须要\ued83到,我也不去考虑后期会降价啊,我个人觉\ued83早买就是早享受,买车不就是赔钱的嘛,谁让咱们自己喜欢\uec89。买车经历:我买的是美规版的G550,63也实在上不到,落地要300\uec25,还是有点实力不允许啊,我的车走的是外商自带手续,据我了解第\uedff批都是外商自带手续的车,还没有那种合格证的手续,毕竟\ued3c急嘛,我这面就是用国外的人进口带回来的车,完了在给我过户,如果不\ued3c急的话也可以等那种叫3C手续的,那样可以直接去当地车管所上牌,省\ued3c像我这种过户的麻烦,因为我之前在天津港提过\uedff台GLS,当时也买的\ued8c顺利,销售也是当时在GLS论坛的红人:天津大壮,这次买车还是选择在他这提的,这俩次提车都\ued8c满意,让人该赚的,主要靠谱就行,也省去被骗的风险。目前我的车开了2000\uec25公里,目前我开\ued3c还是特别的舒服,宽阔的视野,至于油耗嘛,高速上大概16个左\uec5d,要是内区的话差不\uec2520个,还有就是550声浪不像63那么大,也比较舒服,毕竟也不年轻了嘛,比较有科技感的大宽屏幕,还有就是新款的G后排空间比老款的舒服太\uec25了,座椅方面比老款的舒服\ued8c\uec25,我个人觉\ued83老款的G后排坐\ued3c特别的硬,新款的没有这个现象了,目前各个方面都特别的满意,要是非说点缺点,我就是觉\ued83高速上风噪有些大,做工也略微的粗糙些。废话也不\uec25说了,我觉\ued83是不是应该上大片了,周末带上自己的单反拍了\uedff些照片,\uecd0不\uecd0,凑合看吧。这个是提车当天拍了几张保税区,还有天津标志性的建筑物,手机拍摄,我个人也觉\ued83挺漂亮接\ued22来就是大片来袭啦,高清无码来袭!接\ued22来是内饰篇啦,做\uecd0准备喽。网上最近最火的\uedff句话,渣男开大G,渣女奔驰E,\uecd0了,就写怎么\uec25把,感谢汽车之家对我提车的帮助了\ued8c\uec25,也不能总当水军了,我要去霍霍大波浪小姐姐了'

第三步

现在我们来看重点问题,就是如何破解字体反爬。实际上字体反爬的意思就是:通过调用自定义的ttf文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码。

到底是不是呢?首先,我们需要找到网站自定义的ttf文件

  • 看到前端标签,对于字体的相关样式:myfont

  • 查看网页源代码,搜索myfont

  • 将该链接在新的窗口打开,下载该ttf文件

  • 使用 百度字体平台,发现编码与字体是一一对应的。

第四步

记下来,我们就需要将获取到字体中的编码一一替换成对应的汉字

  • 构建编码列表
  • 构建对应汉字列表
  • 编码与字一一替换
from fontTools.ttLib import TTFont

# 使该文件可以打开-->保存为.xml文件
font = TTFont("wKgHFVsUz1eAH_VRAABj9PS-ubk57..ttf")
font.saveXML("fonts.xml")

# 获取所有字体对应的name的列表
uniList = font.getGlyphOrder()

"""
uniEDFF-->'\uedff'  字符串处理成对应unicode编码
1.除第一个以外每一个都需处理-->for循环取出除第一个以外的元素
2.uniEDFF-->'\uedff'
3.添加到新的列表中
"""
uni_list = []
for i in uniList[1:]:
    # eval函数将去掉字符串的两个引号,保留原意
    i = eval(r"'\u"+i[3:]+"'")  
 
    # 将处理好的i添加到uni_list中
    uni_list.append(i)

# 对应字体列表,前端以坐标形式呈现
word_list = ['很', '五', '多', '远', '大', '十', '更', '了', '的', '矮', '不', '少', '九', '三', '八', '一', '右', '坏', '近', '着', '呢', '左', '是', '长', '六', '上', '短', '七', '高', '二', '得', '好', '下', '和', '四', '地', '小', '低']

#怎么替换字符串当中的 编码 对应 的 字
for i in range(len(uni_list)):
    # 对应位置的编码 替换为 对应位置的字 比如:\ued8c 替换成 很
    content_str = content_str.replace(uni_list[i],word_list[i]) # 字符串不可变的特性

print(content_str)

文章持续更新,可以微信搜索「极客夜读 」第一时间阅读,更多Python学习文章,大家的关注就是更新的动力!