1.参考博客

         https://www.jianshu.com/p/9975de57b0ce

         https://blog.csdn.net/litang199612/article/details/83413002

         https://blog.csdn.net/m0_37156322/article/details/84658872

         https://blog.csdn.net/paul0926/article/details/96336947

本博客重点讲解java实现反爬虫字体解密,了解具体原因请参考以上博客,Python也请参考以上博客。

2.背景

          在针对安居客等房地产项目进行数据爬虫工作中,发现页面的显示为标准的数字,但数据抓取到确实乱码

页面:

页面审查:

页面显示的“2500”,但数据显示的却是“龒麣龤龤”的乱码,很疑惑,最后审查发现数据显示是使用的一个特殊字体“fangchan-secret”。

fangchan-secret

经查询相关文档和博客,发现fang-secret是一个动态生成字体库的工具,而且每次根据不同key生成,字体库动态生成,后端又不存在相关字体库,所以获取的是乱码。key为base64,重新加载页面key为变化,具体的key可以审查页面,检索"AAAAA",比较长的一串的base64编码的就是了,浏览器每次返回页面根据动态字体库渲染相关数据。

       3.解决方案

         在博客和相关文档中,了解了相关原因,但其具体的实现却是基于python实现,最关键的是python的ttffont的库,一直想找java的解决方案没有,只好自己动手。

         拿到动态生成的字体库的key

        

         因为字体库基于key生成,这里实现可以通过java的爬虫工具,然后使用正则表达式实现,然后拿到以下的字符串:

   生成字体库,解码

这里使用java的awt的相关jar包,关键的类Font实现

     /**
* font-secret字符串专用解密工具
*
* @param key 密匙
* @param encodeString 加密后的字符串
* @return 解密后的字符串
*/
public static String decodeString(String key, String encodeString) {
try {
//base64解码,初始化字体
byte[] ss = Base64.decodeBase64(key);
InputStream inputStream = new ByteArrayInputStream(ss);
Font dynamicFont = Font.createFont(Font.TRUETYPE_FONT, inputStream);
FontRenderContext fontRenderContext = new FontRenderContext(new AffineTransform(), false, false);
GlyphVector glyphVector = dynamicFont.createGlyphVector(fontRenderContext, ""); //获取font中字形的映射关系,字段为private,使用反射
Class<?> clazz = Font.class;
Field[] fs = clazz.getDeclaredFields();
Font2DHandle font2DHandle = null;
for (int i = 0; i < fs.length; i++) {
fs[i].setAccessible(true);// 将目标属性设置为可以访问
if (fs[i].getName().equals("font2DHandle")) {
font2DHandle = (Font2DHandle) fs[i].get(dynamicFont);
} } //得到映射关系
Font2D font2D = font2DHandle.font2D;
TrueTypeFont trueTypeFont = (TrueTypeFont) font2D;
TrueTypeGlyphMapper charToGlyphMapper = (TrueTypeGlyphMapper) trueTypeFont.getMapper(); //开始解密,encodeString为加密后的字符串
StringBuffer buffer = new StringBuffer();
char[] chars = encodeString.toCharArray();
for (int i = 0; i < chars.length; i++) {
buffer.append(charToGlyphMapper.charToGlyph(chars[i]) - 1);
}
return buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}

4.demo

 demo:https://gitee.com/scnucxy/spiderFontDemo

      

JAVA爬虫对font-face字体反爬虫解密的更多相关文章

  1. 深入细枝末节,Python的字体反爬虫到底怎么一回事

    内容选自 即将出版 的<Python3 反爬虫原理与绕过实战>,本次公开书稿范围为第 6 章——文本混淆反爬虫.本篇为第 6 章中的第 4 小节,其余小节将 逐步放送 . 字体反爬虫开篇概 ...

  2. Python 爬虫工程师必看,深入解读字体反爬虫

    字体反爬虫开篇概述 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人 ...

  3. 基于C#.NET的高端智能化网络爬虫(一)(反爬虫哥必看)

    前两天朋友发给我了一篇文章,是携程网反爬虫组的技术经理写的,大概讲的是如何用他的超高智商通过(挑衅.怜悯.嘲讽.猥琐)的方式来完美碾压爬虫开发者.今天我就先带大家开发一个最简单低端的爬虫,突破携程网超 ...

  4. python网络爬虫 - 如何伪装逃过反爬虫程序

    有的时候,我们本来写得好好的爬虫代码,之前还运行得Ok, 一下子突然报错了. 报错信息如下: Http 800 Internal internet error 这是因为你的对象网站设置了反爬虫程序,如 ...

  5. Python爬虫学习笔记——防豆瓣反爬虫

    开始慢慢测试爬虫以后会发现IP老被封,原因应该就是单位时间里面访问次数过多,虽然最简单的方法就是降低访问频率,但是又不想降低访问频率怎么办呢?查了一下最简单的方法就是使用转轮代理IP,网上找了一些方法 ...

  6. 自动更改IP地址反爬虫封锁,支持多线程(转)

    8年多爬虫经验的人告诉你,国内ADSL是王道,多申请些线路,分布在多个不同的电信机房,能跨省跨市更好,我这里写好的断线重拨组件,你可以直接使用. ADSL拨号上网使用动态IP地址,每一次拨号得到的IP ...

  7. WebSocket 反爬虫

    目录 WebSocket握手验证反爬虫 WebSocket 消息校验反爬虫 WebSocket Ping 反爬虫 总结 WebSocket握手验证反爬虫 ! HTTP协议 请求头 服务器端创建 soc ...

  8. 温故知新,.Net Core利用UserAgent+rDNS双解析方案,正确识别并反爬虫/反垃圾邮件

    背景 一般有价值的并保有数据的网站或接口很容易被爬虫,爬虫会占用大量的流量资源,接下来我们参考历史经验,探索如何在.Net Core中利用UserAgent+rDNS双解析方案来正确识别并且反爬虫. ...

  9. k 近邻算法解决字体反爬手段|效果非常好

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

随机推荐

  1. iOS copy和mutableCopy 整理

    copy 和 mutableCopy 你真的理解吗?最近发现很多面试者基本都不能很好地回答这个问题.所以整理一下. copy和mutableCopy的概念: copy 浅拷贝,不拷贝对象本身,仅仅是拷 ...

  2. 部署vue项目到阿里云服务器(Ubuntu16.04 64位)

    上传文件 1.通过Xftp将vue项目文件上传至云服务器:由于node_modules这个依赖包体积较大,上传较慢,上传时跳过,在云服务器上重新进行npm install安装依赖包即可: 2.也可通过 ...

  3. jenkins+docker+git+harbor构建及代码回滚(未完)

    目录 一.部署 环境工作流程介绍 部署harbor 一.部署 前提环境说明 192.168.111.3 该机器为git本地仓库,及git远程仓库(git用户创建),及Harbor镜像仓库 192.16 ...

  4. poi 读取word 遍历表格和单元格中的图片

    背景 项目需要解析word表格 需要批量导入系统,并保存每行信息到数据库 并且要保存word中的图片, 并保持每条信息和图片的对应关系 一行数据可能有多条图片 解决办法 没有找到现成的代码,怎么办呐? ...

  5. centos 安装 kibana

    因为我本机安装的 elasticsearch 是 6.2.4 版本,所以kibana也要安装对应的 6.2.4 版本 wget https://artifacts.elastic.co/downloa ...

  6. tcpdump命令及输出详解

    一. 使用方法 1. 指定类型 host:指定主机 tcpdump host 192.168.100.1 tcpdump host 192.168.100.1 and !192.168.100.2 t ...

  7. 数组中的reduce

    reduce方法第一次对我的感觉是很鸡肋,但是深入了解,才发现其中的奥妙,是个非常强大且实用的方法 var arr = [1,2,3,4,5,6,7]; var sum = arr.reduce( ( ...

  8. NXP LPC系列学习笔记汇总(持续更新中)

    1. LPC11E68循环冗余校验CRC学习笔记 文章主要介绍了如何使用LPC11E68的CRC外设功能,并介绍了与CRC引擎相关的寄存器,然后以生成CRC-CCITT多项式校验为例进行了介绍. 2. ...

  9. java UDP 通信:服务端与客服端

    import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import j ...

  10. 01-Spring概述

    1.spring是什么 Spring是分层的Java SE/EE应用 full-stack轻量级开源框架,以IoC(Inverse Of Control:反转控制)和AOP(Aspect Orient ...