
说实话做测试开发这么些年写浏览器自动化脚本早就是家常便饭了。但每次接到一个新项目的UI用例打开页面看到那一堆密密麻麻的xpath、css selector还是忍不住头大。直到我最近把Playwright和AI大模型串在一起用自然语言直接指挥浏览器干活那种体验完全是另一个维度——不再是人去迁就代码语法而是让代码理解人的意图。这篇文章就来聊聊我实际搭建这套自然语言控制浏览器方案的全过程。核心就三件事搞清楚它为什么能跑通代码到底怎么写以及真正落地时会踩到哪些坑。不管你是测试工程师、爬虫开发还是单纯想折腾点有意思的自动化工具这篇内容应该都能给你一些实打实的参考。1. 为什么我突然开始折腾自然语言控制浏览器先说个很现实的问题传统自动化脚本最大的痛点不是写不出来而是维护不起。页面改个文案xpath就断了开发调个布局css selector就失效了。我见过太多测试团队用例写了一万多条结果每次版本迭代光修定位器就要花掉一大半时间。这种活干久了人真的会麻木。自然语言控制浏览器的思路本质上就是把“写代码”这件事拆成两层用户只负责说清楚“我要做什么”剩下“怎么做”交给AI大模型去理解然后动态生成Playwright代码去执行。比如你输入一句“打开百度搜索Playwright把第一条结果的标题打印出来”系统会自动把这句话拆解成打开页面、定位输入框、执行搜索、等待结果、提取文本这一串操作每一步都有对应的Playwright API调用。这套组合的优势非常明显用例编写门槛大幅降低不需要记住API甚至不需要懂编程定位器由AI动态生成页面结构小改动时重新生成一次就行调试过程更直观因为每一步操作都是可读的自然语言描述非技术人员也能写自动化脚本业务同学直接描述操作路径即可当然光有概念不够得看技术链路怎么走通。我接下来会把整个架构的核心原理拆开讲清楚这块看懂了后面写代码就是水到渠成的事。2. 核心原理拆解用户指令是怎么变成浏览器操作的2.1 自然语言到代码的关键一跳LLM的角色要让自然语言变成Playwright代码中间必须有一个“翻译官”这个翻译官就是大语言模型LLM。但直接用LLM生成裸代码有个问题大模型再聪明它不了解当前页面的DOM结构不知道这个页面里到底有没有“搜索框”这个元素更不知道它的id叫什么。所以整个设计里LLM其实分两个阶段参与第一阶段是意图解析。用户说“搜索Playwright”模型需要判断这是要定位输入框、输入文字、然后按回车。这一阶段输入是纯文本输出是一个结构化的操作序列描述类似“goto(url) - fill(selector, text) - press(Enter)”。第二阶段是定位器生成。这一步需要把页面的DOM快照喂给模型让它根据HTML结构找出哪个元素对应用户描述的对象。比如用户说“搜索框”模型看到HTML里有input namewd placeholder请输入关键词就能推断出这个input就是目标然后生成一个合适的定位策略。2.2 让Playwright跑起来的三种主流对接方式我调研和实测下来现在主流方案基本分三类各有各的适用场景第一种是最直接的用LLM直接生成完整代码片段然后交给Playwright去执行。这种方案适合一次性、探索性的操作缺点是生成代码稳定性和可维护性都一般。第二种是细粒度工具调用通过MCPModel Context Protocol协议把Playwright暴露成一组小工具给模型调用。模型每次只调用一个动作比如“点击”、“输入”、“等待”每一步都可以根据页面反馈做调整。这种方案最灵活也是目前最被看好的方向。第三种是自训练一个DOM理解模型类似开源项目Midscene的做法用视觉模型定位元素不依赖DOM结构。理论上容错率更高但对部署资源有要求普通场景有点杀鸡用牛刀。我自己实际项目里用的是第二种思路——通过MCP协议把Playwright能力注入给大模型。原因很实在灵活度高每一步都能看到执行结果方便纠错而且和现有Playwright生态无缝衔接官方工具链不用换。2.3 为什么协议设计决定成败这里多说一句MCP协议的事。很多人问我为什么不直接写Python脚本调LLM的API绕一圈搞个MCP干嘛因为直接调API有个致命缺陷模型是“一次性”的它生成完代码就结束了看不到页面反馈。假设它生成的定位器错了页面根本找不到那个元素模型不知道也没有机制去修正。MCP协议的核心价值在于它建立了一条双向通信的通道模型发起工具调用Playwright执行然后把真实页面状态截图、DOM摘要、控制台日志回传给模型。模型看到执行结果后可以自我纠错换一种策略再来一次。你可以理解为直接调API是让一个盲人给你指路他说完就消失了用MCP是让一个能看到路况的司机帮你开车走错了还能倒回来重新绕。对于真实世界的动态网页后者几乎是唯一靠谱的方案。3. 实操从零搭建一个自然语言浏览器助手3.1 环境准备与依赖安装我是在一台Ubuntu 22.04的机器上做的这套搭建Python环境用的3.11。需要安装的东西不多核心就几个包pip install playwright playwright install chromium安装Playwright本身没什么难度真正的坑在第二步——playwright install下载浏览器时经常因为网络问题失败。如果你也遇到一直卡在Downloading Chromium这一步我建议直接设置镜像环境变量export PLAYWRIGHT_DOWNLOAD_HOSThttps://npmmirror.com/mirrors/playwright/ playwright install chromium实测这个镜像速度快很多基本一分钟内搞定。装完之后最好跑一下playwright install-deps把系统依赖库补齐不然启动Chromium时会报一堆缺库的错误。接下来装MCP相关的库。我用的方案是Python环境下的playwright-mcp扩展安装命令很简单pip install playwright-mcp装完可以用playwright-mcp --help看下参数确认安装成功。需要说明的是这个工具本质是一个MCP服务端它启动后会把Playwright的能力封装成一系列工具函数等着LLM客户端来调用。3.2 核心代码架构与关键配置整个系统分三个模块MCP服务端负责实际浏览器操作、LLM客户端负责自然语言理解与决策、以及一个简单的调度脚本负责把用户输入转发给LLM并解析回传的工具调用结果。先看MCP服务端的启动配置。我用的是JSON配置文件方式把服务端注册到LLM客户端里{ mcpServers: { playwright: { command: playwright-mcp, args: [--headless, --viewport-size1280,720], env: { DEBUG: true } } } }这个配置的用意说一下--headless代表无头模式服务器上跑自动化必须开这个不然没有显示器会报错--viewport-size设置浏览器窗口尺寸这个很重要因为页面可能是响应式布局不同的视口宽高会导致元素位置和可见性发生变化直接影响AI的定位结果。然后是业务层的调度逻辑。我这里用Claude作为LLM客户端通过它官方的MCP适配器来连接上面的服务端。但不管用哪家模型核心的流程都是一样的用户输入自然语言任务描述LLM判断需要调用哪些MCP工具通过MCP协议发送工具调用请求Playwright执行浏览器操作并返回结果LLM判断结果是否符合任务目标不符合则继续调整全部完成或达到最大迭代次数后返回最终结果值得一提的是这个流程是循环的不是一次性的。模型会像人一样判断“我刚才点的对不对”不对就换个方式重试。我看到很多demo都忽略了这个细节导致真实场景表现很差这里重点提醒一下。3.3 一个完整的自然语言执行示例理论说了那么多不如直接看效果。我实际测试了一个任务输入是“打开百度首页搜索Playwright点击搜索结果里第一条链接等页面加载完把页面标题和当前URL打印出来。”整个执行过程中AI的操作步骤是这样的第一步调用导航工具打开百度首页。这一步没什么悬念MCP服务端内部的Playwright直接执行了page.goto。第二步AI判断页面上有搜索框于是调用定位工具。此时它会先触发一次DOM快照获取把页面的可交互元素列出来然后锁定搜索框调用填入和回车操作。第三步搜索结果页加载出来后AI需要点击第一条结果。这一步其实是最考验模型的因为“第一条结果”是一个相对模糊的描述。模型需要识别出搜索结果容器里第一个标题链接然后生成精准的点击坐标或DOM路径。我实测下来模型经过一次误操作后成功矫正最终点到了正确的链接。第四步wait.waitForLoadState(networkidle) 等待页面稳定然后提取page.title()和page.url()返回给用户。整个过程大概15秒其中还有一次视图截图的操作。AI会截图看当前页面长什么样确认自己定位得对不对。这一点非常重要通过视觉反馈来验证状态能大幅提高成功率。4. 常见问题与排查技巧实录下面整理了我在实际调这套方案时遇到的高频问题每个都附带了排查思路和修复方案值得收藏。现象可能原因排查与解决浏览器启动失败报缺少依赖库系统缺少Playwright所需的动态链接库执行playwright install-deps一键安装仍失败则根据报错信息单独安装对应库元素定位时好时坏页面是异步渲染AI生成快照时元素还没加载出来在操作序列中强制加上等待动作或在MCP服务端配置默认的networkidle等待AI开始无限循环点击同一个按钮模型陷入了重复执行相同操作的死循环设置最大操作步数限制建议10~15步超过就终止并返回实时的页面快照给模型重新决策页面出现无法关闭的弹窗弹窗是页面级模态框常规点击关闭无效让AI直接调用JavaScript执行移除DOM节点跳过点击关闭按钮的路径中文输入乱码Playwright填入时编码异常在输入前强制设定字符集或者在注入前先聚焦元素再逐字输入这里面最常踩的坑是第一个很多人装完playwright就直接跑了结果浏览器起不来。我遇到过最离谱的一次是缺了libnss3这个安全库白屏报错看了半天才定位到原因。Linux服务器上跑直接先执行playwright install-deps基本能一次到位。再说一个深入一点的排查技巧。当AI定位元素不准的时候很多人第一反应是换模型但我的经验是先看它的决策链路日志。把MCP服务端的DEBUG开关打开它会打印每一步工具调用的输入和输出你能清楚地看到AI是“找错了元素”还是“定位对了但坐标没对上”。这两种情况的修复策略完全不同前者需要优化DOM快照的质量后者只需要调整视口尺寸或滚动位置。还有一个新手容易忽略的如果你用公司内部浏览器环境可能会遇到证书错误页面。这时候需要在启动参数里加上--ignore-certificate-errors不然AI会卡在证书警告页上反复尝试点击“继续前往”永远进不了正题。5. 从脚本到副驾这套方案的更多玩法与边界写到这儿其实核心的东西都讲完了。但我觉得有必要再聊聊这套能力能往哪些方向延伸因为它的价值绝不仅仅局限于写测试用例。首先是网页数据采集。传统爬虫遇到JS动态渲染页面得逐个接口逆向、分析异步加载逻辑非常费劲。现在你可以直接用自然语言描述需求“打开这个页面的列表把每一行的标题、价格、发布日期提取出来翻页直到没有下一页。”AI会自动识别分页控件循环操作最后把结果整理成JSON给你。这种开发效率提升是几何级的。其次是自动化办公场景。有些内部系统没有API接口人工操作又贼繁琐比如OA系统里每天填报表、审批流程、导出数据。用这套方案只需要把操作流程用自然语言描述一次AI就能稳定重复执行等于给你的日常工作配了个浏览器副驾。再就是回归测试的智能生成。传统的UI回归测试写起来最枯燥现在你可以拿一份需求文档直接转化成操作路径让AI生成对应的Playwright用例。虽然生成的用例可能还需要人工微调但至少省掉了从零写的80%时间。当然这套方案也有自己的边界我得客观说一下。一是复杂业务逻辑的判断比如“如果A大于B就点击C否则点击D”这种分支场景纯自然语言描述容易有歧义需要你在提示词里写清楚判断条件。二是模型的上下文有限如果一次任务涉及几十个步骤AI可能会“忘记”前面的目标这时候就需要把大任务拆成多个小任务衔接。我在实际使用中还有一个很深的体会给AI的指令越接近“你是在操作浏览器的人”执行成功率越高。比如你说“点击搜索框输入关键词按回车”比直接说“帮我搜索一下”要好得多。这就像带新人——你交代得越具体他的执行越准确。所以如果你觉得AI表现得不够聪明先检查一下自己的指令是不是太笼统了。最后再分享一个实用小技巧。在调试阶段别总用无头模式跑把浏览器窗口开着跑你能亲眼看到AI每一步操作在干什么。很多时候你以为AI“理解错了”其实它在页面上已经找到了正确的元素只是你视角不同没看出来。看着它自己移动鼠标、点击、翻页那种感觉真的挺奇妙的。