Python 调用 JS 的四种主流方式详解

Miles
Miles
发布时间:2026-10-15 | 6人浏览过
原创

本文详细介绍Python调用JavaScript代码的四种常用方式。通过PyExecJS利用本地JS环境执行,js2py实现纯Python解释器转换,Node.js命令直接调用,以及PyV8封装Chrome V8引擎。文章对比了各方案的优缺点及适用场景,适用于Web爬虫参数加密逆向等实际需求。

1. 前言

在进行Web端爬虫开发时,经常遇到请求参数经过加密的情况。为了获取正确数据,必须深入分析网页源代码。

通过调试工具逐步剥离出关键的JavaScript逻辑,随后使用Python执行这段JS代码,从而复现参数加密前后的处理流程。

本文将重点探讨利用Python调用JavaScript代码的4种具体实现方式。

2. 准备

为了演示,我们准备一段简单的JavaScript脚本,并将其保存为文件。


//norm.js
//计算两个数的和
function add(num1, num2) {
    return num1 + num2;
}

该脚本中定义了一个基础方法,用于计算两个数值的和。

3. 方式一:PyExecJS

PyExecJS是目前使用频率较高的一种方案,其底层原理是在本地JS运行环境中执行JS代码。它支持的JS环境包括Node.js、PyV8、PhantomJS、Nashorn等。首先,需要安装依赖包PyExecJS。


//py_exec_js_demo.py

//安装依赖
pip3 install PyExecJS

接着,从JS文件中读取源代码字符串。


def js_from_file(file_name):
    """
    读取js文件
    :return:
    """
    with open(file_name, 'r', encoding='UTF-8') as file:
        result = file.read()

    return result

随后,使用execjs类的compile()方法编译并加载上述JS字符串,该方法会返回一个上下文对象。


import execjs

from js_code import *

# 编译加载js字符串
context1 = execjs.compile(js_from_file('./norm.js'))

最后,调用该上下文对象的call()方法来执行具体的JS函数。参数部分包括JS代码中被调用的方法名,以及传递给该方法的实际参数。


# 调用js代码中的add()方法,参数为2和3
# 方法名:add
# 参数:2和3
result1 = context1.call("add", 2, 3)

print(result1)

需要注意的是,由于PyExecJS依赖本地JS环境,每次使用前都会启动相应的JS环境,这可能导致运行速度相对较慢。更多功能细节可参考: https://github.com/doloopwhile/PyExecJS

4. 方式二:js2py

js2py是一个纯Python实现的JS解释器,它能够完全脱离本地JS环境,直接将JS代码转换为Python代码执行。

首先,安装相应的依赖库。


# 安装依赖库
pip3 install js2py

然后,使用js2py中的EvalJs()方法生成一个上下文对象。


# 使用获取上下js2py生成一个上下文环境
context = js2py.EvalJs()

接着,利用该上下文对象执行JS脚本,将其转换为Python可执行的代码形式。


# 执行整段JS代码
context.execute(js_content)

最后,通过上下文对象调用JS中的具体方法,并指定相应的输入参数即可完成调用。


# 使用上下文context调用具体的函数
# 函数名:add
# 参数:1,2
result = context.add(1, 2)
print(result)

需要留意的是,如果JS代码经过高度混淆,在转换为Python的过程中可能会遇到报错。

更多功能可参考:

https://github.com/PiotrDabkowski/Js2Py

5. 方式三:Node.js

这种方式本质上是利用Python的os.popen执行node命令,从而运行JS脚本。

首先,确保本地环境已安装Node.js。

修改JS脚本,新增一个名为init的导出函数,以便内部函数能够被外部调用。


//计算两个数的和
function add(num1, num2) {
    return num1 + num2;
}

//新增一个导出函数(node方式)
module.exports.init = function (arg1, arg2) {
    //调用函数,并返回
    console.log(add(arg1, arg2));
};

然后,将调用JS方法的命令拼接成一个字符串。


# 组成调用js的命令
# node命令:node -e
cmd = 'node -e "require(\\"%s\\").init(%s,%s)"' % ('./norm', 3, 5)

最后,通过os.popen执行该命令字符串即可获取结果。


pipeline = os.popen(cmd)

# 读取结果
result = pipeline.read()

print('结果是:', result)

6. 方式四:PyV8

PyV8是Google将Chrome V8引擎封装为Python依赖库的项目。

它不依赖本地JS环境,因此运行速度非常快。


import PyV8
from js_code import js_from_file

with PyV8.JSContext() as ctx:
    ctx.eval(js_from_file('./norm.js'))

# 调用js函数,指定参数
ctx.locals.add(1, 2)

更多功能可参考:

https://github.com/emmetio/pyv8-binaries

7. 最后

以上总结了Python调用JavaScript的4种主要方式。

在实际爬虫项目中,建议先使用node命令进行初步测试,确认逻辑无误后,再选择前3种方式中的任意一种进行Python代码改写。

示例代码地址:https://github.com/xingag/tools_python/tree/master/Python%E6%89%A7%E8%A1%8CJS%E6%80%BB%E7%BB%93

以上就是python 调用js的四种方式的详细内容,更多关于python 调用js的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表