如何在Python中运行JS代码(PyExecJS、Node.js、js2py速度对比)

本文介绍了在Python中调用JavaScript加密函数的三种方法:PyExecJS、Node.js和js2py,并提供了每种方法的使用示例。通过速度测试,发现Node.js的执行速度最快,而js2py最慢。此外,还提到了PyV8在Python3.9上的兼容性问题。

前言

写某自动化脚本时某统一认证系统 CAS (Central Authentication Service) 登录时采用了 js 对用户名和密码进行前端加密。
大致就是这么个东西:(╯°□°)╯︵ ┻━┻
function strEnc(data,firstKey,secondKey,thirdKey) 需要3个 key,似乎并不是常见的 DES加密。
在这里插入图片描述
因为比较着急用这个自动化程序,所以暂时不打算研究这段 867 行的代码。
于是找到了几个方便的在 Python 中调用 js 的好方法。
这里 PyV8 在 Python 3.9 测试会报错,官网只有 3.3 版本的,据说最高支持3.7(未测试),所以这里就不测试了。

PyExecJS

在 Python 中使用本地 js 环境运行代码。
虽然目前已经停止更新维护了,不过还能用。

安装:

pip install PyExecJS

用法:

import execjs

context = execjs.compile(jsContent)
result = context.call("functionName", 'param1', 'param2')

官方文档:https://github.com/doloopwhile/PyExecJS

Node.js

相当于用 node 命令执行 js 脚本,需要导出模块 (module.exports)。
安装:直接在 nodejs 官网下载安装包安装即可。

用法:

import os

pipeline = os.popen("node -e \"require('./jsFileName.js').functionName('param1','param2')\"")
result = pipeline.read().strip()

注意:此方法读出的输出结尾可能多一个空行。

js2py

纯 Python 写的 js 解释器,甚至支持把 js 代码直接翻译成 Python 代码。

安装:

pip install js2py

用法:

import js2py

context = js2py.EvalJs()
context.execute(jsContent)
result = context.functionName('param1', 'param2')

官方文档:https://github.com/PiotrDabkowski/Js2Py

速度测试

测试代码:

import time

def readJson(file_name):
    with open(file_name, 'r', encoding='UTF-8') as file:
        result = file.read()
    return result
js = readJson("des.js")
data = "string"
time.sleep(1)

print("---- Test of execjs ----")
T1 = time.perf_counter()
import execjs
context1 = execjs.compile(js)
res = context1.call("strEnc", data, '1', '2', '3')
T2 = time.perf_counter()
print("result: " + res)
print("Time: " + str((T2 - T1)*1000) + " ms.")
print("---- End of Test ----\n")

print("---- Test of js2py ----")
T1 = time.perf_counter()
import js2py
jsContext = js2py.EvalJs()
jsContext.execute(js)
rsa = jsContext.strEnc(data,'1','2','3')
T2 = time.perf_counter()
print("result: " + res)
print("Time: " + str((T2 - T1)*1000) + " ms.")
print("---- End of Test ----\n")

print("---- Test of nodejs ----")
jsn = js + '''
module.exports.strEnc = function(a,b,c,d) {
  console.log(strEnc(a,b,c,d));
};
'''
with open("test.js", "w") as f:
    f.write(jsn)
T1 = time.perf_counter()
import os
pipeline = os.popen(f"node -e \"require('./test.js').strEnc('{data}','1','2','3')\"")
res = pipeline.read().strip()
T2 = time.perf_counter()
print("result: " + res)
print("Time: " + str((T2 - T1)*1000) + " ms.")
print("---- End of Test ----\n")



print("---- Test of js2py translate ----")
T1 = time.perf_counter()
import js2py
js2py.translate_file('des.js', 'testPython.py')
T2 = time.perf_counter()
print("Translation ime: " + str((T2 - T1)*1000) + " ms.")

T1 = time.perf_counter()
import testPython
res = testPython.PyJsHoisted_strEnc_(data,'1','2','3')
T2 = time.perf_counter()
print("result: " + str(res))
print("Execute translated js: " + str((T2 - T1)*1000) + " ms.")
print("---- End of Test ----\n")

运行结果:

---- Test of execjs ----
result: 60755BA85B594627F34E71F4A9129CBF
Time: 512.5649999999999 ms.
---- End of Test ----

---- Test of js2py ----
result: 60755BA85B594627F34E71F4A9129CBF
Time: 2812.4174999999996 ms.
---- End of Test ----

---- Test of nodejs ----
result: 60755BA85B594627F34E71F4A9129CBF
Time: 113.34299999999953 ms.
---- End of Test ----

---- Test of js2py translate ----
Translation ime: 129.64780000000076 ms.
result: '60755BA85B594627F34E71F4A9129CBF'
Execute translated js: 2133.1337000000003 ms.
---- End of Test ----
<think>我们正在讨论的是在Python环境中运行JavaScript文件(pa.js)时出现的“找不到解释器”错误。根据用户的问题,我们需要理解为什么在Python运行JavaScript文件会出错,并提供解决方案。 首先,明确一点:Python解释器不能直接执行JavaScript代码。它们是两种不同的语言,需要各自对应的解释器。因此,当尝试在Python环境中运行JavaScript文件时,会出现“找不到解释器”的错误,因为Python解释器无法解析JavaScript语法。 ### 错误原因分析 1. **语言不兼容**:Python解释器只能执行Python代码,而pa.jsJavaScript文件,因此无法直接运行2. **执行方式错误**:用户可能试图使用类似`python pa.js`的命令来运行,这会导致错误,因为Python解释器会尝试将JavaScript代码当作Python代码来解析,从而失败。 ### 解决方案 要正确运行JavaScript文件,需要使用JavaScript运行环境,例如Node.js或浏览器。以下是两种常见的解决方案: #### 方案1:使用Node.js运行JavaScript文件 1. **安装Node.js**: - 访问Node.js官网(https://nodejs.org)下载并安装适合你操作系统的版本。 2. **运行JavaScript文件**: - 打开终端(或命令提示符),导航到pa.js所在的目录,然后运行以下命令: ```bash node pa.js ``` #### 方案2:在浏览器中运行JavaScript 1. **创建HTML文件**: - 在pa.js同一目录下创建一个HTML文件(例如index.html),并在其中引入pa.js: ```html <!DOCTYPE html> <html> <head> <title>Run JavaScript</title> </head> <body> <script src="pa.js"></script> </body> </html> ``` 2. **在浏览器中打开HTML文件**: - 双击该HTML文件或在浏览器中打开它,浏览器将执行pa.js中的JavaScript代码。 ### 如果需要在Python中调用JavaScript代码 如果用户确实需要在Python程序中执行JavaScript代码,可以使用第三方库来实现。以下是两种常见的方法: #### 方法1:使用`execjs`库 `execjs`库允许在Python中执行JavaScript代码。 1. **安装`execjs`**: ```bash pip install PyExecJS ``` 2. **使用示例**: ```python import execjs # 创建JavaScript环境 context = execjs.compile(""" function add(a, b) { return a + b; } """) # 调用JavaScript函数 result = context.call("add", 1, 2) print(result) # 输出:3 ``` - 如果要执行pa.js文件中的代码,可以读取文件内容并传递给`execjs.compile`。 #### 方法2:使用`node`子进程 通过Python的`subprocess`模块调用Node.js来执行JavaScript文件。 ```python import subprocess # 运行JavaScript文件 result = subprocess.run(['node', 'pa.js'], capture_output=True, text=True) # 输出结果 print(result.stdout) print(result.stderr) ``` ### 总结 - **直接运行**:使用Node.js或浏览器运行JavaScript文件。 - **在Python中集成**:使用`execjs`库或通过子进程调用Node.js。 ### 相关问题 1. 如何在Python中嵌入JavaScript引擎? 2. 如何将JavaScript函数转换为Python函数? 3. 使用Node.js运行JavaScript时出现错误如何调试? 4. 有哪些常见的JavaScript引擎可以在Python中使用? 5. 如何将JavaScript模块导入到Python中?</think>### Python 运行 JavaScript 文件报错解析 您在尝试用 Python 运行 JavaScript 文件 `pa.js` 时出现 **"找不到解释器"** 错误,这是因为: #### 根本原因 **Python 解释器无法直接执行 JavaScript 代码**。两种语言需要不同的运行环境: - Python 需要 Python 解释器(如 CPython) - JavaScript 需要 JS 引擎(如 Node.js 或浏览器 V8 引擎) 错误示意图: ``` $ python pa.js ┌──────────────┐ ┌──────────┐ │ Python解释器 │ ──×─▶ │ pa.js │ └──────────────┘ └──────────┘ (识别.py/.pyw文件) (无法解析.js语法) ``` #### 解决方案 ##### 方法 1:使用 Node.js 运行(推荐) 1. **安装 Node.js** [官网下载](https://nodejs.org/) 并安装(包含 `npm` 和 `node` 命令) 2. **终端执行** ```bash node pa.js ``` ##### 方法 2:在 Python 中调用 JavaScript(需桥接工具) ```mermaid graph LR A[Python程序] --> B[桥接工具] --> C[JavaScript引擎] ``` **常用桥接方案:** 1. **PyExecJS 库** ```python # 安装:pip install PyExecJS import execjs # 读取 JS 文件 with open('pa.js') as f: js_code = f.read() # 执行 JS ctx = execjs.compile(js_code) result = ctx.eval('yourFunction()') # 调用JS函数 ``` 2. **子进程调用 Node.js** ```python import subprocess result = subprocess.run( ['node', 'pa.js'], capture_output=True, text=True ) print(result.stdout) ``` 3. **浏览器引擎(如 Pyppeteer)** 适用于网页相关 JS: ```python # 安装:pip install pyppeteer from pyppeteer import launch async def run_js(): browser = await launch() page = await browser.newPage() await page.goto('file:///path/to/pa.js') result = await page.evaluate('() => yourFunction()') await browser.close() return result ``` #### 关键区别总结 | 特性 | Python 文件 (.py) | JavaScript 文件 (.js) | |---------------------|----------------------------|---------------------------| | **执行命令** | `python script.py` | `node script.js` | | **解释器** | CPython/PyPy | Node.js/V8 | | **语法兼容性** | Python 语法 | JavaScript 语法 | | **跨语言调用** | 需桥接工具(如 PyExecJS) | 需桥接工具(如 child_process) | ### 相关问题 1. 如何将 JavaScript 函数转换为 Python 可调用的 API? 2. Node.jsPython 在异步处理机制上有哪些核心差异? 3. 有哪些支持 PythonJavaScript 互操作的高性能框架? 4. 如何调试 Python 中调用的 JavaScript 代码? 5. 在混合开发中如何管理 PythonJavaScript 的依赖冲突? > 提示:对于需要深度集成的场景,可考虑使用 WebAssembly 技术实现跨语言模块化调用[^1]。Python 的扩展性虽支持 C/C++ 模块[^1],但直接执行 JS 仍需专用运行时环境。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值