MCP协议实战:用AI大模型驱动浏览器自动化,Chrome DevTools与Playwright双路线对比
浏览器自动化这件事,过去几年一直是少数脚本玩家的专属领地。写爬虫的、做测试的、搞RPA的,各自守着一套工具链,门槛不低。但最近半年,一个叫MCP的东西正在把这件事的门槛砸到地板以下——它让AI大模型直接接管浏览器,你说一句话,它自己点按钮、填表单、翻页面、抓数据。听起来像科幻,实际上已经能跑通了。
我花了大概三周时间,把Chrome DevTools MCP和Playwright MCP这两条主流路线都摸了一遍,中间踩了不少坑,也总结出一套相对稳定的玩法。这篇文章不打算写成官方文档的翻译,而是把我实际折腾的过程、遇到的坑、以及那些文档里不会写的细节,原原本本讲清楚。不管你是完全没接触过MCP的新手,还是已经用过Playwright想升级到AI驱动模式的老手,应该都能从里面找到能直接抄作业的东西。
1. 先搞清楚MCP到底是个什么东西
1.1 用一句话说清MCP:AI和工具之间的USB接口
MCP全称Model Context Protocol,翻译过来叫"模型上下文协议"。这个名字听起来很唬人,但你可以把它理解成AI世界里的USB接口标准。以前每个AI应用要调用外部工具,都得自己写一套对接代码,A工具对接B服务是一种写法,C工具对接D服务又是另一种写法,乱得一塌糊涂。MCP做的事情就是定一个统一标准:只要工具方按照MCP协议暴露自己的能力,AI方按照MCP协议去调用,双方就能即插即用。
这个类比不是随便打的。USB接口出现之前,鼠标用PS/2口、打印机用并口、键盘用另一种口,每换一个设备就得换一根线。MCP要解决的就是同样的问题——让AI调用浏览器、调用数据库、调用文件系统,全都走同一套协议。你作为使用者,只需要在配置文件里写几行JSON,告诉AI"这里有个浏览器工具可以用",剩下的它自己会搞定。
关键词里提到的"mcp协议"和"mcp是什么",本质上就是在问这个。它不是硬件协议,虽然名字里有"协议"两个字容易让人联想到TCP/IP那种底层网络协议。MCP是应用层的、面向AI工具调用的协议,跑在JSON-RPC之上,跟硬件没关系。
1.2 为什么浏览器自动化偏偏需要MCP
你可能会问:浏览器自动化不是早就有Selenium、Playwright、Puppeteer了吗,为什么还要搞个MCP?
这个问题问到点子上了。传统浏览器自动化的核心问题是:你得会写代码。想点一个按钮,得先找到它的选择器,然后写page.click('#submit');想等页面加载完,得写page.waitForSelector('.content')。对于开发者来说这不算什么,但对于不写代码的人来说,这就是一道天堑。
MCP改变的是交互方式。有了MCP之后,你不需要告诉AI"点击id为submit的按钮",你只需要说"帮我把这个表单填了提交"。AI通过MCP调用浏览器工具,自己去看页面结构、自己决定点哪里、自己判断有没有提交成功。这就把"写脚本"变成了"说需求"。
更关键的是,AI能处理不确定性。传统脚本最怕页面改版,选择器一变就全废。AI驱动的方式有容错能力,按钮从#submit变成.btn-primary,它照样能找到。这是质的区别,不是量的区别。
1.3 Chrome DevTools MCP和Playwright MCP的分岔路口
目前浏览器自动化领域主流的MCP实现有两条路线,选哪条直接决定你后面的体验。
Chrome DevTools MCP走的是CDP(Chrome DevTools Protocol)路线。CDP是Chrome浏览器原生暴露的调试协议,你按F12打开的那个开发者工具,底层就是通过CDP跟浏览器通信的。用这条路线的优势是"原生"——不需要额外装浏览器驱动,直接连你本机的Chrome就行,而且能拿到最底层的网络请求、性能数据、DOM快照。缺点是它对浏览器的控制粒度偏"调试"而非"操作",有些交互动作需要绕一下。
Playwright MCP走的是Playwright路线。Playwright是微软开源的浏览器自动化框架,本身就封装好了点击、输入、等待、截图这些操作。用这条路线的优势是"开箱即用"——操作语义清晰,稳定性好,跨浏览器支持完善。缺点是它需要Playwright自己的浏览器实例,跟你日常用的Chrome是两套东西。
我个人的选择是:做数据抓取和页面分析用Chrome DevTools MCP,做流程自动化和表单操作用Playwright MCP。后面会详细讲为什么这么分。
2. 环境搭建:从零到能跑通的第一条命令
2.1 前置条件清单:别急着装,先对一遍
在动手之前,先把这几样东西确认好,缺一个后面都会卡住:
- Node.js 18以上。MCP的服务器实现基本都是Node写的,版本太低会报各种奇怪的错。用
node -v确认一下,低于18先去升级。 - Chrome浏览器。建议用稳定版,别用Canary,Canary的CDP接口有时候会变。
- 一个支持MCP的AI客户端。这是关键。MCP本身只是个协议,你得有个"宿主"来调用它。目前支持MCP的客户端有不少,选一个你顺手的就行。
- 基本的命令行操作能力。不需要会写代码,但得知道怎么打开终端、怎么运行
npx命令。
提示:如果你之前装过Playwright但版本很老,建议先卸载重装。老版本Playwright和MCP服务器的兼容性有问题,我在这上面浪费过两个小时。
2.2 Chrome DevTools MCP的安装与配置
Chrome DevTools MCP的安装方式取决于你用的客户端。核心逻辑是在客户端的MCP配置文件里加一段JSON,告诉它去哪里启动这个MCP服务器。
配置文件通常长这样:
{ "mcpServers": { "chrome-devtools": { "command": "npx", "args": ["-y", "chrome-devtools-mcp@latest"] } } }这段配置的意思是:当客户端需要用到浏览器工具时,用npx去拉取并运行chrome-devtools-mcp这个包。-y参数是自动确认,避免每次都要手动按y。
配置写完之后重启客户端,如果一切正常,你应该能在工具列表里看到一堆以chrome_开头的工具,比如chrome_navigate、chrome_click、chrome_screenshot之类的。
这里有个大坑:Chrome DevTools MCP默认会尝试连接一个已经开启了远程调试端口的Chrome实例。如果你直接运行,它可能会报"无法连接到浏览器"。解决办法是先用调试模式启动Chrome:
# macOS /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 # Windows "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222启动之后,Chrome会监听9222端口,MCP服务器就能连上去了。这个端口号可以改,但改了之后MCP配置里也要同步改。
2.3 Playwright MCP的安装与配置
Playwright MCP的配置更简单,因为它自带浏览器管理:
{ "mcpServers": { "playwright": { "command": "npx", "args": ["-y", "@playwright/mcp@latest"] } } }第一次运行的时候,它会自动下载需要的浏览器二进制文件。这个过程可能有点慢,取决于你的网络。下载完之后,Playwright MCP会自己启动一个浏览器实例,你不需要手动开Chrome。
Playwright MCP暴露的工具命名更语义化,比如browser_navigate、browser_click、browser_type、browser_snapshot。其中browser_snapshot是我用得最多的——它会返回当前页面的可访问性树(accessibility tree),AI根据这个树来决定下一步操作。这比直接给AI看HTML源码要高效得多,因为可访问性树已经过滤掉了大量噪音。
2.4 验证是否跑通:第一个自动化任务
配置完之后,别急着上复杂任务,先用一个最简单的验证一下链路通不通。
在AI客户端里输入类似这样的话:
打开example.com,告诉我页面的标题是什么。
如果配置正确,你会看到AI开始调用MCP工具,先是navigate到目标网址,然后snapshot或者get_title,最后返回结果。整个过程你能在客户端的工具调用日志里看到。
如果卡住了,按这个顺序排查:
- 检查Node版本是否≥18
- 检查MCP配置文件路径是否正确(不同客户端路径不一样)
- 检查是否有端口冲突(Chrome DevTools MCP的9222端口)
- 看客户端日志里MCP服务器的启动报错信息
我遇到最多的问题是配置文件里的JSON格式错误,比如多了一个逗号或者少了一个引号。这种错误不会明确提示"JSON格式错误",而是表现为"MCP服务器启动失败",很容易误导排查方向。
3. 两条路线的实战对比:什么时候用哪个
3.1 用Chrome DevTools MCP抓取动态渲染的数据
假设你要抓一个用React写的单页应用里的数据,页面内容是JavaScript动态渲染的,直接请求HTML拿不到东西。这种场景Chrome DevTools MCP很合适。
操作流程大致是这样:先让AI导航到目标页面,然后等页面渲染完成,再通过CDP获取渲染后的DOM。因为CDP拿到的就是浏览器内存里真实的DOM树,所以动态内容全都在。
我实测过一个电商列表页,用传统requests抓下来只有骨架HTML,商品信息全是空的。换成Chrome DevTools MCP之后,AI导航过去、等两秒、抓DOM,商品名称、价格、评分全都拿到了。整个过程我只需要说一句话:"打开这个页面,把商品列表里的名称和价格提取出来。"
但这里有个细节要注意:CDP拿到的DOM可能非常大,一个复杂页面动辄几万行HTML。如果直接塞给AI,会消耗大量token,而且AI容易在噪音里迷失。我的做法是让AI先用JavaScript在页面里执行提取逻辑,只返回结构化结果。比如:
// 在页面上下文里执行 const items = Array.from(document.querySelectorAll('.product-card')).map(card => ({ name: card.querySelector('.product-name')?.textContent?.trim(), price: card.querySelector('.product-price')?.textContent?.trim() })); return items;这样返回的就是干净的JSON数组,token消耗小,准确率也高。Chrome DevTools MCP提供了执行JavaScript的能力,这是它相比Playwright MCP的一个优势。
3.2 用Playwright MCP做表单填写和流程操作
表单填写是Playwright MCP的强项。它的browser_type工具能直接往输入框里打字,browser_click能点按钮,browser_select_option能选下拉框,语义非常清晰。
我拿一个多步骤的注册流程做过测试:第一步填邮箱和密码,第二步填个人信息,第三步上传头像,第四步点确认。整个流程用Playwright MCP跑下来,AI自己判断每一步该填什么、该点哪里,中间还处理了一个"邮箱已存在"的提示弹窗——它自己决定换个邮箱重试。
这种容错能力是传统脚本做不到的。传统脚本遇到意外弹窗直接卡死,AI驱动的方式会"看一眼"弹窗内容,然后决定怎么处理。
Playwright MCP的一个隐藏优势是它的browser_snapshot返回的可访问性树。这个树的结构比DOM简洁得多,一个复杂的表单在可访问性树里可能只有几十个节点,AI处理起来又快又准。我对比过同一个页面,DOM有8000多行,可访问性树只有200多行,差距巨大。
3.3 两者的能力边界与选择建议
把两条路线的差异整理成一张表,方便你对照选择:
| 维度 | Chrome DevTools MCP | Playwright MCP |
|---|---|---|
| 底层协议 | CDP | Playwright |
| 浏览器实例 | 连接本机Chrome | 自带独立实例 |
| 动态内容抓取 | 强 | 中 |
| 表单操作 | 中 | 强 |
| JavaScript执行 | 原生支持 | 有限支持 |
| 网络请求拦截 | 强 | 中 |
| 跨浏览器 | 仅Chrome系 | Chrome/Firefox/WebKit |
| 配置复杂度 | 中(需调试端口) | 低 |
| 稳定性 | 中 | 高 |
我的选择逻辑很简单:要"看"用Chrome DevTools MCP,要"做"用Playwright MCP。看指的是分析页面、抓数据、监控网络;做指的是点击、输入、提交、走流程。当然两者也能混用,在同一个客户端里配两个MCP服务器就行,AI会根据任务自己选。
4. 那些文档里不会写的踩坑记录
4.1 页面还没加载完,AI就急着操作
这是最常见的问题。AI导航到一个页面后,可能页面还在加载,它就开始找按钮了,结果找不到,报错。
根本原因是AI不知道"什么时候算加载完"。传统脚本里你会写waitForSelector或者waitForLoadState,但AI不会自动做这件事,除非你明确告诉它。
我的解决办法是在提示词里加一句:"导航后等待页面完全加载再进行下一步操作。"更稳妥的做法是让AI先调用browser_snapshot看一眼当前状态,确认页面内容已经出来了再操作。
Playwright MCP的browser_navigate其实有等待机制,但它等的是load事件,对于有大量异步请求的页面来说,load事件触发时内容可能还没渲染完。这时候需要额外等一个networkidle状态,或者干脆手动等两秒。
4.2 登录态丢失:每次都要重新登录
用Playwright MCP的时候,每次启动都是一个新的浏览器上下文,cookie和localStorage都是空的。如果你要操作的是需要登录的网站,每次都得重新走一遍登录流程,非常烦。
解决办法是配置持久化上下文。Playwright支持指定一个用户数据目录,这样cookie和登录态就能保留下来:
{ "mcpServers": { "playwright": { "command": "npx", "args": [ "-y", "@playwright/mcp@latest", "--user-data-dir=/path/to/your/profile" ] } } }把/path/to/your/profile换成你本机的一个目录,第一次登录之后,后续启动都会复用这个目录里的登录态。这个技巧文档里提得很少,但实际用起来能省大量时间。
Chrome DevTools MCP因为连的是你本机的Chrome,登录态天然就在,不存在这个问题。这也是它在某些场景下更方便的原因。
4.3 弹窗和iframe:AI的盲区
网页上的弹窗(alert、confirm、prompt)和iframe是自动化的经典难题。AI驱动的方式在这上面也有盲区。
对于原生弹窗,Playwright MCP有专门的处理工具,但AI不一定知道什么时候该调用。我的经验是在提示词里提前说明:"如果遇到弹窗,先读取弹窗内容再决定是否确认。"
iframe更麻烦。iframe里的内容在主页面的可访问性树里是看不到的,AI会以为那个区域是空的。解决办法是让AI先列出页面上所有的iframe,然后逐个进入查看。Playwright MCP支持frame切换,但需要AI主动去做。
我遇到过一个支付页面,确认按钮在iframe里,AI死活找不到。后来我在提示词里加了一句"注意检查页面是否有iframe",它才反应过来。
4.4 token消耗失控:一个页面烧掉几万token
这是成本问题,也是稳定性问题。如果让AI每次都读取完整页面内容,token消耗会非常快。一个复杂页面几万token是常事,多跑几个任务成本就上去了。
控制token的核心思路是让AI少看、多做。具体来说:
- 优先用
browser_snapshot而不是获取完整HTML,可访问性树比DOM小一个数量级 - 能用JavaScript在页面里提取的就不要返回原始内容
- 明确告诉AI只关注页面的特定区域,不要全页扫描
- 对于重复性任务,让AI先总结出操作模式,后续直接按模式执行
我做过一个对比:同一个数据抓取任务,让AI读完整DOM的方案消耗了约15000 token,用JavaScript提取的方案只消耗了约800 token。差了将近20倍。
5. 把浏览器变成"自动打工人"的进阶玩法
5.1 定时任务:让AI每天自动巡检
MCP本身不负责定时,但你可以用系统的定时任务来触发。思路是写一个脚本,定时启动AI客户端并发送预设的提示词,让AI自动执行巡检任务。
比如每天早上9点检查某个后台的数据报表有没有更新,有更新就抓下来存到本地。这个脚本可以用cron(Linux/macOS)或任务计划程序(Windows)来调度。
关键点是AI客户端要支持命令行调用或者有API接口。如果客户端只支持图形界面,那就得用自动化工具去模拟点击,这就绕回传统自动化了,有点讽刺。所以选客户端的时候,优先选支持headless模式或者有CLI的。
5.2 多步骤工作流:把复杂任务拆成AI能执行的指令
AI不是万能的,太复杂的任务它容易在中途迷失。我的做法是把大任务拆成多个小步骤,每一步都有明确的输入和输出。
比如"抓取竞品价格并生成对比表"这个任务,拆成:
- 打开竞品A的页面,提取价格
- 打开竞品B的页面,提取价格
- 打开竞品C的页面,提取价格
- 把三个价格整理成表格
每一步单独执行,中间结果保存下来。这样即使某一步失败,也不用从头再来。而且每一步的提示词可以写得很具体,AI执行起来准确率高很多。
5.3 结合其他MCP:浏览器只是工具箱里的一把
浏览器MCP只是MCP生态里的一种。你还可以同时配置文件系统MCP、数据库MCP、甚至Blender MCP。这样AI就能完成"打开网页抓数据→存到本地文件→写入数据库"这样的完整链路。
我目前配了三个MCP服务器:Playwright负责浏览器操作,filesystem负责读写本地文件,还有一个sqlite负责数据库操作。AI在任务执行过程中会自动在这些工具之间切换,我只需要描述最终目标。
这种组合的威力在于,你不再需要为每个环节写胶水代码。以前要写一个Python脚本,里面调requests抓数据、调pandas处理、调sqlite3入库,现在这些都由AI通过MCP自动完成。
5.4 稳定性优化:让自动化任务跑得更稳
AI驱动的自动化比传统脚本灵活,但稳定性需要额外下功夫。我总结了几个实用技巧:
重试机制。任何一步失败都让AI重试,最多重试三次。很多失败是偶发的网络抖动,重试就能过。
状态检查。每完成一步,让AI确认当前状态是否符合预期。比如提交表单后,检查是否出现了成功提示。如果没出现,就说明有问题,需要处理。
超时设置。给每个操作设置合理的超时时间,避免AI卡在某个步骤上无限等待。Playwright MCP默认超时是30秒,对于慢页面可能不够,可以调大。
日志记录。让AI把每一步的操作和结果都记录下来,出问题的时候方便回溯。这个日志不用很正式,就是简单的文本记录,但排查问题时非常有用。
6. 关于成本和收益的实话实说
6.1 token成本到底有多高
这是很多人关心的问题。我用一个实际案例来说明:抓取一个包含50个商品的列表页,提取名称、价格、评分三个字段。
- 方案A:让AI读取完整DOM后提取,消耗约12000 token
- 方案B:让AI执行JavaScript在页面内提取,消耗约600 token
- 方案C:传统Playwright脚本,消耗0 token(但需要写代码)
按当前主流模型的定价,方案A单次成本大约几分钱,方案B不到一厘钱。如果每天跑一次,方案A一个月成本一两块钱,方案B几毛钱。单看绝对值不高,但如果任务量大或者页面复杂,差距会迅速放大。
我的建议是:能用代码解决的用代码,需要灵活应变的用AI。不要为了用AI而用AI,那样成本会失控。
6.2 什么任务适合交给AI,什么任务不适合
适合AI的任务特征:
- 页面结构经常变,选择器不稳定
- 需要处理不确定情况(弹窗、验证码、意外跳转)
- 任务步骤不固定,需要根据页面内容动态决定
- 一次性任务,不值得写脚本
不适合AI的任务特征:
- 高频重复,每天跑几百次
- 页面结构极其稳定,选择器几年不变
- 对速度要求极高,AI的推理延迟无法接受
- 对准确性要求100%,不能有任何偏差
说白了,AI适合处理"脏活累活"——那些传统脚本搞不定或者维护成本高的场景。对于规整的、稳定的任务,传统脚本依然是更经济的选择。
6.3 一个真实的收益对比
我拿一个实际项目做过对比。任务是每天从五个不同的后台系统抓取数据,汇总成报表。五个系统里有两个是老旧系统,页面结构混乱,选择器经常变。
传统方案:写五个脚本,其中两个每周都要修,维护成本大概每周两小时。 AI方案:配好MCP,写五个提示词,基本不用维护,偶尔调整一下提示词。
时间成本上AI方案完胜。token成本上,AI方案每天消耗约5000 token,折合下来一个月不到十块钱。用十块钱换每周两小时的维护时间,这笔账怎么算都划算。
当然,如果那五个系统都很规整,传统脚本一次写好半年不用动,那AI方案就没优势了。关键还是看场景。
7. 几个容易被忽略的细节
7.1 浏览器版本和MCP版本的匹配
Chrome DevTools MCP依赖CDP协议,而CDP协议在不同Chrome版本之间有差异。如果你的Chrome太老,某些CDP命令可能不支持;如果太新(比如Canary版),协议可能有变动。
我的建议是锁定Chrome稳定版,并且不要频繁更新。如果MCP突然不工作了,先检查Chrome是不是自动更新了。
Playwright MCP相对好一些,因为它自带浏览器,版本是配套的。但Playwright本身和MCP服务器之间也有版本兼容问题,建议都用latest版本。
7.2 网络环境的影响
MCP服务器启动时需要从npm拉取包,如果网络不通会直接失败。第一次配置的时候建议先手动运行一下npx命令,确认能正常下载。
另外,如果目标网站有地域限制或者反爬机制,AI驱动的方式和传统脚本面临的问题是一样的。MCP不解决网络层面的问题,它只是改变了操作方式。
7.3 安全边界:别让AI碰敏感操作
AI驱动浏览器意味着AI能点击页面上的任何按钮。如果页面涉及支付、删除、权限变更等敏感操作,一定要加确认机制。
我的做法是在提示词里明确列出禁止操作:"不要点击任何标注为删除、支付、确认付款的按钮,遇到这类按钮先停下来询问。"虽然AI通常会谨慎,但明确约束更保险。
另外,MCP服务器本身运行在你本机,它能访问的资源取决于你给它的权限。配置文件里不要暴露不必要的路径和凭据。
7.4 调试技巧:怎么看AI到底做了什么
AI执行任务的时候,你看到的只是最终结果。如果结果不对,需要知道中间发生了什么。
大多数MCP客户端都有工具调用日志,能看到AI调用了哪些工具、传了什么参数、返回了什么结果。这个日志是排查问题的第一手资料。
Playwright MCP还支持截图,可以让AI在关键步骤截图保存。这样你能直观看到AI操作时页面长什么样,比看日志更清楚。
我习惯在提示词里加一句:"每个关键步骤后截图保存到本地。"这样出问题的时候,翻截图就能定位到是哪一步出了偏差。
8. 写在折腾之后
MCP让浏览器变成"自动打工人"这件事,本质上不是技术有多新,而是交互方式变了。以前是人适应机器,得学选择器、学等待、学异常处理;现在是机器适应人,你说需求,它想办法完成。
但这不意味着传统自动化就过时了。恰恰相反,理解传统自动化的原理,能帮你更好地驾驭AI驱动的方式。知道页面加载有哪些状态、知道iframe为什么是盲区、知道token消耗在哪里,这些认知决定了你用的是"能用"还是"好用"。
我自己的体会是,MCP最适合的场景是那些"不值得写脚本但又确实烦人"的任务。比如每周手动查一次的数据、偶尔要填的重复表单、需要盯着看的页面变化。这些任务写脚本吧,维护成本比手动做还高;不写吧,又确实浪费时间。MCP正好填在这个空档里。
最后分享一个小心得:刚开始用的时候,别追求一步到位。先让AI做一个最简单的任务,跑通了再加复杂度。我见过太多人一上来就让AI处理十几个步骤的复杂流程,结果卡在第二步就放弃了。自动化这件事,信任是逐步建立的,你跟AI的配合也是逐步磨合的。先从"打开网页告诉我标题"开始,慢慢来。