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

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

前言

写某自动化脚本时某统一认证系统 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 ----

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/717265.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存