PyExecJS在混淆JS中大概率失败,因其无浏览器上下文(缺window/document)、无法处理控制流扁平化、不支持动态代码执行及反调试逻辑;可靠方案仅AST静态解析(适用于字符串解密等无副作用场景)或Playwright真实环境执行(可注入脚本绕过反调试并同步调用加密函数)。

直接用 PyExecJS 执行混淆 JS 基本无效,90% 以上会因缺失 window、document 或控制流扁平化而崩溃;真正能落地的方案只有两类:静态 AST 解析还原字符串/函数调用,或用 Playwright 真实执行并绕过反调试。
为什么 PyExecJS 在混淆 JS 上大概率失败
它不是浏览器,只是 JS 引擎壳子,没上下文就跑不起来:
-
document.getElementById、localStorage.getItem这类调用直接抛ReferenceError - 控制流被 flatten 成
while(true){switch(v){case 0:...}},PyExecJS 能跑但分支不可控,尤其含Date.now()或Math.random()时结果随机 - 混淆器常插入
eval(unescape("%u674e%u6587"))或动态构造函数名,PyExecJS 解析不了运行时生成的代码 - 哪怕只是
atob("SGVsbG8="),若参数来自location.href或performance.now(),也立刻脱离纯静态范围
AST 静态解析适合哪些场景
只处理混淆中“有结构、无副作用”的字符串解密逻辑,安全、零风险、可批量:
- 匹配
String.fromCharCode(72, 101, 108, 108, 111)→ 提取数字列表转字符 - 识别
atob("SGVsbG8=")→ 直接用base64.b64decode替代 - 捕获
["H","e","l","l","o"].join("")→ 检查ArrayExpression+CallExpression.callee.property.name === "join" - 忽略
void 0、!1等无返回值表达式,只遍历有实际值的子树
推荐用 esprima-python(别用已停更的 pyjsparser,遇到箭头函数直接 ParseError: Unexpected token)。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
立即学习“Python免费学习笔记(深入)”;
Playwright 绕过反调试的关键操作
不是“加载页面等渲染完”就完事,得主动干预 JS 运行环境:
- 启动时加
page.add_init_script('Math.random = () => 0.5')固定随机数,避免加密参数每次不同 - 预置
localStorage.setItem("token", "xxx")或覆盖window.navigator.webdriver = false,骗过基础检测 - 对含
debugger或if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {...}的代码,用page.remove_script_tag或注入空函数覆盖 - 需要调
getSign({a:1})时,不用抠函数,直接page.evaluate("getSign", {"a": 1}),结果同步返回
混淆越深,越不能依赖“格式化后人工读”,AST 和 Playwright 是目前唯二稳定路径;前者快但只能解固定模式,后者慢但能跑通所有逻辑——选哪个,取决于你手上的 JS 是“藏字符串”还是“跑完整加密流程”。

















