字体反爬,是一种利用 CSS 特性和浏览器渲染规则实现的反爬虫手段。其高明之处在于,就算借助(Selenium 套件、Puppeteer 和 Splash)等渲染工具也无法拿到真实的文字内容。

这种反爬虫手段通常被用来保护页面中的关键数据,例如影片票房、外卖平台的商家电话、汽车门户上的车型报价或者是电商平台上商品的属性和价格。

关于字体反爬虫的介绍、实现和原理可以参考书籍《Python3 反爬虫原理与绕过实战》,也可以通过搜索引擎查找资料,本篇文章不再赘述。

本篇文章要解决的问题,是如何让程序准确的识别那些用自定义字体代替的文字

本文将围绕网站 aHR0cHM6Ly9tYW95YW4uY29tL2ZpbG1zLzEyMTgwMjk= 进行讨论,具体目标如下图:

显然,页面中的用户评分、累计票房等内容是关键数据,它们也正是爬虫工程师们想要的东西。虽然人类的眼睛看到的是 9.414.05,但在浏览器开发者工具中它们却是 ..9.4 对应的 HTML 代码为:

<span class="stonefont">.</span>

而网页源代码中,却是另外一番景象:

<span class="stonefont">.</span>

有经验的朋友一眼就看出来了,这是字体反爬虫的手段!没有经验的朋友,请去阅读《Python3 反爬虫原理与绕过实战》。

这种字体反爬虫的破解思路为:

获取相关 CSS 文件中 ttf 或 woff 字体文件,通过 python 的 fontTools 模块建立字体对应关系。

但是当你分析本文给出的案例时,却发现页面使用的字体是实时动态变化的,无法建立确定的对应关系。这跟Python3 反爬虫原理与绕过实战》中提到的反爬虫思路很相似,很棘手!

但庆幸的是,遇到的字体反爬手段和《Python3 反爬虫原理与绕过实战》中介绍的不是完全相同的,有些手段并没有用上,还好还好。

接下来,将介绍基于深度学习中最简单的K-近邻算法来破解这种实时动态变化的字体反爬措施。先说一下破解的步骤:

  • 将页面用到的字体文件下载到本地
  • 通过字体编辑器查看该字体文件
  • 观察字体文件随机动态的现象,并记录变化规律
  • 得出变化规律的规则

以本文给出的案例网站为例,首先在浏览器开发者工具的 NetWork 一栏找到页面加载的字体文件(通常是 WOFF 格式),并将问价下载到本地。然后用字体编辑器(例如百度字体编辑器)查看字体文件,如下图:

接着用 fontTools 库将 WOFF 格式的文件转换为 XML,并查看坐标变化规律。例如数字 6 对应的特殊字符为 uniF5DE,其对应的坐标值如下:

另一个字体文件中,数字 6 对应的坐标值如下:

经过多次测试发现:同一数字的对象虽然不同,但是区别甚微,对象中每个坐标的差值较小。这样我们可以通过限定对象的坐标值差值在一定范围内就可以认为是两个相同的数字了。

接下来采用机器学习最简单的方法KNN算法经过简单的训练,即可将坐标分类。

那么什么是KNN算法呢?

简单的说,K-近邻算法采用策略不同特征值之间的距离方法进行分类。

工作原理

存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中 k 的出处,通常k是不大于20的整数。最后,选择 k 个最相似数据中出现次数最多的分类作为新数据的分类。

基于上述介绍,可以先制作一个样本数据集合,样本数据集合如下:

即从 XML 文件中提取相关数字的坐标。通过 KNN 算法,对输入的字体的坐标进行计算,标记其标签:

def classifyPerson(font):
# 完整代码将在文末获得
pass

通过 KNN 算法标记标签后,即可通过 replace 方法对源代码文件进行替换:

fonts = {}
for i in base_list:
# 完整代码将在文末获得

这里随意选取了多个目标地址,并验证了其正确输出,本文案例对应的数据如下:

{"电影名称": "少年的你", "用户评分": "9.4", "评分人数": "95.2 万", "累计票房": "7.32 亿"}

至此,字体反爬的问题就解决了。

更多关于字体反爬的思路和研究请翻阅《Python3 反爬虫原理与绕过实战》,本文中还有一些重要观点未提及,建议翻书补齐知识。

完整代码请关注微信公众号爬虫工程师之家,并回复 20191029,即可获得代码仓库的链接。

本文参考:

公众号爬虫工程师之家的文章《基于K-近邻算法,破解CSS动态混淆字体》

韦世东的新书《Python3 反爬虫原理与绕过实战》

作者:华为云享专家 夜幕韦世东

k 近邻算法解决字体反爬手段|效果非常好的更多相关文章

  1. 使用K近邻算法改进约会网站的配对效果

    1 定义数据集导入函数 import numpy as np """ 函数说明:打开并解析文件,对数据进行分类:1 代表不喜欢,2 代表魅力一般,3 代表极具魅力 Par ...

  2. 02-16 k近邻算法

    目录 k近邻算法 一.k近邻算法学习目标 二.k近邻算法引入 三.k近邻算法详解 3.1 k近邻算法三要素 3.1.1 k值的选择 3.1.2 最近邻算法 3.1.3 距离度量的方式 3.1.4 分类 ...

  3. 第4章 最基础的分类算法-k近邻算法

    思想极度简单 应用数学知识少 效果好(缺点?) 可以解释机器学习算法使用过程中的很多细节问题 更完整的刻画机器学习应用的流程 distances = [] for x_train in X_train ...

  4. 机器学习实战 - python3 学习笔记(一) - k近邻算法

    一. 使用k近邻算法改进约会网站的配对效果 k-近邻算法的一般流程: 收集数据:可以使用爬虫进行数据的收集,也可以使用第三方提供的免费或收费的数据.一般来讲,数据放在txt文本文件中,按照一定的格式进 ...

  5. 从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    转载自:http://blog.csdn.net/v_july_v/article/details/8203674/ 从K近邻算法.距离度量谈到KD树.SIFT+BBF算法 前言 前两日,在微博上说: ...

  6. 1.K近邻算法

    (一)K近邻算法基础 K近邻(KNN)算法优点 思想极度简单 应用数学知识少(近乎为0) 效果好 可以解释机器学习算法使用过程中的很多细节问题 更完整的刻画机器学习应用的流程 图解K近邻算法 上图是以 ...

  7. 从K近邻算法谈到KD树、SIFT+BBF算法

    转自 http://blog.csdn.net/v_july_v/article/details/8203674 ,感谢july的辛勤劳动 前言 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章 ...

  8. Python爬虫入门教程 64-100 反爬教科书级别的网站-汽车之家,字体反爬之二

    说说这个网站 汽车之家,反爬神一般的存在,字体反爬的鼻祖网站,这个网站的开发团队,一定擅长前端吧,2019年4月19日开始写这篇博客,不保证这个代码可以存活到月底,希望后来爬虫coder,继续和汽车之 ...

  9. Python爬虫入门教程 63-100 Python字体反爬之一,没办法,这个必须写,反爬第3篇

    背景交代 在反爬圈子的一个大类,涉及的网站其实蛮多的,目前比较常被爬虫coder欺负的网站,猫眼影视,汽车之家,大众点评,58同城,天眼查......还是蛮多的,技术高手千千万,总有五花八门的反爬技术 ...

随机推荐

  1. Java描述设计模式(17):调停者模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 在公司的日常安排中,通常划分多个部门,每个部门又会分为不同的小组,部门经理的一项核心工作就是协调部门小组之间的工作 ...

  2. NOIP模(ka)拟(chang)测试30 考试报告

    应得分:300 实得分:210 毒瘤卡常出题人,卡掉90分! T1 Return 开个副本数组sort一下,unique去重就可以啦.时间复杂度$ O(nlog2(n)) $ T2 One 其实就是约 ...

  3. Mac中的Python安装selenium,结合chrom及chromdriver使用

    一.安装selenium 1.在终端通过命令安装 pip3 install -U selenium 二.准备环境 1.在电脑中安装谷歌浏览器chrom,和下载估计浏览器驱动chromdriver,以下 ...

  4. Elastic Stack 开源的大数据解决方案

    目的 本文主要介绍的内容有以下三点: 一. Elastic Stack是什么以及组成部分 二. Elastic Stack前景以及业务应用 三. Elasticsearch原理(索引方向) 四. El ...

  5. 深入理解 DNS

    深入理解 DNS 简介 DNS(Domain Name System)域名系统,它是一个将域名和 IP 地址相互映射的一个分布式数据库,把容易记忆的主机名转换成主机 IP 地址. DNS使用 TCP ...

  6. PHP Laravel 中使用简单的方法跟踪用户是否在线

    今天,我的任务是,在 Laravel 应用程序用户个人资料页面上,用户名旁边添加一个绿点,表示他们是否在线.我首先想到的是,我们将需要启动一个 node.js 服务器并跟踪每个用户的活动套接字连接.然 ...

  7. CSS复合选择器是什么?复合选择器是如何工作

    复合选择器介绍 复合选择器其实很好理解,说白了就跟我们生活中的有血缘关系家庭成员一样,通过标签或者class属性或id属性,去找对应的有血缘关系的某个选择器,具体的大家往下看哦. 如果是初学者对基本的 ...

  8. (C#)WPF:Property和Attribute的区别

    在C#里Property是属性,Attribute是特性.它们的概念是不一样的,充其量就是中文的神翻译问题. 1)属性是指类体里用get或set封装好的属性.属性是面向对象的理论范畴.比如说一个盒子, ...

  9. 前端小白在asp.net core mvc中使用ECharts

    对于在浏览器中绘制图形图表,目前有较多的js类库可以使用,如:ChartJS,Flot,canvasjs等,但是今天介绍的主角为国产图表库,并在apache孵化,就是大名鼎鼎的echarts. 前方高 ...

  10. 力扣(LeetCode)4的幂 个人题解

    给定一个整数 (32 位有符号整数),请编写一个函数来判断它是否是 4 的幂次方. 示例 1: 输入: 16 输出: true 示例 2: 输入: 5 输出: false 进阶:你能不使用循环或者递归 ...