问题:怎么将源代码中的加密字体正常显示?
当爬取数据时,经常会发现一些既不是想要的对应文字,也不是乱码。那么该网站是进行了字体加密的反爬虫。如何解决这一问题呢?
那么就会用到了我们的TTFont模块:
from fontTools.ttLib import TTFont
那么我们来看一下解决的流程,以实习僧网为例:
实习僧:https://www.shixiseng.com
1、获取网页源代码
url = "https://www.shixiseng.com/interns?keyword=python&city=%E5%85%A8%E5%9B%BD&type=intern"
headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.52"}
resp = requests.get(url,headers=headers)
print(resp.text)
找到加密的字体,如:
2、在网页中找到加密字体格式
通常在网页的(网络-字体-url)中,可直接转码下载。
下载后点击打开即可,这里会用到一个浏览文件的辅助性软件(High-Logic FontCreator),下载打开查看。
然后将文件放到pycharm中。
3、添加解密字体
找到相应文件(file),将数据进行手动整理至glyfmap字典中以用于读取。(数据不多手动整理即可,若编程能力底子厚可写一个程序自动提取内容,不过这个过程太麻烦0.0)。
font = TTFont("file")
glyf = font["glyf"]
glyfmap={
0: glyf['uni30'],
1: glyf['uni31'],
2: glyf['uni32'],
3: glyf['uni33'],
4: glyf['uni34'],
5: glyf['uni35'],
6: glyf['uni36'],
7: glyf['uni37'],
8: glyf['uni38'],
9: glyf['uni39'],
'p': glyf['uni70'],
'y': glyf['uni79'],
't': glyf['uni74'],
'h': glyf['uni68'],
'o': glyf['uni6f'],
'n': glyf['uni6e'],
'工': glyf['uni5DE5'],
'程': glyf['uni7A0B'],
'师': glyf['uni5E08'],
}
4、寻找对应关系
在这里观察到&#由0代替,运用.replace代替即可。
resp = requests.get(url,headers=headers)
response = resp.text.replace("&#",str(0))
- 读取解密字体
cont = font.getBestCmap()
- 遍历键和值,将键转化为十六进制。
- 将cont中的值转化为glyfmap中的值(赋值)。
name = glyf[name]
遍历glyfmap字典中的值,若其值与cont中的值相同,将源代码中的加密字体转换成解密后的字体。
for data,name in cont.items():
hex_data = hex(data)
print(hex_data)
name = glyf[name]
for data_new,name_new in glyfmap.items():
if name_new == name:
response = re.sub(hex_data,str(data_new),response)
- 打印后就可以看到解密好的字体了。
5、完整代码展示
import requests
from fontTools.ttLib import TTFont
import re
url = "https://www.shixiseng.com/interns?keyword=python&city=%E5%85%A8%E5%9B%BD&type=intern"
headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.52"}
# resp = requests.get(url,headers=headers)
# print(resp.text)
font = TTFont("file1")
glyf = font["glyf"]
glyfmap={
0: glyf['uni30'],
1: glyf['uni31'],
2: glyf['uni32'],
3: glyf['uni33'],
4: glyf['uni34'],
5: glyf['uni35'],
6: glyf['uni36'],
7: glyf['uni37'],
8: glyf['uni38'],
9: glyf['uni39'],
'p': glyf['uni70'],
'y': glyf['uni79'],
't': glyf['uni74'],
'h': glyf['uni68'],
'o': glyf['uni6f'],
'n': glyf['uni6e'],
'工': glyf['uni5DE5'],
'程': glyf['uni7A0B'],
'师': glyf['uni5E08'],
}
# 寻找对应关系
resp = requests.get(url,headers=headers)
response = resp.text.replace("&#",str(0))
# 读取解密字体
cont = font.getBestCmap()
for data,name in cont.items():
hex_data = hex(data)
print(hex_data)
name = glyf[name]
for data_new,name_new in glyfmap.items():
if name_new == name:
response = re.sub(hex_data,str(data_new),response)
print(response)
标签:加密,name,resp,headers,字体,解决,glyf,data From: https://www.cnblogs.com/LoLong/p/16916744.html