欢迎光临
我们一直在努力

教程:将 Python Playwright 脚本打包为独立 Windows EXE (含浏览器内核)

在开发自动化工具或定制化浏览器时,我们经常使用 Python 的 Playwright 库。但如果要将工具分发给非技术用户,要求对方安装 Python 环境、下载对应版本的浏览器内核是非常痛苦的。

本文介绍一种方案:将 Python 代码、Playwright 依赖库以及 Chromium 浏览器内核全部打包进一个独立的 .exe 文件中,实现真正的“零依赖”运行。

核心挑战

Playwright 默认将浏览器二进制文件下载到用户目录(如 %AppData%)。在打包时,我们需要解决两个核心问题:

  • 构建时包含:如何把浏览器文件“塞”进 exe 里?
  • 运行时定位:打包后的程序运行在临时目录,如何告诉 Playwright 去哪里找浏览器?
  • 解决方案

    1. Python 代码适配 (test-01.py)

    我们需要在代码中动态检测当前是否在 PyInstaller 的打包环境中运行。如果是,则将环境变量 PLAYWRIGHT_BROWSERS_PATH 指向解压后的临时目录(sys._MEIPASS)。

    此外,为了更好的用户体验,我们增加了错误捕获:如果程序崩溃(特别是在无控制台模式下),会弹出 Windows 错误对话框,而不是直接静默退出。

    import argparse
    import os
    from pathlib import Path
    import sys
    import time
    import traceback
    from playwright.sync_api import sync_playwright

    SUPPORTED_DEFAULT_DEVICE = "Pixel 5"

    def resolve_browser_root() > Path | None:
    """
    核心逻辑:定位浏览器路径
    1. 如果是打包环境,资源位于 sys._MEIPASS 下的 ms-playwright 目录
    2. 如果是开发环境,可能在环境变量指定位置、当前目录或系统默认目录
    """

    candidates = []
    # PyInstaller 解压临时目录
    if hasattr(sys, "_MEIPASS"):
    candidates.append(Path(sys._MEIPASS) / "ms-playwright")

    # 手动环境变量
    if os.environ.get("PLAYWRIGHT_BROWSERS_PATH"):
    candidates.append(Path(os.environ["PLAYWRIGHT_BROWSERS_PATH"]))

    # 当前目录或默认目录
    candidates.append(Path.cwd() / "ms-playwright")
    candidates.append(Path.home() / "AppData" / "Local" / "ms-playwright")

    for c in candidates:
    if c.exists():
    return c
    return None

    def parse_args() > argparse.Namespace:
    parser = argparse.ArgumentParser(
    description="Launch Chromium in mobile emulation mode."
    )
    parser.add_argument("–url", default="https://doris.apache.org", help="Page to open.")
    parser.add_argument("–device", default=SUPPORTED_DEFAULT_DEVICE, help="Device profile name.")
    parser.add_argument("–headless", action="store_true", help="Run in headless mode.")
    parser.add_argument("–timeout", type=int, default=0, help="Auto-close timeout.")
    return parser.parse_args()

    def launch_mobile(url: str, device_name: str, headless: bool, timeout: int) > None:
    # 动态设置浏览器路径
    browser_root = resolve_browser_root()
    if browser_root:
    os.environ["PLAYWRIGHT_BROWSERS_PATH"] = str(browser_root)

    with sync_playwright() as p:
    devices = p.devices
    if device_name not in devices:
    print(f"Unknown device: {device_name}")
    sys.exit(1)

    browser = p.chromium.launch(headless=headless)
    # 忽略 HTTPS 证书错误,确保内网或测试环境可用
    context = browser.new_context(ignore_https_errors=True, **devices[device_name])
    page = context.new_page()
    page.goto(url)

    print(f"Opened {url} in mobile mode: {device_name}")
    if browser_root:
    print(f"Using bundled browsers at: {browser_root}")

    # 保持运行
    try:
    if timeout > 0:
    time.sleep(timeout)
    else:
    while True:
    time.sleep(1)
    except KeyboardInterrupt:
    pass
    finally:
    browser.close()

    def main():
    try:
    args = parse_args()
    launch_mobile(args.url, args.device, args.headless, args.timeout)
    except Exception:
    # 错误处理:如果是打包环境(无控制台),弹窗提示错误
    if getattr(sys, 'frozen', False):
    import ctypes
    ctypes.windll.user32.MessageBoxW(0, f"Error: {traceback.format_exc()}", "Application Error", 0x10)
    else:
    traceback.print_exc()
    sys.exit(1)

    if __name__ == "__main__":
    main()

    2. 自动化构建脚本 (build_exe.ps1)

    为了简化构建流程,我们编写一个 PowerShell 脚本。它的作用是:

  • 局部下载:将 Chromium 下载到当前项目的临时文件夹 ms-playwright-local,防止污染全局环境。
  • 资源映射:在调用 PyInstaller 时,使用 –add-data 参数,将下载好的 ms-playwright-local 映射打包到 EXE 内部的 ms-playwright 路径。
  • # build_exe.ps1

    # 1. 确保安装依赖
    Write-Host "Installing Python dependencies…"
    pip install playwright pyinstaller

    # 2. 设置本地下载路径,避免影响系统全局配置
    $localBrowserPath = Join-Path (Get-Location) "ms-playwright-local"
    $env:PLAYWRIGHT_BROWSERS_PATH = $localBrowserPath

    # 3. 下载 Chromium 到本地文件夹
    Write-Host "Downloading Chromium to $localBrowserPath…"
    if (Test-Path $localBrowserPath) { Remove-Item Recurse Force $localBrowserPath }
    # 这里会自动下载 Chromium
    python m playwright install chromium

    # 4. 执行 PyInstaller 打包
    Write-Host "Building EXE…"

    # 关键参数解释:
    # –windowed: 隐藏控制台窗口(适合 GUI 程序)
    # –collect-all playwright: 自动收集 Playwright 的库文件
    # –add-data "源路径;目标路径": 将浏览器文件夹打入包内
    pyinstaller noconfirm onefile windowed name mobile_chromium `
    collect-all playwright `
    add-data "$localBrowserPath;ms-playwright" `
    src02/test-01.py

    Write-Host "Build complete! Output: dist/mobile_chromium.exe"

    如何使用

    构建

    在项目根目录下,打开 PowerShell 运行:

    .\\src02\\build_exe.ps1

    分发与运行

    构建完成后,dist 文件夹下的 mobile_chromium.exe 就是我们需要的文件。你可以将其拷贝到任何 Windows 电脑上运行。

    基本用法: 直接双击运行。

    高级用法(命令行):

    # 指定打开百度,模拟 iPhone 13
    .\\mobile_chromium.exe url https://www.baidu.com device "iPhone 13"

    最终效果:
    在这里插入图片描述

    exe文件大小:
    在这里插入图片描述

    总结

    通过这种方式,我们成功将一个复杂的浏览器自动化环境(Python + Playwright + Chromium Binary)压缩成了一个数百MB的单文件 EXE,极大地降低了工具的分发和部署成本。

    赞(0)
    未经允许不得转载:171主机测评 » 教程:将 Python Playwright 脚本打包为独立 Windows EXE (含浏览器内核)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址