使用 PyExecJS (最简单、通用)
PyExecJS 是一个通用的 JavaScript 解释器封装库,它不直接运行 JS,而是作为桥梁,调用你系统上已有的 JavaScript 运行环境(如 Node.js、PyV8、JavaScriptCore 等),这是最轻量级、最简单的入门方式。

优点:
- 安装简单,
pip install pyexecjs即可。 - 语法简单,上手快。
- 支持多种 JS 运行环境。
缺点:
- 性能不如原生环境。
- 对于复杂的浏览器 API(如
window,document,fetch)无法支持。
安装
pip install pyexecjs
使用示例
确保你的系统上安装了 JavaScript 运行环境,最常见的是 Node.js,安装 Node.js 后,PyExecJS 会自动找到它。
import execjs
# 1. 直接执行一段 JavaScript 代码
js_code = """
function add(a, b) {
return a + b;
}
var result = add(10, 20);
result; // 最后一个表达式的结果会作为返回值
"""
ctx = execjs.compile(js_code)
print(f"10 + 20 = {ctx.eval('result')}") # 输出: 10 + 20 = 30
# 2. 调用 JavaScript 函数并传递参数
js_code2 = """
function greet(name) {
return 'Hello, ' + name + '!';
}
"""
ctx2 = execjs.compile(js_code2)
greeting = ctx2.call('greet', 'Python')
print(greeting) # 输出: Hello, Python!
# 3. 从文件加载并执行 JS 代码
# 假设有一个 math.js 文件,内容如下:
# function multiply(x, y) { return x * y; }
with open('math.js', 'r', encoding='utf-8') as f:
js_file_content = f.read()
ctx3 = execjs.compile(js_file_content)
product = ctx3.call('multiply', 7, 8)
print(f"7 * 8 = {product}") # 输出: 7 * 8 = 56
使用 nodejs 库 (调用 Node.js)
如果你只需要 Node.js 的功能,可以使用 nodejs 这个库,它通过子进程的方式调用你系统中的 Node.js 来执行代码。

优点:
- 直接利用 Node.js 强大的生态系统(可以安装任何 npm 包)。
- 对于纯 Node.js 环境下的任务非常高效。
缺点:
- 需要系统安装 Node.js。
- 启动子进程有一定开销,不适合高频调用。
安装
pip install nodejs
使用示例
from nodejs import eval_js
# 直接执行 JS 代码
# Node.js 中,console.log 是向标准输出打印,而不是返回值
# eval_js 会捕获标准输出
result = eval_js("console.log('Hello from Node.js!'); 2 + 2;")
print(f"JS 执行结果: {result}")
# 输出:
# Hello from Node.js!
# JS 执行结果: 4
# 调用函数
js_code = """
function factorial(n) {
if (n === 0 || n === 1) {
return 1;
}
return n * factorial(n - 1);
}
"""
# eval_js 也可以编译代码
factorial_result = eval_js(js_code + "factorial(5);")
print(f"5! = {factorial_result}") # 输出: 5! = 120
# 使用 npm 包
# 使用 lodash 的 _.cloneDeep
deep_clone_result = eval_js("""
const _ = require('lodash');
const original = { a: 1, b: { c: 2 } };
const cloned = _.cloneDeep(original);
cloned.b.c = 3;
JSON.stringify(cloned);
""")
print(f"深拷贝后的对象: {deep_clone_result}")
# 输出: 深拷贝后的对象: {"a":1,"b":{"c":3}}
使用 PyV8 (高性能,但已停止维护)
PyV8 是 Google V8 JavaScript 引擎的 Python 封装,性能极高,因为它直接在 Python 进程中运行 JS,无需启动子进程。
警告: PyV8 项目已经多年没有更新,不兼容新版 Python 和 V8 引擎,不推荐在新项目中使用,但了解它有助于理解 JS 执行的原理。

使用 Selenium 或 Playwright (与真实浏览器交互)
这是最强大、最复杂的方法,当你需要执行依赖浏览器环境的 JavaScript 代码时(获取渲染后的页面内容、操作 DOM、触发事件),必须使用这种方法。
Selenium 和 Playwright 都是 Web 自动化测试工具,它们可以启动一个真实的浏览器(或无头浏览器),然后让你通过 Python 控制这个浏览器,并执行任意 JS 代码。
优点:
- 功能最强大,可以模拟真实用户的所有操作。
- 能访问完整的浏览器 API (
window,document,fetch,localStorage等)。 - Playwright 在性能和稳定性上通常优于 Selenium。
缺点:
- 设置最复杂,需要下载浏览器驱动。
- 运行速度慢,不适合简单的 JS 计算。
Selenium 示例
-
安装库和浏览器驱动:
pip install selenium # 下载 ChromeDriver: https://chromedriver.chromium.org/downloads # 确保chromedriver.exe在系统PATH中,或指定其路径
-
代码示例:
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By # 指定 chromedriver 的路径 (如果不在PATH中) # service = Service(executable_path='path/to/your/chromedriver') # driver = webdriver.Chrome(service=service) # chromedriver 在PATH中,可以直接这样启动 driver = webdriver.Chrome() try: # 1. 打开一个网页 driver.get("https://www.example.com") # 2. 在当前页面的上下文中执行 JavaScript # 这是关键方法:execute_script(script, *args) # 获取页面标题 title = driver.execute_script("return document.title;") print(f"页面标题: {title}") # 输出: 页面标题: Example Domain # 获取页面的 URL url = driver.execute_script("return window.location.href;") print(f"页面URL: {url}") # 输出: 页面URL: https://www.example.com/ # 修改页面元素内容 heading = driver.execute_script("return document.querySelector('h1').textContent;") print(f"原始标题文本: {heading}") # 输出: 原始标题文本: Example Domain # 执行 JS 修改 h1 标签内容 driver.execute_script("document.querySelector('h1').innerText = '标题被Python修改了!';") # 再次获取验证 new_heading = driver.find_element(By.TAG_NAME, "h1").text print(f"修改后标题文本: {new_heading}") # 输出: 修改后标题文本: 标题被Python修改了! finally: # 3. 关闭浏览器 driver.quit()
使用 Pyppeteer (Playwright 的 Python 封装)
Pyppeteer 是 Google Chrome 开发团队推出的无头 Chrome 的 Python 封装,可以看作是 Selenium 的一个现代化替代品。
优点:
- 性能通常比 Selenium 好。
- 与 Chrome 的集成度更高,更新更及时。
- API 设计更现代化。
缺点:
- 依赖 Chromium 浏览器,包体积较大。
安装
pip install pyppeteer # 首次运行时会自动下载 Chromium 浏览器
使用示例
import asyncio
from pyppeteer import launch
async def main():
# 启动一个无头浏览器
browser = await launch(headless=True)
page = await browser.newPage()
# 设置视口大小
await page.setViewport({'width': 1024, 'height': 768})
await page.goto('https://example.com')
# 执行 JavaScript 代码= await page.evaluate('() => document.title')
print(f"页面标题: {title}") # 输出: 页面标题: Example Domain
# 修改页面元素
await page.evaluate('() => document.querySelector("h1").innerText = "标题被 Pyppeteer 修改了!"')
new_heading = await page.querySelectorEval('h1', 'el => el.innerText')
print(f"修改后标题文本: {new_heading}") # 输出: 修改后标题文本: 标题被 Pyppeteer 修改了!
await browser.close()
# 运行异步主函数
asyncio.get_event_loop().run_until_complete(main())
总结与如何选择
| 方法 | 主要用途 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|---|
| PyExecJS | 执行简单的 JS 函数、代码片段 | 轻量级,安装简单,通用 | 性能一般,无法访问浏览器 API | 快速计算、解析 JS 配置文件、处理加密逻辑 |
| nodejs | 运行 Node.js 环境下的 JS | 可用 npm 生态,功能强大 | 依赖 Node.js,有子进程开销 | 需要使用特定 npm 包(如 crypto, moment)的脚本 |
| Selenium / Playwright | 与真实浏览器交互 | 功能最全,能模拟用户操作 | 设置复杂,运行速度慢 | Web 爬虫(动态渲染页面)、UI 自动化测试、需要操作 DOM 的场景 |
| Pyppeteer | 与无头 Chrome 交互 | 性能好,API 现代化 | 依赖 Chromium | 对性能和自动化要求高的 Web 爬虫和测试任务 |
如何选择?
-
如果只是想运行一小段 JS 代码(比如加密、解密、计算):
- 首选 PyExecJS,最简单快捷。
-
如果你的 JS 代码依赖于 Node.js 的特定模块(如
fs,path, 或某个 npm 包):- 使用
nodejs库。
- 使用
-
如果你的 JS 代码必须在浏览器中运行(比如获取 AJAX 加载的数据、操作 DOM、
localStorage):- 选择 Selenium 或 Playwright/Pyppeteer,Playwright/Pyppeteer 通常是更新的、更优的选择。
希望这个详细的指南能帮助你根据需求选择最合适的工具!
