title: “解决 AI Agent 使用 Playwright 频繁下载 Chromium 的问题”
tags:

  • Playwright
  • AI编程
  • 浏览器自动化
  • 开发工具
  • MCP
    categories:
  • 开发工具
    description: “使用 Trae、Cursor 等 AI IDE 的 Playwright MCP 时频繁遇到 Chromium 重复下载问题,本文从原理分析原因,给出 Python Playwright 替代方案、固定版本方案等 4 种解决方案。”

导读:用 Trae/Cursor 等 AI IDE 的 Playwright MCP 功能时,经常遇到 “Executable doesn’t exist” 错误,然后被迫重新下载 100MB+ 的 Chromium。这个问题困扰了我很久,本文分享我踩过的坑和最终解决方案。


一、问题现象

在 Trae IDE 中使用 Playwright MCP 进行浏览器自动化时,经常碰到这样的报错:

Failed to initialize browser: browserType.launch: Executable doesn't exist at
/Users/aiksyuan/Library/Caches/ms-playwright/chromium-1200/chrome-mac-arm64/
Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing

╔═════════════════════════════════════════════════════════════════════════╗
║ Looks like Playwright Test or Playwright was just installed or updated. ║
║ Please run the following command to download new browsers:              ║
║                                                                         ║
║     npx playwright install                                              ║
║                                                                         ║
║ <3 Playwright Team                                                     ║
╚═════════════════════════════════════════════════════════════════════════╝

然后你乖乖运行 npx playwright install,下载了 100 多 MB 的 Chromium。过了几天,MCP 一更新,又来一遍。反反复复,烦不胜烦。

二、为什么会反复下载

要搞清楚这个问题,得先理解 AI IDE 里 Playwright 的运行架构。

2.1 两套独立的 Playwright 系统

你的电脑上其实存在两套 Playwright:

┌─────────────────────────────────────────────────────┐
│  MCP Playwright(AI IDE 用的)                        │
│  ├── 独立的 MCP 服务进程                               │
│  ├── 内置 npm 包 @playwright/mcp                     │
│  ├── 版本随 IDE/MCP 更新自动变化                        │
│  └── 要求 chromium-1200 → chromium-1208 → ...        │
│      存储路径: ~/Library/Caches/ms-playwright/         │
│                  chromium-{版本号}/                    │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│  Python Playwright(你自己装的)                        │
│  ├── pip install playwright                           │
│  ├── 版本由你控制,不自动更新                            │
│  └── chromium_headless_shell-1223                     │
│      同样在: ~/Library/Caches/ms-playwright/           │
└─────────────────────────────────────────────────────┘

关键在于:MCP Playwright 的版本不受你控制

2.2 版本绑定的致命问题

Playwright 的设计是 每个版本绑定特定版本的浏览器。这不是 bug,而是 Playwright 的核心机制——它需要精确控制浏览器的 CDP 协议版本,以保证自动化行为的稳定性。

具体来说:

Playwright 版本 要求的 Chromium 版本 缓存目录
1.52.x chromium-1179 ms-playwright/chromium-1179/
1.53.x chromium-1200 ms-playwright/chromium-1200/
1.54.x chromium-1208 ms-playwright/chromium-1208/

当 MCP 服务更新时(通常跟随 IDE 更新),它内置的 Playwright 版本也跟着变。新版本要求新的 Chromium 版本号,而你的缓存里只有旧的——于是报错,要求重新下载。

这个问题在 GitHub 上也有大量反馈,比如 playwright-mcp#1091 就记录了完整的版本不匹配问题。

2.3 根本原因总结

MCP 服务更新 → 内置 Playwright 版本变化 → 要求新版本 Chromium → 缓存里没有 → 报错

而且这个问题 无解——你不可能阻止 MCP 更新,也不可能预知它下次要哪个版本的 Chromium。

三、解决方案

既然 MCP Playwright 的版本问题不可避免,我的思路是 绕开 MCP Playwright,用其他方式实现浏览器自动化

方案一:Python Playwright 脚本(推荐)

这是我现在用的方案。核心思路:不用 MCP 的 Playwright,改用 Python 的 Playwright 库

Python Playwright 的版本由 pip 管理,你装了什么版本就是什么版本,不会自动更新。对应的 Chromium 版本也就固定了。

安装(一次性)
pip install playwright
python3 -m playwright install chromium

安装完成后,Chromium 二进制文件保存在 ~/Library/Caches/ms-playwright/chromium_headless_shell-1223/,只要你不手动升级 Playwright,这个文件就一直有效。

使用方式

写一个 Python 脚本,在脚本里完成所有浏览器操作。然后通过 RunCommand 工具执行这个脚本。

举个例子——从 Instagram 下载图片:

from playwright.sync_api import sync_playwright
import json
import os
import urllib.request
import ssl

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    context = browser.new_context(
        user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                   "AppleWebKit/537.36",
        viewport={"width": 1280, "height": 800}
    )

    # 注入 Cookie 登录 Instagram
    context.add_cookies([
        {"name": "sessionid", "value": "your_session_id",
         "domain": ".instagram.com", "path": "/"},
        {"name": "ds_user_id", "value": "your_user_id",
         "domain": ".instagram.com", "path": "/"},
        {"name": "csrftoken", "value": "your_csrf_token",
         "domain": ".instagram.com", "path": "/"},
    ])

    page = context.new_page()
    page.goto("https://www.instagram.com/explore/tags/cat/", timeout=20000)
    page.wait_for_timeout(3000)

    # 提取图片 URL
    imgs = page.evaluate("""
        const links = document.querySelectorAll('a[href*="/p/"]');
        const results = [];
        links.forEach(a => {
            const img = a.querySelector('img');
            if (img && !a.querySelector('svg[aria-label="Reels"]')
                && img.src.includes('e35_tt6')) {
                results.push({src: img.src, alt: img.alt});
            }
        });
        JSON.stringify(results.slice(0, 10));
    """)

    data = json.loads(imgs)
    for i, d in enumerate(data):
        req = urllib.request.Request(d['src'], headers={"User-Agent": "Mozilla/5.0"})
        with urllib.request.urlopen(req, context=ctx, timeout=15) as resp:
            with open(f"image_{i+1}.jpg", 'wb') as f:
                f.write(resp.read())
        print(f"Downloaded image_{i+1}.jpg")

    browser.close()

在 Trae IDE 中,我只需要把这个脚本保存到 /tmp/download.py,然后让 AI 执行 python3 /tmp/download.py 就行了。

为什么这个方案稳定
pip install playwright==1.52.0        ← 版本锁定
  └── 对应 chromium_headless_shell-1223  ← Chromium 版本锁定
       └── ~/Library/Caches/ms-playwright/chromium_headless_shell-1223/
                                          ↑ 这个目录不会消失

只要你不执行 pip install --upgrade playwright,这个 Chromium 就一直能用。跟 MCP 更新完全解耦。

方案二:连接已有 Chrome(CDP 模式)

如果你电脑上已经有 Chrome 浏览器,可以让 Playwright 连接到它,完全不需要下载 Chromium。

第 1 步:用调试模式启动 Chrome

先关闭所有 Chrome 窗口,然后在终端运行:

# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222

# 或者用独立的用户数据目录(不影响正常 Chrome)
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 \
  --user-data-dir=/tmp/chrome-debug
第 2 步:Python 连接
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp("http://127.0.0.1:9222")
    context = browser.contexts[0]
    page = context.pages[0] if context.pages else context.new_page()

    page.goto("https://www.instagram.com/")
    print(page.title())
    browser.close()

这个方案的优势是 零下载——直接用你系统里已有的 Chrome。缺点是每次使用前需要手动启动 Chrome,而且部分沙盒环境可能阻止连接 localhost。

方案三:固定 MCP Playwright 版本

如果你还是想用 MCP Playwright,可以尝试锁定版本。

在 MCP 配置中,把 @latest 改成固定版本号:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@0.0.30"]
    }
  }
}

然后手动安装对应版本的浏览器:

npx @playwright/mcp@0.0.30 --help  # 确认版本
# 根据该版本要求的 Chromium 安装

缺点:你需要自己查清楚每个 MCP 版本对应哪个 Chromium 版本,而且固定版本意味着用不到新功能。这个方案只适合对稳定性要求极高的场景。

方案四:设置全局浏览器路径

Playwright 支持通过环境变量指定浏览器存储路径,并在该路径下复用已有浏览器:

# 在 ~/.zshrc 或 ~/.bashrc 中添加
export PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers

这样所有版本的 Playwright 都会把浏览器下载到同一个目录。配合 CI 缓存策略,可以避免重复下载。但对于本地开发场景,不同版本的 Playwright 仍然要求不同版本的 Chromium,所以这个方案只能缓解、不能根治。

四、方案对比

Python Playwright CDP 连接 Chrome 固定 MCP 版本 全局浏览器路径
稳定性 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐
免下载 ❌(一次)
版本可控 ✅ pip 锁定 ✅ 用系统 Chrome ✅ 锁定 npm 版本
使用难度
沙盒兼容 ❌(需连 localhost)
适合场景 AI Agent 自动化 有 GUI 的本地开发 CI/生产环境 CI 缓存优化

我的推荐:日常 AI Agent 开发用 方案一(Python Playwright),装一次 Chromium 就够了,版本完全由你控制。

五、Python Playwright 速查表

安装和常用操作快速参考:

# 安装
pip install playwright
python3 -m playwright install chromium

# 验证
python3 -c "from playwright.sync_api import sync_playwright; print('OK')"

# 查看已安装的浏览器
python3 -m playwright install --dry-run

# 强制重装(一般不需要)
python3 -m playwright install chromium --force

常用 Python 代码片段:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()

    # 导航
    page.goto("https://example.com", timeout=20000)

    # 等待
    page.wait_for_timeout(3000)

    # 截图
    page.screenshot(path="screenshot.png")

    # 提取数据
    title = page.title()
    text = page.inner_text("body")
    html = page.content()

    # 执行 JS
    result = page.evaluate("document.querySelectorAll('a').length")

    # Cookie 操作
    context = browser.new_context()
    context.add_cookies([...])

    browser.close()

六、常见问题

Q:Python Playwright 的 Chromium 和 MCP 的 Chromium 会冲突吗?

不会。它们存储在不同的子目录下:

  • MCP: ms-playwright/chromium-1208/
  • Python: ms-playwright/chromium_headless_shell-1223/

Playwright 官方也说了,多版本浏览器可以共存,不再使用的版本会被自动垃圾回收。

Q:Python Playwright 升级后也需要重新下载 Chromium 吗?

是的,如果你执行了 pip install --upgrade playwright,新版本可能要求不同的 Chromium。但关键区别是——升级是你主动做的,不是被动发生的。你不升级,就不会触发重新下载。

Q:headless 和 headed 模式有什么区别?

Python Playwright 默认用 headless=True,也就是无头模式,不会弹出浏览器窗口。适合 AI Agent 在后台运行。如果你需要看到浏览器操作过程,改成 headless=False

Q:为什么不用 Selenium?

Selenium 确实不需要下载专用浏览器,它可以直接驱动系统已安装的 Chrome。但 Playwright 的 API 更现代、对现代 Web 应用的支持更好,而且有更好的自动等待机制。对于 AI Agent 场景,Playwright 的执行 JS 能力(page.evaluate)特别实用。

参考链接


如果你也被 Playwright 反复下载 Chromium 折腾过,希望这篇文章能帮你彻底解决。如果你有更好的方案,欢迎在评论区分享,我会一一回复~

觉得有用的话,点个赞 👍 收个藏 📌 吧~

更多推荐