当前位置:网站首页>字体反爬之好租
字体反爬之好租
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近邻算法进行训练,预测来达到实时映射的目的!

边栏推荐
- 4种常见的鉴权方式及说明
- 【公开课预告】:超分辨率技术在视频画质增强领域的研究与应用
- RK3399 platform development series on introduction to (kernel) 1.52, printk function analysis - the function call will be closed
- Data frame and remote frame of CAN communication
- 力扣解法汇总1374-生成每种字符都是奇数个的字符串
- R语言ggplot2可视化:使用ggpubr包的ggdensity函数可视化密度图、使用stat_central_tendency函数在密度中添加均值竖线并自定义线条类型
- 【CLion】CLion 总是提示 “This file does not belong to any project target xxx” 的解决方法
- C language implementation!20000 in 4 seconds
- 收藏|机械工程师面试常问问题
- R语言ggplot2可视化:使用ggpubr包的ggscatter函数可视化散点图、使用xscale函数指定X轴坐标轴度量调整方式、设置x轴坐标为scientific使用科学计数法显示坐标值
猜你喜欢

【讲座分享】“营收“看金融

2022 Go生态圈 rpc 框架 Benchmark

音视频技术开发周刊 | 256

How to use DevExpress controls to draw flowcharts?After reading this article, you will understand!

Promise learning (1) What is Promise?how to use?How to solve callback hell?

用户体验 | 如何度量用户体验 ?

表达式引擎在转转平台的实践

.NET analyzes the LINQ framework in depth (three: the elegant prelude of LINQ)

STM32 CAN过滤器配置详解

一篇文章,带你详细了解华为认证体系证书(1)
随机推荐
Small application project works WeChat gourmet recipes applet graduation design of finished product (1) the development profile
正则表达式
从零开始Blazor Server(4)--登录系统
pgAdmin 4 v6.12 发布,PostgreSQL 开源图形化管理工具
ddl and dml in sql (the difference between database table and view)
【likeshop】回收租凭系统100%开源无加密 商城+回收+租赁
Why Metropolis–Hastings Works
JS数据类型转换完全攻略
[5 days countdown] to explore the secret behind the great quality promotion, gift waiting for you to take of $one thousand
如何利用DevExpress控件绘制流程图?看完这篇文章就懂了!
收藏|机械工程师面试常问问题
sql中ddl和dml(数据库表与视图的区别)
(ES6以上以及TS) Map对象转数组
xss漏洞学习
Promise学习(二)一篇文章带你快速了解Promise中的常用API
Mini Program Graduation Works WeChat Food Recipes Mini Program Graduation Design Finished Products (4) Opening Report
复现assert和eval成功连接或失败连接蚁剑的原因
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)
2022 Go生态圈 rpc 框架 Benchmark
R语言ggplot2可视化:使用ggpubr包的geom_exec函数执行geom_*函数(没有任何参数需要放置在aes中)