当前位置:网站首页>字体反爬之好租
字体反爬之好租
2022-08-01 11:31:00 【tslilove】
声明
本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!
采集需求:

当然你可以再进行详情页,这里主要研究学习为主
主页:aHR0cHM6Ly94dWFuemhpLjU4LmNvbS8=
目标列表页:aHR0cHM6Ly94dWFuemhpLjU4LmNvbS9iai9ob3VzZS1saXN0Lw==
我们下面进行抓包看看,发现部分数字被加密了,呈现为一种方框的形式,有经验的小朋友一看就知道是字体反爬,对应源码中以&#x开头的字符串
我们接着看请求字体包,我们发现,该font-woff字体文件是经过Base64编码以后的字符串,我们在网页搜索一下woff,正是在网页源码中,这一步,我们可通过获取页面源码得到字体编码字符串
通过多次测试,发现字体不是静态的一套字体,将字体编码转换为woff字体
def new_save_font(page,text):
font_encryptData = text
binData = base64.decodebytes(font_encryptData.encode())
with open(f'./woff/{page}.woff', 'wb') as f:
f.write(binData)
f.close()
return f'./woff/{page}'
先通过在线网站查看(https://font.qqe2.com/),可以证实,对应数字的编码字符是不一样的,这样我们就不能固定一套字体来进行映射

当然你也可以通过fontTools.ttLib import的类方法TTFont,将woff字体保存为xml文件,方便我们查看比对
from fontTools.ttLib import TTFont
font = TTFont('./woff/1.woff')
font.saveXML('./woff/font1.xml')
font = TTFont('./woff/2.woff')
font.saveXML('./woff/font2.xml')
然后我们获取一下字体的坐标数据,绘制出字体图,这里以数字8为例
#导入matplotlib图表库
import matplotlib.pyplot as plt
#字体坐标,这里均为数字8
GlyphCoordinates1 = [(181, 371),(71, 412),(56, 521),(71, 603),(128, 656),(198, 710),(282, 710),(362, 710),(421, 647),(495, 596),(495, 507),(495, 412),(386, 371),(462, 344),(489, 300),(524, 251),(524, 184),(524, 88),(391, -39),(283, -25),(174, -39),(110, 25),(42, 86),(42, 186),(42, 257),(114, 354),(163, 509),(163, 470),(200, 439),(230, 414),(284, 406),(331, 406),(369, 439),(402, 470),(402, 567),(334, 635),(229, 635),(163, 570),(163, 524),(134, 186),(134, 146),(169, 75),(207, 55),(242, 35),(284, 21),(316, 35),(343, 46),(372, 57),(390, 77),(432, 117),(432, 248),(376, 301),(346, 332),(217, 332),(179, 290),(134, 249),(134, 198)]
GlyphCoordinates2 = [(193, 371),(71, 412),(71, 521),(71, 603),(185, 710),(378, 710),(495, 596),(495, 519),(509, 412),(386, 371),(454, 345),(524, 251),(524, 184),(524, 88),(458, 11),(391, -39),(174, -39),(108, 25),(42, 86),(42, 186),(37, 257),(78, 301),(114, 354),(181, 357),(163, 524),(163, 470),(197, 439),(223, 406),(284, 413),(333, 406),(369, 439),(402, 470),(402, 519),(398, 567),(354, 601),(334, 635),(229, 635),(197, 603),(163, 576),(148, 524),(134, 186),(134, 159),(152, 111),(169, 75),(207, 55),(242, 35),(284, 35),(316, 35),(369, 57),(390, 81),(432, 116),(432, 183),(432, 235),(389, 290),(346, 332),(281, 332),(204, 332),(179, 290),(134, 249)]
def makeFontChart(a1,a2):
#plot1
x1 = [i[0] for i in a1]
y1 = [i[1] for i in a1]
plt.subplot(1,2,1)
plt.scatter(x1, y1)
plt.plot(x1,y1)
plt.title("font1")
#plot2
x2 = [i[0] for i in a2]
y2 = [i[1] for i in a2]
plt.subplot(1,2,2)
plt.scatter(x2, y2)
plt.plot(x2,y2)
plt.title("font2")
plt.show()
makeFontChart(GlyphCoordinates1,GlyphCoordinates2)
可见,虽然字体的坐标不同,但是确实是同一个字

那既然字体是动态的,有没有一些什么好的方案么?答案是有的,有很多博主采用坐标差值到一定阈值内,就视为同一个字,但本文采用K近邻算法进行训练,预测每个出每个字体,关于K近邻算法,网上有很多教程,这里不做过多赘述。
KNN训练算法:
def _knn():
# 处理缺失值
imputer = SimpleImputer(missing_values=np.nan, strategy='mean')
data = pd.DataFrame(imputer.fit_transform(pd.DataFrame(get_font_data())))
# 取出特征值\目标值
x = data.drop([0], axis=1)
y = data[0]
# 分割数据集
# x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
x_train = x.head(40)
y_train = y.head(40)
# x_test = x.tail(10)
# y_test = y.tail(10)
# 标准化
# std = StandardScaler()
# x_train = std.fit_transform(x_train)
# x_test = std.transform(x_test)
# 进行算法流程
knn = KNeighborsClassifier(n_neighbors=1)
# 开始训练
knn.fit(x_train, y_train)
return knn,x.shape[1]
# 预测结果
# y_predict = knn.predict(x_test)
# print(y_test,y_predict)
# 得出准确率
# print(knn.score(x_test, y_test))
下面就是进行实战获取环节,刷新网页

获取前两页,发现我网页的一致


总结:当遇到站点字体是动态字体时,我们就不能只考虑固定的字体编码映射,尝试 K近邻算法进行训练,预测来达到实时映射的目的!

边栏推荐
猜你喜欢
【倒计时5天】探索音画质量提升背后的秘密,千元大礼等你来拿
Jenkins安装插件遇到的问题
语音聊天app源码——语音聊天派对
Stone Technology builds hard-core brand power and continues to expand the global market
【likeshop】回收租凭系统100%开源无加密 商城+回收+租赁
redis6 跟着b站尚硅谷学习
各位大拿,安装Solaris 11.4操作系统,在安装数据库依赖包的时候包这个错,目前无原厂支持,也无安装盘,联网下载后报这个错,请教怎么解决?
华硕和微星多款产品将升级英特尔Arc A380和A310显卡
解决vscode输入! 无法快捷生成骨架(新版vscode快速生成骨架的三种方法)
基于ArkUI eTS开发的坚果食谱(NutRecipes)
随机推荐
万字解析:vector类
Envoy source code flow chart
如何获取微信视频号的地址(微信公众号的链接地址)
Kaitian aPaaS mobile phone number empty number detection [Kaitian aPaaS battle]
腾讯云原生:Areaki Mesh 在 2022 冬奥会视频直播应用中的服务网格实践
基于ArkUI eTS开发的坚果食谱(NutRecipes)
redis6 跟着b站尚硅谷学习
利用正则表达式的回溯实现绕过
R语言诊断ARIMA模型:forecast包构建了一个ARIMA模型、使用checkresiduals函数诊断ARIMA模型、并进行结果解读(拟合较差的ARIMA模型具有的特点)
Excel表格打印时不打印标记填充颜色
表连接详解
pandas connects to the oracle database and pulls the data in the table into the dataframe, filters all the data from the current time (sysdate) to one hour ago (filters the range data of one hour)
The difference between undefined and null in JS
[CLion] CLion always prompts "This file does not belong to any project target xxx" solution
SCHEMA解惑
R语言ggplot2可视化:使用ggpubr包的ggscatter函数可视化散点图、使用xscale函数指定X轴坐标轴度量调整方式、设置x轴坐标为scientific使用科学计数法显示坐标值
C#/VB.NET 将PPT或PPTX转换为图像
pandas连接oracle数据库并拉取表中数据到dataframe中、筛选当前时间(sysdate)到一个小时之前的所有数据(筛选一个小时的范围数据)
Data frame and remote frame of CAN communication
音视频技术开发周刊 | 256