首页 > 其他分享 >07--JS07--逆向03:字体反爬

07--JS07--逆向03:字体反爬

时间:2024-07-12 15:30:00浏览次数:17  
标签:文字 03 07 -- url 字体 unicode uni font

JS逆向03:字体反爬

jsvmp : 代码虚拟化保护方案
    
ast   : 抽象语法树

1.字体文件、字体反爬

### 1 字体文件  .ttf  .woff   或 .eot
在计算机内存中,文字就是一堆二进制(unicode),要以文字图形的样子,展示给用户看
就要指定 它们之间的对应关系,就是字体文件


书法字体、火星文字体,不同的字体文件,对同样的文字unicode,显示出来的文字图形不一样
文字unicode  <== 字体文件 ==> 显示的文字图形(按照字体文件的规则,对应显示)

eg: 帅(101011二进制)  <--- 微软雅黑字体 --->  帅(汉字的图形)

# 文字图形样子的核心:取决于 文字的unicode 和 字体文件

# windows中的font-creator软件,可以打开查看字体文件  (只有windows) 



### 2 字体反爬原理
unicode的字节范围比较大(包含世界所有文字)
网站自定义了一套字体规则,把文字unicode中 用不上的unicode码,重新进行编排,对应上文字图形
而且有可能 编排对应后的文字图形,也做过一些微处理
例如:人字,细节处多一个小点,或者 一部分很长之类的

并在网页中显示时,不是直接显示 正常的现成文字图形
而是混杂着,重新编排的一些 特定unicode码 和 正常文字图形

所以正常爬取时,爬到这些特定的文字unicode码,并按照自己的现有字体文件 加载的话,就是乱的



### 3 解决字体反爬的实现步骤: 
1.从网站中,获取字体文件

2.从字体文件中,获取所有的文字unicode码

3.先将文字unicode码,照着字体文件里面的样子,把所有对应的文字图形,画到同一张图片上去

4.再用人工智能-图片识别文字【AI_OCR】,去识别这个图片   # 识别没有百分之百的准确率
  就知道了网页中 所有该文字unicode码,对应的正确文字是什么
  # 3、4步是 对字体文件进行解析   # unicode ---> 正确的文字 (难)


5.在获取到页面源代码后
  把unicode码的文字,进行正确文字的替换   # 后续就可以正常处理了 

    
    
    
### 4 第三方图片识别文字  ---> 也可以用于识别 验证码
1.ddddocr        # python的第三方库  免费
2.Tesseract-OCR  # python的第三方库  免费

3.火山(字节)     # 第三方 收费
4.百度AI(比上面这几个都好一些)

2.案例

2.1 获取字体文件

### 1 从网站中,获取到字体文件
import requests
from lxml import etree
from urllib.parse import urljoin
import re

# 1.先加载 index.html
url = "http://bikongge.com/chapter_1/font_1/index.html"
resp = requests.get(url)
resp.encoding = 'utf-8'
# print(resp.text)


# 2.从index.html中,获取style.css的url
tree = etree.HTML(resp.text)
href = tree.xpath("//link/@href")[0]
href = urljoin(url, href)
# print(href)


# 3.从style.css中,获取字体文件的url
font_resp = requests.get(href)
font_url_re = re.compile(r'src: url\("(?P<font_url>.*?)"\);', re.S)
font_url = font_url_re.search(font_resp.text).group("font_url")
# print(font_url)

# url拼接    这个url应该和谁拼接,是相对应style.css的,和style.css的url拼接
font_url = urljoin(href, font_url)
print(font_url)


# 4.下载字体文件
font_resp = requests.get(font_url)
with open("font.woff", mode="wb") as f:
    f.write(font_resp.content)


# 对比查看:
s = "\ue0df"    # 文字unicode码
print(s)        # 直接打印(默认unicode编码打印):一个奇怪的乱字

# 但实际是    windows软件font-creator打开看
'\ue0df' => 店 (字体文件)

2.2 获取文字unicode码

# 2 从字体文件中,获取所有的文字unicode码  需要font-tools库
# pip install fontTools

# TTFont('字体文件')的方法
  .getGlyphOrder()  # 获取所有文字的unicode码   有顺序  推荐使用
  .getGlyphNames()  # 获取所有文字的unicode码   无顺序


from fontTools.ttLib import ttFont

ttf = ttFont.TTFont("font.woff")
uni_list = ttf.getGlyphOrder()[2:]   # 推荐使用, 有顺序  ['unie467', 'uniee7e'...]

# 将uni字符串,转化为 python的unicode格式   \u:unicode码
uni_ok_list = []
for uni in uni_list:
    uni = uni.replace("uni", "\\u")  # 不能直接 \u,会被直接识别为unicode,再加个\ 防止转义
    uni_ok_list.append(uni)
    
    
print(uni_ok_list)
print(len(uni_ok_list))  # 601

2.3 根据字体文件画图

# 3 按照字体文件,把文字unicode码的文字图形,画出来
# 安装 pip install pillow
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw


# 1.创建画布    参数:模式-RGB彩色、大小、颜色
img = Image.new(mode="RGB", size=(2000, 1000), color=(255, 255, 255))

# 2.准备一只可以在图上画画的笔
img_draw = ImageDraw.Draw(img)

# 3.准备好画图的字体    画的字体、字体每个字的像素大小
img_font = ImageFont.truetype("font.woff", size=50)

# 4.准备开始画图,需要画图规划    不能全在一行,需要换行
# 例如:一行40个字 (50*40=2000,画布宽2000,正好够)

# 换行逻辑:
# 根据所有文字unicode码列表的索引号, 若 索引 % 40 == 0,(取余) 就该换行了

# 行号:  索引 // 40   # 整除,向下取整   从第0行开始
# 目的是为了计算,每行画笔的高度  y ---> (索引 // 40) * 每行的高度


# 指定每行字符的个数
line_length = 40

# 指定每行的高度  像素
line_heigth = 60

# 把一行需要画的字符,放进一个列表
char_line = []

for i in range(len(uni_ok_list)):
    uni = uni_ok_list[i]
    # 把 '\\uxxxx' 修改成unicode码,需要 用编码的转换 来进行调整  先编码成字节,再按照unicode解码
    uni = uni.encode().decode("unicode-escape")

    if i % line_length == 0 and i != 0:  # 遍历到需要换行的字符了
        # 1.先把上一行的字符,同时画到画布上
        char_line_s = "".join(char_line)

        # 画笔写字(.text)的参数:画的坐标(x,y)、内容、fill(填充)、参照的字体
        img_draw.text((0, (i // line_length - 1) * line_heigth), char_line_s, fill=1, font=img_font)

        # 2.本次遍历到字符 需要换行,直接覆盖上一次的行列表
        char_line = [uni]
    else:
        # 正常需画在同一行的字符,追加行列表
        char_line.append(uni)


# 再画,最后不足一整行的字符
if char_line:
    char_line_s = "".join(char_line)
    img_draw.text((0, (len(uni_ok_list) // line_length) * line_heigth), char_line_s, fill=1, font=img_font)

    
# 完成上述操作,你只是在内存中画了一张图

# 保存到硬盘上
img.save("tu.jpg")

2.4 图片识别文字

# 4 接下来就是识别上面这张图,获取到所有文字   ---> 百度AI
pip install baidu-aip
# 该库 还需要其他库
pip install chardet


from aip import AipOcr
 
"""刚才创建的那个应用里. 有下面这三个东西"""
APP_ID = '27643903'
API_KEY = 'atSZosOQ1xOQmBOmGSgLnbNA'
SECRET_KEY = 'znj959V9ZN0zlGVhZexABFT4ek57Kom2'

client = AipOcr(APP_ID, API_KEY, SECRET_KEY)

f = open("tu.jpg", mode="rb")
r = client.basicGeneral(f.read())


# 所有文字
result_list = []
for item in r['words_result']:
    result_list.extend(item['words'])
    
    
print(len(result_list))  # 注意:调整识别后的文字数量 是否与 unicode码字数量 一致

2.5 解析替换

### 5 替换--反向
# 5.1 把unicde对应的word,进行映射 ---> 字典
  # zip() 有水桶效应(以短的一方,为边界) 
  # 故:uni_ok_list和result_list必须长度保持一致.

dic = dict(zip(uni_ok_list, result_list))
# 结果:{"\\uxxxx": 天}



# 5.2 获取页面源代码,并把字典中'\\u' ,按照页面的形式,换成 '&#X'
# 5.3 再页面源码的'&#X',替换成 识别后的文字
url = "http://bikongge.com/chapter_1/font_1/index.html"
resp = requests.get(url)
resp.encoding = 'utf-8'

page_source = resp.text

for k in dic:
    # k: \\uxxxxx
    # v: 天
    v = dic[k]

    kk = k.replace("\\u", "&#x") + ";"
    # 字符串不可变. 需要重新赋值
    page_source = page_source.replace(kk, v)

print(page_source)

标签:文字,03,07,--,url,字体,unicode,uni,font
From: https://www.cnblogs.com/Edmondhui/p/18298496

相关文章

  • 海外短剧系统源码搭建(APP+H5)平台多语言系统
    为大家推荐一个非常好用的短剧系统,它可以搭建海外短剧多语言。这个海外短剧系统平台支持多种国家语言,后台管理一键翻译,系统自带7种语言,后台支持中文简体、中文繁体、英语、泰语、越南语、阿拉伯语、西班牙语、等等,后台管理想要什么语言随便加。讲一下推荐的优势:系统自带7种......
  • Docker学习笔记(03)——制作Docker镜像
    Docker镜像原理思考:Docker镜像本质是什么?是一个分层文件系统Docker中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?Centos的iso镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层Docker中一个tomcat......
  • 【提交ACM出版 | EI&Scopus检索稳定 | 高录用 | 数字经济、区块链、人工智能相关主题
    2024年数字经济,区块链与人工智能国际学术会议(DEBAI2024)为第五届大数据与社会科学国际学术会议(ICBDSS2024)的分会,将于2024年8月23-25日在中国-广州隆重举行。为了让更多的学者有机会参与会议分享交流经验。本次会议主要围绕“数字经济,区块链与人工智能等研究领域展开讨论。目前......
  • 【北方工业大学承办,JPCS独立出版 (ISSN:1742-6596) | 组委会嘉宾阵容强大】2024年电力
    2024年电力系统工程与智能电网国际学术会议(PSESG2024)于2024年8月16-18日在中国·北京隆重召开。会议旨在为从事“电力系统工程”、“智能电网”、“储能技术”等领域的专家学者、工程技术人员、研发人员提供一个共享科研成果和前沿技术,了解学术发展趋势,拓宽研究思路,加强学术......
  • VAE(Variational auto-encoder)
    1.VAE(Variationalauto-encoder)笔记来源及推荐文章:1.变分自编码器(一):原来是这么一回事2.变分自编码器(二):从贝叶斯观点出发3.变分自编码器(三):这样做为什么能成?4.变分自编码器(四):一步到位的聚类方案5.变分自编码器=最小化先验分布+最大化互信息6.变分自编码器(六):从几何......
  • 连锁门店收银系统源码,可二次开发
    1.多样化线下收银如Windows版收银(exe安装包)、安卓版收银(apk安装包)、AI智能称重收银(exe/安卓安装包)、无人自助收银(apk安装包)、手机端收银(微信小程序版)、聚合码收银(小程序版)。2.收银端ui风格收银端ui风格,门店可以根据自己的喜好去自定义,如天空蓝、高端金、热情红、生鲜绿、......
  • 【C++修行之道】string类的使用
    目录一.C语言中的字符串二、标准库中的string类(了解)2.1string类(了解)2.2帮助文档阅读三、string类的常用接口说明3.1 string类对象的常见构造 3.2 string类对象的容量操作3.3 string类对象的访问及遍历操作字符串类的简单实现3.4 string类对象的修改操作......
  • 脑瘤-图像分类数据集
    脑瘤-图像分类数据集数据集:链接:https://pan.baidu.com/s/11nIlAsNbhx3umCdjcTUzFg?pwd=0e1g提取码:0e1g数据集信息介绍:文件夹健康中的图片数量:500文件夹垂体肿瘤中的图片数量:899文件夹神经胶质瘤中的图片数量:926文件夹脑膜瘤中的图片数量:929所......
  • 十一、【机器学习】【监督学习】- 局部加权线性回归 (Locally Weighted Linear Regres
     系列文章目录第一章【机器学习】初识机器学习第二章【机器学习】【监督学习】-逻辑回归算法(LogisticRegression)第三章【机器学习】【监督学习】-支持向量机(SVM)第四章【机器学习】【监督学习】-K-近邻算法(K-NN)第五章【机器学习】【监督学习】-决策树(D......
  • Nepxion 教程 - Discovery 之配置中心支持灰度配置
    NepxionDiscovery支持与主流配置中心(如Nacos、Apollo、SpringCloudConfig)集成,实现配置的集中管理和动态刷新,特别是在灰度发布场景下,能够为不同的服务实例或环境提供差异化配置。以下是如何使用NepxionDiscovery配合配置中心实现灰度配置的教程:1.准备工作选择配置中......