You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyInstaller编译后Playwright调用Edge持久化上下文遇TargetClosedError

PyInstaller编译后Playwright启动Edge持久化上下文抛出TargetClosedError

PyInstaller编译Python脚本后,生成的可执行文件无法通过Playwright启动Microsoft Edge的持久化浏览器上下文,抛出TargetClosedError异常。相同代码在虚拟环境中作为普通Python脚本运行完全正常。问题几乎持续出现,但调试时(添加消息框、暂停等操作)偶尔能成功,推测存在竞态条件。

此前使用executable_path和launch_persistent_context的方式可正常工作(最后一次成功是2025年2月,编译版本为2024年4月),环境未做重大变更,但Microsoft Edge可能已更新,且本次在新电脑上编译(Python版本同为3.12)。已通过connect_over_cdp实现功能并验证稳定性,现希望恢复使用持久化上下文与executable_path的方式。

最小可复现示例(test.py)

import os
import asyncio
from playwright.async_api import async_playwright

async def main():
    executable_path = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
    base_dir = os.getcwd()
    user_data_dir = os.path.join(base_dir, "User Data")
    os.makedirs(user_data_dir, exist_ok=True)
    
    async with async_playwright() as p:
        context = await p.chromium.launch_persistent_context(
            user_data_dir=user_data_dir,
            headless=False,
            executable_path=executable_path,
        )
        page = await context.new_page()
        await page.goto("https://google.com")
        # Wait a few seconds to observe the browser window
        await asyncio.sleep(5)
        print("Page title:", await page.title())
        await context.close()

if __name__ == "__main__":
    asyncio.run(main())

编译后运行时回溯信息

Traceback (most recent call last):
  File "test.py", line 24, in <module>
  File "asyncio\runners.py", line 194, in run
  File "asyncio\runners.py", line 118, in run
  File "asyncio\base_events.py", line 686, in run_until_complete
  File "test.py", line 11, in main
  File "playwright\async_api\_generated.py", line 14681, in launch_persistent_context
  File "playwright\_impl\_browser_type.py", line 159, in launch_persistent_context
  File "playwright\_impl\_connection.py", line 61, in send
  File "playwright\_impl\_connection.py", line 528, in wrap_api_call
playwright._impl._errors.TargetClosedError: BrowserType.launch_persistent_context: Target page, context or browser has been closed
Browser logs:

<launching> C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe --disable-field-trial-config --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync,Translate,HttpsUpgrades,PaintHolding,ThirdPartyStoragePartitioning,LensOverlay,PlzDedicatedWorker --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --no-sandbox --user-data-dir=C:\Users\[username]\Desktop\Playwright_Test\dist\test\User Data --remote-debugging-pipe about:blank
<launched> pid=21472
[pid=21472] <process did exit: exitCode=0, signal=null>
[pid=21472] starting temporary directories cleanup
Call log:
  - <launching> C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe --disable-field-trial-config --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync,Translate,HttpsUpgrades,PaintHolding,ThirdPartyStoragePartitioning,LensOverlay,PlzDedicatedWorker --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --no-sandbox --user-data-dir=C:\Users\[username]\Desktop\Playwright_Test\dist\test\User Data --remote-debugging-pipe about:blank
  -   - <launched> pid=21472
  -   - [pid=21472] <process did exit: exitCode=0, signal=null>
  -   - [pid=21472] starting temporary directories cleanup

编译脚本(build.bat)

call venv\scripts\activate
set PLAYWRIGHT_BROWSERS_PATH=0
pyinstaller --noconsole test.py

编译输出

207 INFO: PyInstaller: 6.11.1, contrib hooks: 2024.11
207 INFO: Python: 3.12.8
242 INFO: Platform: Windows-11-10.0.22631-SP0
242 INFO: Python environment: C:\Program Files\Python312
244 INFO: wrote C:\Users\[username]\Desktop\Playwright_Test\test.spec
247 INFO: Module search paths (PYTHONPATH):
['C:\\Program Files\\Python312\\Scripts\\pyinstaller.exe',
 'C:\\Program Files\\Python312\\python312.zip',
 'C:\\Program Files\\Python312\\DLLs',
 'C:\\Program Files\\Python312\\Lib',
 'C:\\Program Files\\Python312',
 'C:\\Users\\[username]\\AppData\\Roaming\\Python\\Python312\\site-packages',
 'C:\\Program Files\\Python312\\Lib\\site-packages',
 'C:\\Program Files\\Python312\\Lib\\site-packages\\win32',
 'C:\\Program Files\\Python312\\Lib\\site-packages\\win32\\lib',
 'C:\\Program Files\\Python312\\Lib\\site-packages\\Pythonwin',
 'C:\\Program Files\\Python312\\Lib\\site-packages\\setuptools\\_vendor',
 'C:\\Users\\[username]\\Desktop\\Playwright_Test']
717 INFO: checking Analysis
739 INFO: Building because inputs changed
739 INFO: Running Analysis Analysis-00.toc
739 INFO: Target bytecode optimization level: 0
739 INFO: Initializing module dependency graph...
742 INFO: Initializing module graph hook caches...
749 INFO: Analyzing base_library.zip ...
2152 INFO: Processing standard module hook 'hook-encodings.py' from 'C:\\Program Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks'
3239 INFO: Processing standard module hook 'hook-pickle.py' from 'C:\\Program Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks'
3710 INFO: Processing standard module hook 'hook-heapq.py' from 'C:\\Program Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks'
3921 INFO: Caching module dependency graph...
3987 INFO: Looking for Python shared library...
3997 INFO: Using Python shared library: C:\Program Files\Python312\python312.dll
3997 INFO: Analyzing C:\Users\[username]\Desktop\Playwright_Test\test.py
4085 INFO: Processing standard module hook 'hook-multiprocessing.util.py' from 'C:\\Program Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks'
4166 INFO: Processing standard module hook 'hook-xml.py' from 'C:\\Program Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks'
4496 INFO: Processing standard module hook 'hook-playwright.async_api.py' from 'C:\\Program Files\\Python312\\Lib\\site-packages\\playwright\\_impl\\__pyinstaller'
4859 INFO: Processing standard module hook 'hook-platform.py' from 'C:\\Program Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks'
5025 INFO: Processing module hooks (post-graph stage)...
5143 INFO: Performing binary vs. data reclassification (343 entries)
5219 INFO: Looking for ctypes DLLs
5225 INFO: Analyzing run-time hooks ...
5228 INFO: Including run-time hook 'pyi_rth_inspect.py' from 'C:\\Program Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks'
5231 INFO: Including run-time hook 'pyi_rth_pkgutil.py' from 'C:\\Program Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks'
5231 INFO: Including run-time hook 'pyi_rth_multiprocessing.py' from 'C:\\Program Files\\Python312\\Lib\\site-packages\\PyInstaller\\hooks\\rthooks'
5239 INFO: Looking for dynamic libraries
5465 INFO: Extra DLL search directories (AddDllDirectory): []
5471 INFO: Extra DLL search directories (PATH): []
5714 INFO: Warnings written to C:\Users\[username]\Desktop\Playwright_Test\build\test\warn-test.txt
5729 INFO: Graph cross-reference written to C:\Users\[username]\Desktop\Playwright_Test\build\test\xref-test.html
5753 INFO: checking PYZ
5774 INFO: Building because name changed
5774 INFO: Building PYZ (ZlibArchive) C:\Users\[username]\Desktop\Playwright_Test\build\test\PYZ-00.pyz
6099 INFO: Building PYZ (ZlibArchive) C:\Users\[username]\Desktop\Playwright_Test\build\test\PYZ-00.pyz completed successfully.
6105 INFO: checking PKG
6114 INFO: Building because name changed
6114 INFO: Building PKG (CArchive) test.pkg
6132 INFO: Building PKG (CArchive) test.pkg completed successfully.
6136 INFO: Bootloader C:\Program Files\Python312\Lib\site-packages\PyInstaller\bootloader\Windows-64bit-intel\runw.exe
6136 INFO: checking EXE
6175 INFO: Building because name changed
6179 INFO: Building EXE from EXE-00.toc
6179 INFO: Copying bootloader EXE to C:\Users\[username]\Desktop\Playwright_Test\build\test\test.exe
6325 WARNING: Execution of 'remove_all_resources' failed on attempt #1 / 20: error(110, 'EndUpdateResourceW', 'The system cannot open the device or file specified.'). Retrying in 0.05 second(s)...
6380 INFO: Copying icon to EXE
6397 INFO: Copying 0 resources to EXE
6397 INFO: Embedding manifest in EXE
6538 INFO: Appending PKG archive to EXE
6541 WARNING: Execution of '_append_data_to_exe' failed on attempt #1 / 20: PermissionError(13, 'Permission denied'). Retrying in 0.05 second(s)...
6597 WARNING: Execution of '_append_data_to_exe' failed on attempt #2 / 20: PermissionError(13, 'Permission denied'). Retrying in 0.06 second(s)...
6654 WARNING: Execution of '_append_data_to_exe' failed on attempt #3 / 20: PermissionError(13, 'Permission denied'). Retrying in 0.06 second(s)...
6714 WARNING: Execution of '_append_data_to_exe' failed on attempt #4 / 20: PermissionError(13, 'Permission denied'). Retrying in 0.06 second(s)...
6954 INFO: Fixing EXE headers
7658 INFO: Building EXE from EXE-00.toc completed successfully.
7661 INFO: checking COLLECT
WARNING: The output directory "C:\Users\[username]\Desktop\Playwright_Test\dist\test" and ALL ITS CONTENTS will be REMOVED! Continue? (y/N)y
On your own risk, you can use the option `--noconfirm` to get rid of this question.
10946 INFO: Removing dir C:\Users\[username]\Desktop\Playwright_Test\dist\test
11021 INFO: Building COLLECT COLLECT-00.toc
11682 INFO: Building COLLECT COLLECT-00.toc completed successfully.

依赖清单(requirements.txt)

et_xmlfile==2.0.0
greenlet==3.1.1
numpy==2.2.1
openpyxl==3.1.5
pandas==2.2.3
playwright==1.49.1
pyee==12.0.0
PySide6==6.8.1.1
PySide6_Addons==6.8.1.1
PySide6_Essentials==6.8.1.1
python-dateutil==2.9.0.post0
pytz==2024.2
shiboken6==6.8.1.1
six==1.17.0
typing_extensions==4.12.2
tzdata==2024.2

可能的解决方案

1. 开启控制台输出调试

去掉编译脚本中的--noconsole参数,让可执行文件显示控制台窗口,观察Edge启动时的实时日志,排查隐藏的启动失败原因:

pyinstaller test.py

2. 添加初始化延迟缓解竞态条件

在启动Playwright上下文前添加短暂延迟,模拟调试时的暂停效果,验证是否为进程启动时序问题:

async def main():
    executable_path = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
    base_dir = os.getcwd()
    user_data_dir = os.path.join(base_dir, "User Data")
    os.makedirs(user_data_dir, exist_ok=True)
    
    # 添加2秒延迟
    await asyncio.sleep(2)
    
    async with async_playwright() as p:
        context = await p.chromium.launch_persistent_context(
            user_data_dir=user_data_dir,
            headless=False,
            executable_path=executable_path,
        )
        # 后续代码不变

3. 改用TCP端口进行调试通信

替换默认的管道通信为TCP端口,可能解决编译后进程间通信的竞态问题:

context = await p.chromium.launch_persistent_context(
    user_data_dir=user_data_dir,
    headless=False,
    executable_path=executable_path,
    args=["--remote-debugging-port=9222"]
)

4. 锁定Edge版本到历史兼容版本

如果是Edge更新导致的兼容性问题,可下载并安装2025年2月前后的Edge稳定版,然后指定该版本的executable_path路径。

5. 手动完善PyInstaller spec文件

检查生成的test.spec文件,确保Playwright的钩子资源完整加载,必要时手动调用钩子函数:

a = Analysis(
    'test.py',
    # 其他参数保持不变
)
# 手动调用Playwright钩子确保资源打包
from playwright._impl.__pyinstaller import hook_playwright_async_api
hook_playwright_async_api(a)

内容的提问来源于stack exchange,提问作者karga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 23:27:26