python-执行js代码常见包(特点与内置引擎)和pyinstaller打包node依赖
目录
python读取并执行js代码的包有很多,但每个包的特点和内置引擎都不一样,各自特点和适用环境也大不相同。了解各个某块的特点可以极大减少报错几率和代码运行效率,减少内存占用等。
常见的包有:ExecJS,js2py,PyMinRacer,quickjs,dukpy和subprocess+node
其次就是适用selenium来执行js代码,该方式支持所有浏览器原生 JS,完全兼容 JS + DOM,但是启动慢、需要浏览器驱动、打包复杂。我就不介绍了。
感兴趣的可以看完之前写的博客。
1.ExecJS
一.安装
pip install PyExecJS 这是最经典包了,相信很多小伙伴的第一次都是它。
二.特点
- 需要本地node.js环境 能自动检测环境并调用
- 是python对多种JS引擎的封装(Node,JScript,PhantomJS......)
- 兼容性高,大部分的JS代码都没问题
- 操作简单
- 不能单独打包运行(除非有node环境)
三.实例
import execjs js_code = execjs.compile(open('js.js','r',encoding='utf-8').read()) result = js_code.call('函数名',参数)result就是函数返回值
2.subprocess + node.exe
一.安装
不需要额外安包。
这是第二好用的包了。
二.特性
subprocess适用最原始的兼容方式。用python直接启动node进程执行JS代码。
- 需要完整的node环境
- 能执行任何JS,兼容性几乎百分百(支持require,fs,crypto......)
- 但是启动慢,用起来会复杂一些
三.实例
python代码
import subprocess param = "hello" result = subprocess.run(["node", "main.js", param], capture_output=True, text=True) print(result.stdout.strip()) main.js
function a_b(x) { return x + "_from_node"; } if (require.main === module) { console.log(a_b(process.argv[2])); } 3.js2py
一.安装
pip install js2py 二.特点
- js2py是纯python实现的JS解释器,脱离于node环境
- 不需要node环境和任何外部解释器
- 但性能一般,只能执行简单JS代码(就比如什么require()导包就会报错)
- 不支持ES6+特性
三.实例
import js2py js = "function add(a, b){return a + b;}" context = js2py.EvalJs() context.execute(js) print(context.add(5, 7)) # 输出: 12 4.PyMiniRacer
一.安装
pip install py_mini_racer 二.特点
- 基于Google V8引擎,不需要node环境就能运行
- 性能强悍
- 适合pyinstaller打包
- 兼容现代JS语法(ES6+)
- 适用于加密算法,签名计算,JS执行等,但不支持node模块体系(require())
三.实例
from py_mini_racer import py_mini_racer ctx = py_mini_racer.MiniRacer() ctx.eval("function a_b(x){return x.toUpperCase();}") print(ctx.call("a_b", "hello")) # 输出: HELLO 5.quickjs
这个包就不怎么常见的,我基本上不怎么用
一.安装
pip install quickjs 二.特点
- 也是纯python内嵌的,无需node环境
- 性能好,内存小
- 轻量、现代语法支持
- 适用独立的QuickJS引擎(QuickJS 是一个体积小巧、可嵌入的 Javascript 引擎。它支持 ES2023规范,包括模块、异步生成器、代理和 BigInt。)
- 但不支持node的require(),不支持DOM......
三.实例
import quickjs ctx = quickjs.Context() ctx.eval("function a_b(x){return x + ' world';}") print(ctx.call("a_b", "hello")) # 输出: hello world 6.dukpy
一.安装
pip install dukpy 二.特点
- 不依赖node环境
- 运行快,内存小
- 小巧、安全嵌入式
- 不支持复杂JS特性(如import,export)
三.实例
import dukpy result = dukpy.evaljs(""" function test(x){return x + 100;} test(23); """) print(result) # 输出: 123 7.pyinstaller打包node环境
当我们要打包python程序时,而里面又用到了js代码,而我们正好用的execjs加载的js代码。
我们用pyinstaller打包,如下。
pyinstaller -F main.py --add-data "main.js;."这样得到的exe执行文件,若给到没用node环境的人执行就会报语法错误,就是因为他没有环境.
若是简单的js加密还行,我们直接用PyMiniRacer或其它不需要node环境的包,代替打包就行。
但如果我们的js代码很复杂,用到了require()包,或者是js逆向补环境来的等等等。
这时候打包最后就连带着node环境一起打包.这样即使是没任何环境的人也能执行打包后的exe文件。
我们将node.exe放到相同目录node文件下,然后打包
pyinstaller -F main.py --add-data "main1.js;." --add-data "main2.js;." --add-data "node/;node"
如果用到了更多js文件,照着这格式写就行。
以上便是这期全部内容,感谢观看。
六、免责声明
本文仅用于网络通信与数据序列化协议的学习、研究与交流。
文中示例均为自建或公开协议示例,不涉及任何实际平台的接口调用或逆向分析。
禁止读者将本文所述技术用于未授权的数据抓取、破解或商业用途。
作者不对任何滥用行为承担法律责任。