本文最后更新于 2026年4月6日 下午
本文介绍 MCP Playwright 如何将 AI 助手与浏览器自动化结合,实现智能化的 Web 应用调试。
什么是 MCP Playwright MCP (Model Context Protocol) 是一种标准化的协议,允许 AI 助手与外部工具进行交互。Playwright 是微软开发的现代化浏览器自动化工具。
MCP Playwright 将两者结合,让 AI 助手能够:
🌐 控制真实浏览器(Chrome、Edge、Firefox)
🔍 捕获页面元素、截图、录制视频
📊 监控网络请求和控制台日志
⚡ 执行 JavaScript 代码
🎯 模拟用户交互(点击、输入、滚动等)
核心优势 1. 智能化调试 AI 可以:
自动分析错误信息
智能选择最优的选择器
动态调整调试策略
自动生成调试报告
2. 完整的上下文感知 AI 可以看到:
当前页面 DOM 结构
控制台日志(console.log, error, warning)
网络请求和响应
页面截图和视频
localStorage/sessionStorage 状态
3. 高效的迭代循环 1 2 3 发现问题 → AI 分析 → 生成修复方案 → 自动验证 → 输出报告 ↓ ↑ └──────────── 快速迭代,无需手动干预 ──────────┘
4. 可复用的调试资产 每次调试都会生成:
📸 关键步骤截图
📹 完整操作视频
📄 详细的 JSON 日志
📝 结构化的问题报告
环境准备 安装 Playwright 1 2 3 4 5 6 7 pip install playwright playwright install chromium playwright install chrome playwright install msedge
验证安装 1 2 3 4 5 6 7 8 from playwright.sync_api import sync_playwrightwith sync_playwright() as p: browser = p.chromium.launch(headless=True ) page = browser.new_page() page.goto("https://example.com" ) print (page.title()) browser.close()
预期输出:Example Domain
核心功能 1. 浏览器导航 1 2 3 4 5 6 7 8 page.goto("http://localhost:5173/login" ) page.wait_for_load_state("networkidle" ) page.wait_for_selector("#username" , timeout=5000 )
2. 元素定位与交互 1 2 3 4 5 6 7 8 9 page.locator('input[name="username"]' ) page.locator('text=忘记密码' ) page.locator('//button[contains(text(), "登录")]' ) page.fill('input[name="username"]' , 'admin' ) page.fill('input[name="password"]' , 'admin123' ) page.click('button[type="submit"]' )
3. 截图与录制 1 2 3 4 5 6 7 8 9 10 11 12 page.screenshot(path='debug_01_initial.png' , full_page=True ) element = page.locator('#error-message' ) element.screenshot(path='error_element.png' ) context = browser.new_context( record_video_dir='videos/' , record_video_size={'width' : 1920 , 'height' : 1080 } )
4. 日志捕获 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 console_messages = []def handle_console (msg ): console_messages.append({ 'type' : msg.type , 'text' : msg.text, 'location' : f"{msg.location.get('url' , '' )} :{msg.location.get('lineNumber' , '' )} " }) page.on("console" , handle_console) network_requests = []def handle_response (response ): network_requests.append({ 'url' : response.url, 'method' : response.request.method, 'status' : response.status, 'headers' : dict (response.headers) }) page.on("response" , handle_response)
5. JavaScript 执行 1 2 3 4 5 6 7 8 9 10 11 12 auth_data = page.evaluate("""() => { return { token: localStorage.getItem('token'), user: localStorage.getItem('user') }; }""" ) page.evaluate("""() => { document.body.style.backgroundColor = 'red'; }""" )
实战案例:登录问题排查 问题背景 用户报告无法登录系统,提示”登录失败,请检查用户名和密码”。
调试流程 Step 1: 创建调试脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 from playwright.sync_api import sync_playwrightimport timeimport jsondef debug_login (): with sync_playwright() as p: browser = p.chromium.launch( headless=False , channel="chrome" , slow_mo=500 ) context = browser.new_context(viewport={'width' : 1920 , 'height' : 1080 }) page = context.new_page() console_messages = [] network_requests = [] page.on("console" , lambda msg: console_messages.append({ 'type' : msg.type , 'text' : msg.text })) page.on("response" , lambda res: network_requests.append({ 'url' : res.url, 'status' : res.status, 'method' : res.request.method })) page.goto('http://localhost:5173/login' ) page.wait_for_load_state('networkidle' ) time.sleep(2 ) page.screenshot(path='debug_01_initial.png' , full_page=True ) page.fill('input[name="username"]' , 'admin' ) page.fill('input[name="password"]' , 'admin123' ) time.sleep(1 ) page.click('button[type="submit"]' ) time.sleep(3 ) if '/login' in page.url: print ("❌ 仍在登录页面,登录可能失败" ) error_element = page.locator('.bg-red-50' ) if error_element.count() > 0 : error_text = error_element.inner_text() print (f"❌ 错误提示: {error_text} " ) else : print ("✅ 已跳转到首页,登录成功" ) debug_info = { 'console_messages' : console_messages[-20 :], 'network_requests' : [r for r in network_requests if 'api' in r['url' ]], 'current_url' : page.url, 'timestamp' : time.time() } with open ('debug_login_info.json' , 'w' , encoding='utf-8' ) as f: json.dump(debug_info, f, ensure_ascii=False , indent=2 ) browser.close()if __name__ == '__main__' : debug_login()
Step 2: 分析输出 发现的关键信息:
1 2 3 4 5 6 [Console error ] Access to XMLHttpRequest at 'http://localhost:8000/api/v1/auth/login' from origin 'http://localhost:5173' has been blocked by CORS policy [Console error ] Failed to load resource: net::ERR_FAILED ❌ 错误提示: 登录失败,请检查用户名和密码
后端日志显示:
1 2 ValueError : password cannot be longer than 72 bytesFile "app/core/security.py" , line 26 , in verify_password
Step 3: 定位根本原因 通过综合分析:
❌ CORS 错误 - 实际是表象,请求被后端拒绝
❌ bcrypt 兼容性问题 - passlib 与新版 bcrypt 不兼容
✅ 根本原因 - 密码验证逻辑崩溃导致返回错误响应
Step 4: 实施修复 修改 backend/app/core/security.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from passlib.context import CryptContext pwd_context = CryptContext(schemes=["bcrypt" ], deprecated="auto" )def verify_password (plain_password: str , hashed_password: str ) -> bool : return pwd_context.verify(plain_password, hashed_password)import bcryptdef verify_password (plain_password: str , hashed_password: str ) -> bool : try : return bcrypt.checkpw( plain_password.encode('utf-8' ), hashed_password.encode('utf-8' ) ) except Exception: return False
Step 5: 验证修复 重新运行调试脚本,确认:
✅ 无 CORS 错误
✅ 无控制台错误
✅ 成功跳转到首页
✅ localStorage 中有 token
最佳实践 1. 浏览器配置 1 2 3 4 5 6 7 8 9 10 11 browser = p.chromium.launch( headless=False , channel="chrome" , slow_mo=500 , args=[ '--no-sandbox' , '--disable-infobars' , '--disable-extensions' ] )
⚠️ 重要提醒:进程隔离原则
Playwright 必须启动独立的 Chrome 进程,严禁复用用户当前打开的浏览器!
原因:
🔒 权限边界 :AI 只能控制自己启动的进程,无法操作用户的浏览器
👤 用户隐私 :避免访问用户的个人浏览数据、登录状态等敏感信息
🛡️ 工作隔离 :防止自动化测试干扰用户的正常工作流程
🧹 资源清理 :测试完成后可以安全关闭,不留残留
2. 元素定位策略 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 page.locator('input[name="username"]' ) page.locator('#login-button' ) page.locator('[data-testid="submit-btn"]' ) page.locator('.btn.btn-primary' ) page.locator('text=登录' ) page.locator('//div[@class="form"]/input[1]' )
3. 等待策略 1 2 3 4 5 6 7 8 9 10 11 12 page.wait_for_load_state('networkidle' ) page.wait_for_selector('#element' , state='visible' ) page.wait_for_selector('#button' , state='enabled' ) time.sleep(5 )
4. 错误处理 1 2 3 4 5 6 7 8 9 10 11 try : page.goto('http://localhost:5173/login' , timeout=10000 )except TimeoutError: print ("❌ 页面加载超时" ) page.screenshot(path='error_timeout.png' ) raise except Exception as e: print (f"❌ 未知错误: {e} " ) page.screenshot(path='error_unknown.png' ) raise
常见问题 Q1: 浏览器启动失败 症状:
1 playwright._impl._errors.Error: BrowserType.launch: Executable doesn't exist
解决:
1 2 3 playwright install chromium playwright install chrome
Q2: 元素找不到 症状:
1 TimeoutError: locator.click: Timeout 30000 ms exceeded
解决:
1 2 3 4 5 6 7 8 9 10 11 print (page.content()) page.screenshot(path='debug_current.png' ) element = page.locator('input[name="username"], input#username' ).first page.wait_for_selector('input[name="username"]' , timeout=10000 )
Q3: CORS 跨域错误 症状:
1 Access to XMLHttpRequest has been blocked by CORS policy
解决:
1 2 3 4 5 6 7 8 9 10 11 12 BACKEND_CORS_ORIGINS = [ "http://localhost:5173" , "http://127.0.0.1:5173" ] context = browser.new_context( bypass_csp=True , ignore_https_errors=True )
总结 MCP Playwright 将 AI 助手与浏览器自动化结合,实现了智能化的 Web 应用调试。通过 AI 驱动的自动化调试、全面的上下文感知、高效的迭代循环和可复用的调试资产,大大提升了调试效率和质量。
核心优势:
智能化 - AI 驱动的自动化调试,减少人工干预
全面性 - 从 UI 到网络,从截图到日志,全方位监控
高效性 - 快速定位问题,自动生成报告
可复用 - 调试脚本和最佳实践可以沉淀为团队资产
行动建议:
立即开始 - 在你的下一个 bug 修复中使用 Playwright 调试
建立规范 - 制定团队的 Playwright 使用规范
积累资产 - 将常用的调试脚本整理成工具库
持续优化 - 定期回顾和改进调试流程
相关资源:
💡 提示 :本文是基于实战经验总结的 MCP Playwright 使用指南,更多细节请参考完整的实战指南文档。