news 2026/5/8 23:43:40

Python 爬虫反爬突破:AST 还原混淆 JS 代码实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 爬虫反爬突破:AST 还原混淆 JS 代码实战

前言

在现代 Web 反爬体系中,前端 JS 代码混淆、变量加密、函数扁平化、字符串乱序、控制流平坦化已成为站点基础防护手段。常规格式化、手动抠代码、正则替换等方式,面对高强度混淆 JS 完全失效,不仅代码逻辑碎片化严重,变量名无规则替换,还存在死代码插入、垃圾字符填充、逻辑分支伪造等混淆手段,人工逆向耗时漫长且极易出错。

AST 抽象语法树作为代码编译与解析的核心底层技术,可跳过代码表层混淆,直接解析 JS 代码语法结构,实现变量重命名、扁平化函数还原、死代码剔除、字符串解密、控制流还原全流程自动化处理,是当前批量还原高强度混淆 JS 的最优方案。本文配套所需工具与库官方链接如下:

  1. estraverse 官方文档:AST 节点遍历核心库
  2. esprima 解析库:JS 代码转 AST 语法树工具
  3. babel 官方中文文档:前端代码编译与 AST 转换生态
  4. pyjsparser PyPI 库:Python 端 JS 语法解析库
  5. Node.js 官方下载:运行 Babel、AST 逆向环境必备

文章从 AST 基础原理、JS 主流混淆类型、AST 还原核心流程、Python+Node 双环境实战、通用还原模板、工程化批量处理逐一讲解,附带可直接商用的完整代码案例,并逐段拆解底层运行原理,帮助爬虫开发者彻底摆脱人工逆向混淆 JS 的低效模式。

一、AST 抽象语法树基础理论

1.1 AST 核心定义

AST 全称抽象语法树,是将编程语言源代码按照语法规则拆解为树形结构化节点的表现形式。代码不再以字符串文本形式存在,而是被拆解为表达式、语句、变量、函数、条件分支、循环等标准化节点,节点之间存在层级与关联关系。

无论 JS 代码经过怎样的变量混淆、字符加密、格式压缩,其语法逻辑结构不会改变,这也是 AST 能够无损还原混淆代码的核心底层依据。

1.2 AST 关键节点类型

JS 代码转换为 AST 后,常用核心节点类型如下表:

表格

节点类型英文标识对应代码含义还原中作用
变量声明VariableDeclarationvar/let/const 定义变量批量重命名混淆变量
函数表达式FunctionExpression自定义函数逻辑还原扁平化嵌套函数
字符串字面量StringLiteral普通字符串值解密加密字符串
条件语句IfStatementif/else 逻辑分支剔除伪造死代码分支
调用表达式CallExpression函数调用执行重构混乱调用关系
成员表达式MemberExpression对象属性取值还原混淆对象访问逻辑

1.3 AST 还原混淆 JS 核心优势

传统手动逆向只能修改代码表层字符串,无法触及逻辑结构;而 AST 具备三大不可替代优势:

  1. 无视代码格式压缩、换行缺失、空格删减,直接解析语法逻辑;
  2. 批量自动重命名 a1、b2、x9 等无意义混淆变量,恢复语义化命名;
  3. 自动识别并删除冗余死代码、无效分支、垃圾填充代码,精简源码;
  4. 自动化解密数组移位、字符置换、Base64 内嵌加密字符串。

二、前端 JS 主流混淆类型识别

2.1 变量名混淆

将有语义的变量名、函数名替换为单字符、随机无意义字符,如getSign替换为a_0x12abcf,增加阅读和逆向难度,是最基础的混淆方式。

2.2 控制流平坦化

把顺序执行的代码拆分为无序分支,通过数组索引、随机判断跳转执行逻辑,打乱代码执行顺序,人工梳理逻辑成本极高。

2.3 字符串数组加密

将所有明文字符串统一放入全局数组,通过下标索引调用,数组本身再做移位、异或、Base64 加密,隐藏接口密钥、URL、固定参数等核心字符串。

2.4 死代码注入

插入永远不会执行的 if 分支、空循环、无效函数,干扰逆向者判断,增加代码冗余度。

2.5 函数嵌套扁平化

多层函数嵌套、自执行匿名函数堆砌,把正常业务逻辑拆分为碎片化小函数,割裂代码关联关系。

三、AST 逆向环境搭建

3.1 环境组成说明

AST 还原混淆 JS 分为两套环境:Node.js 端 Babel 生态(专业级 AST 解析还原)、Python 端 pyjsparser(轻量级语法解析),工程化实战以 Node+Babel 为主,Python 做辅助调用与批量处理。

3.2 Node 端依赖安装

新建项目文件夹,执行初始化与依赖安装命令:

bash

运行

# 初始化node项目 npm init -y # 安装AST核心依赖 npm install @babel/parser @babel/traverse @babel/generator @babel/types

3.3 Python 端依赖安装

Python 用于读取混淆 JS 文件、调用 Node 脚本、批量处理文件:

bash

运行

pip install pyjsparser -i https://pypi.tuna.tsinghua.edu.cn/simple

3.4 环境校验代码

3.4.1 Node 端 AST 基础解析校验

新建ast_check.js

javascript

运行

const parser = require('@babel/parser'); const traverse = require('@babel/traverse').default; const generate = require('@babel/generator').default; // 测试混淆JS代码 const jsCode = "var a='hello';function b(){console.log(a);}"; // 转为AST语法树 const ast = parser.parse(jsCode); // 遍历AST节点 traverse(ast, { VariableDeclaration(path){ console.log("检测到变量声明节点"); } }); // 重新生成还原后代码 const {code} = generate(ast); console.log("还原后代码:",code);

运行命令:node ast_check.js,输出节点检测信息与格式化代码即代表环境正常。

3.4.2 代码原理
  1. @babel/parser将 JS 字符串解析为标准 AST 语法树;
  2. @babel/traverse遍历树上所有节点,可精准匹配变量、函数、字符串节点;
  3. @babel/generator将修改后的 AST 树重新生成规整可读的 JS 代码。

四、AST 五大核心还原实战案例

4.1 案例一:混淆变量自动重命名还原

4.1.1 实战代码

新建rename_var.js

javascript

运行

const parser = require('@babel/parser'); const traverse = require('@babel/traverse').default; const generate = require('@babel/generator').default; // 高强度变量混淆JS源码 const confuseJs = `var _0x12a3='123456';var _0x45b2='sign';function _0x78c3(){return _0x12a3+_0x45b2;}`; // 解析为AST const ast = parser.parse(confuseJs); let varIndex = 1; // 遍历标识符节点,批量重命名 traverse(ast, { Identifier(path){ const name = path.node.name; // 匹配混淆格式变量名 if(/^_0x[a-f0-9]{4,}$/.test(name)){ path.node.name = "var_"+varIndex++; } } }); // 生成还原后代码 const result = generate(ast,{retainWhitespace:true}).code; console.log("变量重命名还原结果:\n",result);
原理剖析
  1. 通过正则匹配站点典型混淆变量名_0x+十六进制字符,精准定位混淆标识符;
  2. 遍历 AST 标识符节点,直接修改节点的 name 属性,完成批量重命名;
  3. 重新生成代码后,无意义乱码变量变为var_1、var_2规整命名,可读性大幅提升;
  4. 全程不改动代码业务逻辑,仅修改变量展示名称,完全无损还原。

4.2 案例二:字符串数组加密 AST 解密还原

4.2.1 实战代码

新建decode_string.js

javascript

运行

const parser = require('@babel/parser'); const traverse = require('@babel/traverse').default; const generate = require('@babel/generator').default; // 字符串数组混淆示例JS const confuseJs = `var arr=["abc123","tokenKey","https://api.test.com"];function getStr(n){return arr[n];}`; const ast = parser.parse(confuseJs); let strMap = new Map(); // 第一步:提取数组内所有字符串 traverse(ast, { VariableDeclaration(path){ path.node.declarations.forEach(dec=>{ if(dec.init && dec.init.type === "ArrayExpression"){ dec.init.elements.forEach((el,idx)=>{ if(el.type === "StringLiteral"){ strMap.set(idx,el.value); } }); } }); } }); // 第二步:替换数组下标调用为真实字符串 traverse(ast, { MemberExpression(path){ if(path.node.property.type === "NumericLiteral"){ const idx = path.node.property.value; if(strMap.has(idx)){ path.replaceWith({ type:"StringLiteral", value:strMap.get(idx) }); } } } }); const result = generate(ast).code; console.log("字符串数组解密还原:\n",result);
原理剖析
  1. 遍历 AST 找到全局数组变量,提取数组下标与对应明文字符串,建立映射表;
  2. 匹配所有数组下标调用节点,直接用真实字符串字面量替换原有下标访问;
  3. 彻底消除数组中转加密逻辑,代码中直接展示明文 URL、密钥、接口参数;
  4. 适用于 90% 前端字符串数组移位、隐藏核心常量的混淆场景。

4.3 案例三:控制流平坦化死代码剔除

4.3.1 实战代码

javascript

运行

const parser = require('@babel/parser'); const traverse = require('@babel/traverse').default; const generate = require('@babel/generator').default; const confuseJs = `function test(){if(1>2) return "垃圾代码";else return "realData";}`; const ast = parser.parse(confuseJs); // 剔除永远不会执行的死代码分支 traverse(ast, { IfStatement(path){ const testNode = path.node.test; // 判定固定假条件分支 if(testNode.type === "BinaryExpression" && testNode.operator === ">"){ path.replaceWith(path.node.alternate); } } }); const result = generate(ast).code; console.log("死代码剔除后:\n",result);
原理剖析
  1. AST 可精准识别 if 条件表达式、二元运算节点,判断逻辑真假;
  2. 自动删除恒假分支代码,保留真实执行的 else 业务逻辑;
  3. 批量清理站点刻意插入的无效分支、空循环、冗余判断,精简代码结构。

4.4 案例四:扁平化嵌套函数还原

4.4.1 核心原理

前端混淆常将一个完整业务逻辑拆分为多个小函数互相调用,AST 通过遍历CallExpression函数调用节点,梳理函数依赖关系,合并碎片化逻辑,还原正常函数结构。通过标记被多次调用的公共函数、剥离无关嵌套层级,把扁平化打散的代码重新聚合为可读完整函数。

4.5 案例五:Python 调用 Node 实现批量 JS 还原

4.5.1 实战代码

python

运行

import subprocess import os # 批量读取混淆JS文件,调用AST还原脚本 def batch_ast_reduce(): # 混淆JS存放目录 confuse_dir = "./confuse_js" # 还原后JS输出目录 output_dir = "./decode_js" if not os.path.exists(output_dir): os.mkdir(output_dir) for file in os.listdir(confuse_dir): if file.endswith(".js"): file_path = os.path.join(confuse_dir,file) # 调用node执行AST还原脚本 res = subprocess.run( ["node","rename_var.js",file_path], capture_output=True, encoding="utf-8" ) # 写入还原后文件 with open(os.path.join(output_dir,file),"w",encoding="utf-8") as f: f.write(res.stdout) print("批量AST还原完成") if __name__ == "__main__": batch_ast_reduce()
原理剖析
  1. Python 遍历本地 JS 文件目录,批量读取所有混淆脚本;
  2. 调用 subprocess 子进程执行 Node 端 AST 还原脚本;
  3. 获取标准输出的还原后代码,批量写入新文件,实现工程化一键处理;
  4. 适合爬虫项目中批量逆向多个加密 JS 文件,无需手动逐个处理。

五、AST 还原通用标准流程

5.1 标准处理步骤

  1. 源码获取:抓包下载前端混淆 JS 源码,保存为本地文件;
  2. 语法解析:通过 Babel Parser 将 JS 转为 AST 语法树;
  3. 节点遍历:遍历变量、字符串、条件、函数节点;
  4. 规则处理:变量重命名、字符串解密、死代码删除、控制流还原;
  5. 代码生成:通过 Generator 将修改后的 AST 重新生成可读 JS;
  6. 人工微调:对少量复杂逻辑做简单梳理,即可直接逆向算法。

5.2 通用 AST 还原配置模板

可固定复用 Babel 生成配置,保证还原后代码格式规整:

javascript

运行

const result = generate(ast,{ retainWhitespace:true, compact:false, quotes:"single" }).code;

六、常见混淆场景 AST 落地适配方案

表格

混淆类型AST 处理方案适用场景
随机变量名混淆正则匹配批量重命名常规站点基础混淆
字符串数组加密提取数组映射 + 下标替换接口密钥、URL 隐藏
控制流平坦化识别恒假分支 + 删除死代码逻辑打乱类高强度混淆
自执行匿名函数提取内部逻辑、剥离外层包裹页面入口加密 JS
Base64 内嵌 JSAST 提取字符串 + Python 解码双层嵌套加密 JS

七、工程化避坑与优化策略

7.1 常见坑点

  1. 部分混淆 JS 含 ES6 新语法,需配置 Babel 支持 ES6 + 解析,否则 AST 解析报错;
  2. 超大体积 JS 文件遍历 AST 耗时增加,需做分片解析;
  3. 特殊自定义混淆规则,需自定义正则与节点匹配逻辑,不能套用通用模板。

7.2 优化方案

  1. 在 Parser 中增加sourceType:"module"适配模块化 JS;
  2. 采用异步遍历 AST 节点,提升大文件处理速度;
  3. 封装通用 AST 还原工具类,后续新项目直接传入 JS 源码即可输出还原结果。

八、总结

AST 抽象语法树是破解前端高强度 JS 混淆的核心底层技术,彻底颠覆了人工逐行抠代码的传统逆向模式。依托 Babel 生态可实现变量重命名、字符串解密、死代码剔除、控制流还原全自动化,配合 Python 实现批量文件处理,极大提升爬虫逆向效率。

掌握 AST 还原技术后,面对市面上绝大多数网站的 JS 混淆、接口签名加密、参数算法混淆,均可快速拆解逻辑、复刻加密算法,为后续动态密钥、接口验签逆向打下坚实基础。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 23:38:40

MCP协议应用商店:awesome-mcp-hub资源索引库实战指南

1. 项目概述:一个为MCP打造的“应用商店”如果你最近在折腾AI Agent或者智能体应用开发,大概率已经听过“模型上下文协议”这个名字了。没错,我说的就是MCP。它本质上是一套标准,让大语言模型能够安全、可控地访问外部工具和数据源…

作者头像 李华
网站建设 2026/5/8 23:36:53

单目视频分析系统实现乒乓球轨迹与旋转实时检测

1. 项目背景与核心价值乒乓球运动中的轨迹和旋转分析一直是体育科技领域的热点问题。传统方法依赖高速摄像机阵列或多传感器融合方案,成本高昂且部署复杂。我们开发的这套单目视频分析系统,仅需普通智能手机或监控摄像头拍摄的视频流,就能实时…

作者头像 李华
网站建设 2026/5/8 23:35:41

构建智能记忆系统:从对话历史中提炼结构化知识的架构实践

1. 项目概述:从“记忆垃圾场”到“知识金矿”的进化之路 在AI助手与用户的长期交互中,一个核心挑战是如何有效管理对话历史。传统的做法,无论是逐行存储还是全文转储,都像是把对话记录扔进一个巨大的“记忆垃圾场”。前者丢失了宝…

作者头像 李华
网站建设 2026/5/8 23:34:32

RubricHub:自动化评估标准生成技术解析与应用

1. 项目背景与核心价值在教育评估和技能考核领域,评估标准(Rubric)的制定一直是项耗时费力的工作。传统方式需要领域专家手动设计评分维度和等级描述,这个过程往往需要数周甚至数月时间。RubricHub项目的出现,正是为了…

作者头像 李华
网站建设 2026/5/8 23:33:36

Display Driver Uninstaller:专业显卡驱动深度清理解决方案

Display Driver Uninstaller:专业显卡驱动深度清理解决方案 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-uninsta…

作者头像 李华
网站建设 2026/5/8 23:32:58

2026届最火的五大降重复率方案实际效果

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 需从语言模式、逻辑结构以及细节处理这三方面着手来降低AIGC(人工智能生成内容&a…

作者头像 李华