杰瑞科技汇

Python如何直接执行JavaScript代码?

使用 PyExecJS (最简单、通用)

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

Python如何直接执行JavaScript代码?-图1
(图片来源网络,侵删)

优点:

  • 安装简单,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 来执行代码。

Python如何直接执行JavaScript代码?-图2
(图片来源网络,侵删)

优点:

  • 直接利用 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 执行的原理。

Python如何直接执行JavaScript代码?-图3
(图片来源网络,侵删)

使用 SeleniumPlaywright (与真实浏览器交互)

这是最强大、最复杂的方法,当你需要执行依赖浏览器环境的 JavaScript 代码时(获取渲染后的页面内容、操作 DOM、触发事件),必须使用这种方法。

SeleniumPlaywright 都是 Web 自动化测试工具,它们可以启动一个真实的浏览器(或无头浏览器),然后让你通过 Python 控制这个浏览器,并执行任意 JS 代码。

优点:

  • 功能最强大,可以模拟真实用户的所有操作。
  • 能访问完整的浏览器 API (window, document, fetch, localStorage 等)。
  • Playwright 在性能和稳定性上通常优于 Selenium。

缺点:

  • 设置最复杂,需要下载浏览器驱动。
  • 运行速度慢,不适合简单的 JS 计算。

Selenium 示例

  1. 安装库和浏览器驱动:

    pip install selenium
    # 下载 ChromeDriver: https://chromedriver.chromium.org/downloads
    # 确保chromedriver.exe在系统PATH中,或指定其路径
  2. 代码示例:

    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 爬虫和测试任务

如何选择?

  1. 如果只是想运行一小段 JS 代码(比如加密、解密、计算)

    • 首选 PyExecJS,最简单快捷。
  2. 如果你的 JS 代码依赖于 Node.js 的特定模块(如 fs, path, 或某个 npm 包)

    • 使用 nodejs 库。
  3. 如果你的 JS 代码必须在浏览器中运行(比如获取 AJAX 加载的数据、操作 DOM、localStorage

    • 选择 SeleniumPlaywright/Pyppeteer,Playwright/Pyppeteer 通常是更新的、更优的选择。

希望这个详细的指南能帮助你根据需求选择最合适的工具!

分享:
扫描分享到社交APP
上一篇
下一篇