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. pymysql操作mysql数据库

    1.建库 import pymysql # 建库 try: conn=pymysql.connect( host='127.0.0.1', port=3306, user='root', passwd ...

  2. Hystrix 熔断器

    Hystrix 是Netflix开源的一个延迟和容错库,用于隔离访问远程服务,防止出现级联失败 一.Hystrix 的定义 二.Hystrix 的原理 在分布式式系统中应用熔断器后,服务调用方可以自己 ...

  3. SAP-参数(条件表)配置教程–GS01/GS02/GS03

    转载:http://www.baidusap.com/abap/others/2849 在SAP开发中,某段代码运行可能需要满足某个条件,通常解决办法有两种:一种是在代码中写死限制条件,此种方式当限制 ...

  4. 转载 AI-Talking 图算法

    https://mp.weixin.qq.com/s/2XRgJr-ydxHA3JxAZ_5HeA 图算法在风控业务的实践 直播行业中有很多业务风控问题,比如说批量注册.刷热度.垃圾信息以及薅羊毛等. ...

  5. Android笔记(三) 使得Activity之间可以跳转---Intent

    什么是Intent 一个APP肯定不单单由一个Activity构成,我们在使用过程中,经常需要在多个Activity中跳转,Android中Intent可以帮我们来完成在各个Activity中跳转的功 ...

  6. github看项目-浏览器插件

    浏览器插件,使用浏览器看github项目 原文:浏览 GitHub 太卡了?教你两招!

  7. 使用Arduino开发板控制步进电机

    目前为止,我还没有真正深入了解过电机,特别是步进电机. 最近我在计划一个项目,需要相对精确的电机控制,所以可能会使用到步进电机,但很快就意识到我首先应该更多地了解这些. 本篇文章主要介绍我到目前为止学 ...

  8. 14 webpack中url-loader的使用

    默认情况下,webpack无法处理css文件中的url地址,不管是图片还是字体库,只要是URL地址,都处理不了,需要第三方loader 1.安装loader cnpm i url-loader fil ...

  9. List集合和Set集合UML图总结

    1.List和Set,用RationalRose展示 2.Map

  10. vscode 输出面板字符编码问题

    默认的输出中文会显示成乱码,需要在vscode内部的终端中输入 chcp 65001 缺点是需要每次打开vscode进行激活,另一种方式是在vscode的首选项中进行配置: "termina ...