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

📅 发布时间:2026/7/6 22:53:06 👁️ 浏览次数:
教程:将 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 错误对话框而不是直接静默退出。importargparseimportosfrompathlibimportPathimportsysimporttimeimporttracebackfromplaywright.sync_apiimportsync_playwright SUPPORTED_DEFAULT_DEVICEPixel 5defresolve_browser_root()-Path|None: 核心逻辑定位浏览器路径 1. 如果是打包环境资源位于 sys._MEIPASS 下的 ms-playwright 目录 2. 如果是开发环境可能在环境变量指定位置、当前目录或系统默认目录 candidates[]# PyInstaller 解压临时目录ifhasattr(sys,_MEIPASS):candidates.append(Path(sys._MEIPASS)/ms-playwright)# 手动环境变量ifos.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)forcincandidates:ifc.exists():returncreturnNonedefparse_args()-argparse.Namespace:parserargparse.ArgumentParser(descriptionLaunch Chromium in mobile emulation mode.)parser.add_argument(--url,defaulthttps://doris.apache.org,helpPage to open.)parser.add_argument(--device,defaultSUPPORTED_DEFAULT_DEVICE,helpDevice profile name.)parser.add_argument(--headless,actionstore_true,helpRun in headless mode.)parser.add_argument(--timeout,typeint,default0,helpAuto-close timeout.)returnparser.parse_args()deflaunch_mobile(url:str,device_name:str,headless:bool,timeout:int)-None:# 动态设置浏览器路径browser_rootresolve_browser_root()ifbrowser_root:os.environ[PLAYWRIGHT_BROWSERS_PATH]str(browser_root)withsync_playwright()asp:devicesp.devicesifdevice_namenotindevices:print(fUnknown device:{device_name})sys.exit(1)browserp.chromium.launch(headlessheadless)# 忽略 HTTPS 证书错误确保内网或测试环境可用contextbrowser.new_context(ignore_https_errorsTrue,**devices[device_name])pagecontext.new_page()page.goto(url)print(fOpened{url}in mobile mode:{device_name})ifbrowser_root:print(fUsing bundled browsers at:{browser_root})# 保持运行try:iftimeout0:time.sleep(timeout)else:whileTrue:time.sleep(1)exceptKeyboardInterrupt:passfinally:browser.close()defmain():try:argsparse_args()launch_mobile(args.url,args.device,args.headless,args.timeout)exceptException:# 错误处理如果是打包环境无控制台弹窗提示错误ifgetattr(sys,frozen,False):importctypes ctypes.windll.user32.MessageBoxW(0,fError:{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-HostInstalling Python dependencies...pip install playwright pyinstaller# 2. 设置本地下载路径避免影响系统全局配置$localBrowserPathJoin-Path(Get-Location)ms-playwright-local$env:PLAYWRIGHT_BROWSERS_PATH $localBrowserPath# 3. 下载 Chromium 到本地文件夹Write-HostDownloading Chromium to$localBrowserPath...if(Test-Path$localBrowserPath){Remove-Item-Recurse-Force$localBrowserPath}# 这里会自动下载 Chromiumpython-m playwright install chromium# 4. 执行 PyInstaller 打包Write-HostBuilding 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.pyWrite-HostBuild 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--deviceiPhone 13最终效果exe文件大小总结通过这种方式我们成功将一个复杂的浏览器自动化环境Python Playwright Chromium Binary压缩成了一个数百MB的单文件 EXE极大地降低了工具的分发和部署成本。