javascript动态生成或加密的数据需执行js逻辑才能获取,直接requests返回的html中无目标字段;应优先分析关键js文件中的加密函数,复现时注意js与python在数值、字符串、编码等差异,复杂场景建议用playwright执行js。

JavaScript加密混淆导致response中没有目标数据
直接用requests请求页面,返回的HTML里找不到你要的字段(比如价格、token、加密参数),大概率是数据由JS动态生成或通过加密函数计算后插入DOM。这不是反爬策略多高明,而是你没执行那段JS逻辑。
常见现象:response.text里只有空容器(如<div id="data"></div>),但浏览器F12能看到渲染后的内容;Network面板里也找不到对应API,说明数据是本地算出来的。
- 优先检查页面是否加载了关键JS文件(比如
main.xxx.js或app.chunk.js),用浏览器开发者工具的Sources页签定位核心加密函数 - 不要急着上无头浏览器——如果只是解密固定逻辑(如AES、RSA、Base64+异或、自定义混淆),用Python复现更快更稳
- 注意JS里的时间戳、随机数、页面指纹(如
document.cookie、navigator.userAgent)可能参与计算,硬编码会失效
如何快速定位并提取JS中的加密函数
打开浏览器开发者工具 → Sources → 刷新页面 → 在左侧文件树里按关键词搜索:encrypt、sign、getSign、__anti、md5、aes,或者直接搜你看到的加密字符串(比如"a1b2c3"附近)。
找到后,在Console里手动调用验证:把函数复制出来,补全依赖(如require('crypto')在Node里才有,浏览器里可能是window.crypto.subtle或自定义实现),再用已知输入测输出是否一致。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 重点关注函数参数:是否依赖
document.title、Math.random()、new Date().getTime()等实时值 - 留意字符串拼接顺序、进制转换(
.toString(16))、位运算(>>>、^)——Python里^是异或,但JS里>>>是无符号右移,Python需用>>配合& 0xffffffff - 混淆后的函数名(如
_0x1a2b)别硬记,用断点调试看实际调用栈,找未混淆前的原始逻辑
Python复现JS加密逻辑时容易出错的细节
JS和Python在数值、字符串、编码处理上差异明显,直接翻译代码大概率跑不通。最常踩的坑不是算法错,而是类型和边界没对齐。
-
parseInt("0x1a")在JS里是10进制26,Python要用int("1a", 16);JS的String.fromCharCode(65)对应Python的chr(65),但JS字符串索引是UTF-16,Python是Unicode码点,中文基本一致,但emoji可能出错 - JS数组方法如
.map()、.reduce()返回新数组,Python的map()返回迭代器,记得加list() - JS里
0.1 + 0.2 === 0.3为false,Python虽然也存在浮点误差,但加密逻辑一般不涉及小数——如果JS用了toFixed(2),Python得用round(x, 2)或格式化字符串f"{x:.2f}" - 加密结果如果是base64,JS常用
btoa()(仅支持ASCII),Python要用base64.b64encode(...).decode(),且输入必须是bytes,别忘了.encode("utf-8")
什么时候该放弃复现,直接用PyExecJS或Playwright
当JS逻辑包含Web Crypto API(如SubtleCrypto.digest())、Canvas指纹、WebAssembly模块,或者混淆层超过3层(变量名全乱、控制流扁平化、字符串数组拆分),硬解成本远高于运行环境模拟。
-
PyExecJS已多年未维护,Node.js版本兼容性差,遇到ES6+语法(const、箭头函数)直接报错,不推荐新项目使用 -
Playwright比Selenium轻量且默认支持自动等待,用page.evaluate()直接执行JS片段最稳妥,例如:page.evaluate("() => window.getSign('data')") - 如果只需跑一次加密,可临时起个本地HTTP服务(用
http.server),把JS文件放进去,用Playwright访问并调用函数,避免打包整个页面上下文
真正麻烦的不是加密本身,而是那个加密函数依赖的“上下文”——比如它读取了某个隐藏input的value,而这个value又是另一个JS生成的。这种链式依赖,光看代码很难理清,必须在浏览器里单步调试确认每一步输入来源。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










