首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
LLM Agent vs 传统浏览器自动化:实测对比与选型指南
📅 2026/9/8 5:22:26
✍️ 爱科研究院
👁 阅读 3,247
上个月我被一个大模型 Agent 项目整得想骂人。需求其实不复杂让 AI 自己打开某个公开网站定时抓取价格再填一个查询表单把结果整理成表格发到群里。我一开始理所当然选了 LLM Agent 路线毕竟让大模型“看懂页面、自己操作”听起来才是未来。结果半个多月下来速度慢、成本高、动不动就被一个弹窗卡死最离谱的是页面改了一个 CSS 类名Agent 直接原地崩溃完全不知道该怎么办。被逼到墙角之后我回头老老实实测了一圈浏览器自动化工具Playwright、Selenium、AutoFlow甚至把安卓平板上的移动端自动化也翻出来试了一遍。测完最大的感触是在 LLM Agent 被吹上天的这两年传统浏览器自动化这条“笨路”不仅没死反而在很多生产级场景里更可靠、更便宜、更可控。这期就聊聊我的实测过程和踩坑记录给同样在 LLM Agent 和自动化脚本之间纠结的朋友一个参考。1. 先聊聊我为什么从 LLM Agent “叛逃”回自动化脚本1.1 我的原始需求让 AI 自己去网站上填表单、查信息我手上的任务其实相当典型公司想监控一批竞品公开页面的价格变化每天自动去这几个网站查询、截图、把关键数据抓回来。最开始我的设想特别“先进”——用大模型 Agent 直接操作浏览器它能理解网页语义遇到弹窗就自己关遇到结构变化就自己调整策略听起来几乎不需要维护。于是我搭了一个最简单的 LLM Agent 流程大模型作为“大脑”浏览器作为一个工具Agent 决定下一步点击哪个元素、输入什么内容。架构上很漂亮大模型看页面截图或者 DOM 结构输出动作序列然后由浏览器工具执行。跑 Demo 的时候确实惊艳GitHub 上那些演示视频不是假的给大模型一个自然语言指令它真的能自己去完成“搜索→筛选→抓取”这种多步任务。但 Demo 和真实项目之间隔着一条我低估了的鸿沟。1.2 LLM Agent 踩到的三个真实痛点速度、成本、幻觉第一个痛点是速度。大模型每做一次决策要先把页面信息传给它它思考再输出动作。看起来每次决策只需要几秒钟但一个稍微复杂的流程有二十几步操作累积起来常常要几分钟。我拿一个简单的“登录→进入商品列表页→选择价格区间→抓取前十个商品名”流程做了统计纯 LLM Agent 平均耗时 3 分 25 秒其中大部分时间消耗在“看页面”和“思考”上真正执行动作反而是毫秒级的。第二个痛点是成本。这里的成本不只是 API 费用还有上下文窗口的消耗。大模型要理解一个现代网页光 DOM 或截图就很占 token如果页面里有大量图片、JS 动态插入的节点一次请求轻松烧掉几千甚至上万 token。一次成功的任务可能 trial and error 好几次一个月的成本足够买一台不错的云服务器。第三个痛点是幻觉和“迷之自信”。最典型的表现是大模型明明没有找到“登录按钮”但它会认为自己找到了然后输出一个不存在的坐标或选择器又或者页面已经跳转到了“密码错误”提示页它还坚持下一步是“点击查询”。当 Agent 陷入这种状态你几乎无法通过参数调优解决只能人工介入这就完全失去了自动化的意义。1.3 促发我写这篇测试的瞬间一个 CSS 类名改版让 Agent 原地崩溃真正让我决定换赛道的是一次改版事故。那天早上接到测试反馈说自动化任务全部失败。我打开日志一看原来是网站前端把商品卡片的classproduct-title改成了classproduct-name highlight。放在传统自动化里这就是改一行选择器的事但放在 LLM Agent 里我本以为它具备语义理解能力应该能轻松跨过这种改动结果它没有。大模型对着新的 DOM 结构看了半天开始反复点击页面左上角的 logo然后断言“商品标题的 CSS 选择器是.product-title a”——这个选择器在改版后的页面上根本匹配不到任何元素。它甚至没有尝试去推理“product-name”和“product-title”在语义上是一样的也没有去检查页面实际渲染结果。那种感觉就像面试时遇到一个简历写得很漂亮的人上手干活才发现他只会背题不会解决新问题。这次事故之后我去翻了传统浏览器自动化工具的资料发现我过去一年多被“LLM 万能论”带偏了。传统工具的定位不是“智能”而是“确定性”只要页面结构稳定它就能精确执行速度快、成本低、可测试、可审计。这恰恰是生产环境最需要的东西。2. 浏览器自动化工具的底层逻辑驱动、选择器和状态机2.1 从驱动配置看“浏览器自动化”到底是什么很多人一提浏览器自动化第一反应是“就是用脚本控制浏览器”但真正上手才发现控制之前要先解决“驱动”问题。以 Selenium 为例你要用 Chrome 浏览器自动化就必须下载一个和浏览器版本完全匹配的chromedriver这个可执行文件相当于一个桥接层脚本发指令给 chromedriverdriver 再用 Chrome DevTools 协议去操作真实浏览器。这个“版本必须匹配”的规则是所有新手跨不过去的第一道坎。我见过太多人把 Chrome 升级到最新版结果chromedriver还是旧的启动脚本立刻报session not created或This version of ChromeDriver only supports Chrome version xx。解决办法不是粗暴地找个新版 driver 替换而是搞清楚你的浏览器主版本号去下载对应的大版本驱动。以 Chrome 为例驱动版本的前三位要和浏览器版本完全一致比如浏览器是 129.0.6668.89驱动最好也是 129.0.xxxx.x。Playwright 会选择性地绕开这个坑它提供了npx playwright install命令自动下载匹配的浏览器和驱动默认还会用补丁版本的 Chromium。这种“自带运行时”的设计让我第一次体验到了“零配置”的快乐。但便宜不是白占的如果你需要操作系统里已经安装的那个 Chrome比如要保留用户的登录态Playwright 也可以连接真实浏览器这时候同样需要手动指定executablePath版本匹配问题又回来了。2.2 选择器不是玄学是把页面结构翻译成可匹配的模式驱动配置好之后自动化脚本的核心工作就是“定位元素”。这段经历彻底改变了我对“智能”的理解。传统自动化工具的定位方式看起来很简单通过 CSS 选择器、XPath、文本内容或者 ARIA 属性去匹配页面上的元素。但真正高效的做法不是随便复制一个浏览器里生成的 XPath而是要理解页面结构的语义层级。我用一个具体例子说明。假设要抓取商品价格最常见的 CSS 选择器是.product-card .priceXPath 可以是//*[contains(class,price)]。这两种写法在页面稳定时都有效。但问题是现代前端项目经常带后缀哈希或者动态类名比如price_12345如果你写死了类名任何一次前端构建都可能让脚本失效。我的经验是“优先语义结构”而不是“优先视觉位置”。例如不要用#main div:nth-child(3) div span这种绝对路径因为只要上层加了一个 div整个表达式就废了而改用//span[contains(class,price)]或者[data-testidproduct-price]这种更接近业务含义的定位方式。Playwright 在这方面做得更现代它推荐getByRole、getByText、getByTestId这些 API 让我觉得像是给页面元素打了“语义标签”本质上是把测试思维引入自动化。2.3 为什么 AutoFlow 这类移动端自动化工具会让我意外测试完桌面端我又关注到移动端的浏览器自动化。手头刚好有一台安卓平板就试了热搜里提到的 AutoFlow。这个工具最特别的一点是没有独立的网页官网官方/社区主要在网盘或直链分享里提供 APK 下载所以很多新手第一反应是不敢装怀疑是病毒。我实测下来的感受是——成也直链败也直链。直链让工具避开了复杂的上架审核也省了服务器费用但“没有官网”这件事给用户带来了巨大的信任成本。但在平板浏览器里用下来AutoFlow 给了我一个很意外的启发它把“选择器”这个概念简化成了“屏幕坐标 文字/图标匹配”。在安卓上做自动化通常要借助无障碍服务权限AutoFlow 就像一个轻量版 RPA你可以录制一组操作也可以写流程脚本点击、长按、输入、滑动、全局断言都能做。对于平板浏览器里那些 H5 页面我可以用它循环读取某个动态数据区域这种能力在纯桌面自动化工具里反而不太好实现。我当时的项目是需要在平板上自动打开某个网页版工具每周点一遍所有菜单收集各页面的加载时间。用 AutoFlow 配置了一个点击流程跑了三天成功率很高只在平板休眠唤醒后因为权限弹窗卡住过一次。这让我意识到浏览器自动化的“另一条路”其实不只是在桌面 Web 里打转移动端浏览器的自动化同样是拼图的重要一块。3. 实操对比我用自己的小任务跑了三种方案3.1 任务设定在某个公开商品页抓价格、自动登录并筛选为了让测试有说服力我设计了一个不涉及任何敏感数据的标准任务打开一个公开的演示电商网站登录测试账号进入“数码产品”分类按价格从低到高排序抓取第一页全部商品名称和价格输出 JSON。整个流程总共 8 步打开首页 → 点击登录 → 输入账号密码 → 确认登录 → 点击分类入口 → 选择排序 → 等待列表加载 → 提取数据。这个任务复杂度适中既能体现 LLM Agent 的“语义理解”也能体现传统脚本的“确定性执行”对比起来比较公平。3.2 方案 A纯 LLM AgentGPT-4o 浏览器工具的表现方案 A 我用了 GPT-4o 配合一套开源的浏览器操作框架。大模型能看到页面的截图和可访问性树每一步自主决策。前十次运行里成功完成任务的次数是 7 次看起来还行但失败的 3 次问题都很典型一次是页面出现了“推荐弹窗”Agent 点了关闭按钮但弹窗动画还没结束它马上又点了一次结果第二次点击落在了背后的页面上误触了一个广告位跳到了无关页面一次是登录时输入框有前置校验Agent 输入完账号密码立即点了登录但页面还没完成 Ajax 验证直接报“账号格式错误”一次是排序下拉框选项需要 hover 之后再点击Agent 直接 click 了下拉框的收起区域导致排序逻辑没生效。这些失败让我很挫败。每一次失败大模型都会“主动反思”然后重新尝试但新的尝试往往又引入新的误判。整个过程像在教一个聪明但手不稳的孩子做精细活他理解你说的话但手脚跟不上。3.3 方案 B纯 Playwright 脚本的表现方案 B 就是我写一套 Playwright 脚本用固定的选择器走完整个流程。写脚本花了我大概四十分钟大部分时间用在等待条件判断上。我明确告诉脚本点击登录后等待“账户信息”元素出现再执行下一步点击排序后等待列表第一个商品的文本发生变化再开始抓取。全部用显式等待不用time.sleep。跑了一百次成功率是 100%。耗时稳定在 9 秒左右也就是 LLM Agent 的二十分之一。费用基本为零因为脚本不调用任何大模型接口。唯一的维护成本就是如果页面结构发生变化需要手动更新选择器。这个结果一点都不意外但真实跑完我还是很受冲击。因为在 LLM Agent 的语境里浸得太久我几乎快忘了“输入相同指令、每次结果都相同”是多么宝贵的特性。自动化测试领域这么多年沉淀下来的“等待策略”“重试机制”“快照断言”放在 RPA 场景里完全适用它们才是真正的工程资产。3.4 方案 C混合路线——LLM 负责写选择器脚本负责执行方案 C 是我自己尝试的新路线让 LLM 只做“离线代码生成”不参与运行时决策。具体操作是把网站页面代码喂给 GPT-4o让它生成一套 Playwright 脚本要求所有元素定位都用>unknown error: net::ERR_CONNECTION_CLOSED我一时间以为是网络问题排查了半天防火墙、代理甚至把代码里的超时时间都调整了一遍问题依旧。最后实在没办法进入交互模式手动启动 driver才看到真正的报错SessionNotCreatedException: This version of ChromeDriver only supports Chrome version 126那一刻真想抽自己。这也提醒我所有浏览器自动化项目都应该在启动时加一个版本检查。Playwright 有playwright install --dry-run可以检查浏览器版本Selenium 则需要自己在代码里定期去检测driver.capabilities[browserVersion]和本地chromedriver版本是否一致。我后来干脆给服务器设了策略禁止浏览器自动更新统一用版本固定的容器镜像。这个教训对所有人应该都适用自动化的前提是“环境可控”连环境版本都不可控后面所有稳定都是空谈。4.2 CSS 选择器和 XPath 该怎么选我的经验是“优先语义结构”经常有人问到底学 CSS 选择器还是 XPath 好。我的答案很直接优先学 CSS 选择器但 XPath 的“文本匹配”和“包含匹配”在某些场景下无可替代。CSS 选择器的优势是简洁、可读性好而且主流框架对 CSS 支持都很完善。比如.card .title、#username、input[nameemail]一眼就能看出定位逻辑。XPath 的优势是功能更强大可以按文本内容定位//button[contains(text(),立即登录)]这在按钮没有稳定 class 时特别好用。但我的真实建议是能不用 XPath 就不用因为 XPath 表达式一旦写长可读性很差而且很多 XPath 在页面结构微调时会静默失效不像 CSS 选择器失配时就直接报NoSuchElementException问题暴露得快。如果项目用的是 Playwright最好优先使用它封装的定位 APIgetByRole(button, { name: 立即登录 })这种“按角色和可访问名称定位”的方式比任何选择器都更贴近语义也能兼顾可访问性。真正要避开的坑是“绝对路径式”选择器。比如#root div div ul li:nth-child(3) a这种选择器现在能用但任何一次前端结构调整都让你当场去世。反观相对路径ul.list li a或者text查看详情就有韧性得多。写自动化脚本要把页面当成一个“接口文档”而不是“一串像素”。4.3 页面异步加载导致的竞态条件等元素而不是等 sleep异步加载是我踩过最深的坑没有之一。现代网页几乎没有纯静态的很多数据都是 Ajax 加载后 DOM 才出现。新手最容易犯的错误是“等待时间固定”比如time.sleep(5)这在网络快的时候没问题一旦网络慢5 秒不够用网络快的时候又白白等很久。正确的思路是基于条件等待。Selenium 里是WebDriverWait配合expected_conditionsPlaywright 里是locator.wait_for()或expect(locator).to_be_visible()。我处理竞态条件的核心心法是永远等“业务状态”而不是等“时间”。什么是业务状态就是要抓数据的列表多出了一个特定元素或者某个“加载完成”的暗号出现了。比如抓取价格列表前我会等[data-testidproduct-list] .product-card元素数量大于 0而不是等 10 秒。这种写法在 99% 的情况下都比固定 sleep 更快且更稳定。还有个小技巧对于无限滚动页面可以用循环滚动到底部每次滚动后判断页面高度是否变化而不是随便滚几屏。我见过有人为了兼容无限滚动直接向下滚 100 次结果页面上所有数据全被滚“懒加载”出来内存直接爆掉。正确的实现是记录上一次滚动高度和当前滚动高度相等时就说明到底了。4.4 验证码、弹窗、懒加载这些“反自动化”设计的破解思路“破解”这个词不准确我的意思是怎么合理应对。验证码存在的意义就是拦截自动化如果你的自动化任务需要频繁登录验证码是绕不过去的坎。我的经验是能避免就避免比如尽量用持久化登录态保留 cookie / storage而不是每次都走登录流程。Playwright 可以在登录一次之后把 storage state 存成 JSON下次启动直接加载——这在内部测试平台上非常实用能规避掉 90% 的登录验证码问题。弹窗是另一个高频干扰源。处理弹窗我不用复杂逻辑而是准备一个“清除干扰”的函数遇到模态框就点关闭遇到隐私弹窗就点同意然后重试主流程。关键在于给这个函数设置“失败即放弃”的熔断逻辑防止脚本在弹窗上死循环。我见过最离谱的场景是自动化脚本点击了一个不可见的遮罩层然后触发了一连串的事件冒泡把页面切到了另一个路由最后卡在空白页。为了避免这种问题所有点击动作都应该先行判断元素是否可见、是否可点击。懒加载相对简单需要哪个元素就滚动到哪个元素附近再等待它可见而不是一上来就等待所有内容加载完成。5. 移动端浏览器自动化的实测AutoFlow 和那些“直接下载链接”5.1 AutoFlow 是什么为什么没有官网AutoFlow 是一款安卓端的自动化工具主打流程编排支持点击、滑动、文本输入、条件判断、循环等操作。它最特殊的地方不是功能而是分发方式没有独立的网页官网官方和用户主要在分享链接里发布 APK。我第一次听说时第一反应也是“这也太不正规了”但研究了一下发现不少这种工具选择不上架商店主要是为了避开发布审核周期和抽成尤其是自动化、无障碍相关工具商店审核卡得很严。所以当我在热搜词里看到“autoflow(安卓自动化) 没有独立的网页官网,直接用下载链接在平板浏览器”我想说这是真实情况。我自己的做法是先用平板浏览器打开某一个网络收藏夹里的直链下载 APK安装后手动给无障碍权限。整个过程确实比从应用商店安装麻烦但胜在直接不用绕过什么限制。看到这种工具我的态度是“谨慎但别一刀切”。先检查下载链接的域名是否正规有没有可疑权限比如请求短信、通讯录再在闲置平板上试用一段时间确认没问题再放到主力设备上。5.2 在平板上装 AutoFlow 的真实体验从 APK 下载到无障碍权限我测试用的是一台普通的安卓平板系统版本不高不低。下载 APK 后系统可能会弹“未知来源”的警告这里是需要主动确认的。安装完成后打开 AutoFlow第一步就是引导开启“无障碍服务”这个环节是在系统设置里操作需要手动找到“已安装的服务”列表把 AutoFlow 切换为开启状态。开启无障碍服务后AutoFlow 可以读取屏幕内容、模拟点击这其实和桌面端浏览器的读 DOM 本质上是同一件事都是把“可交互的信息”暴露给自动化引擎。但差别在于移动端很多网页是用 WebView 渲染的传统的无障碍树可能不完整所以 AutoFlow 的定位逻辑里“图像识别 文本匹配”会比纯节点定位更实用。我实测了在平板浏览器上跑一个 H5 页面自动化流程打开一个数据报表页面 → 点击日期控件 → 选择最近七天 → 截图保存。AutoFlow 每一步都提示我录制一个操作我也能手工设置“等待某段文字出现”作为同步点。整体体验很像轻量版的 UiPath但跑在安卓端对硬件要求也低。5.3 用 AutoFlow 在平板浏览器里做自动化和桌面端有哪些不同最明显的不同是“执行上下文”。桌面端浏览器自动化我可以假设窗口大小固定、网络环境稳定但在平板上我遇到的最大的坑是屏幕旋转。平板一旋转屏幕坐标就变了原本录制的点击位置全部偏移。我的解决办法是在 AutoFlow 流程里强制固定屏幕方向或者在每一步都用“元素文字”而不是“坐标”去定位尽量减少对屏幕坐标的依赖。第二个不同是“后台限制”。安卓系统为了省电可能会在几分钟后杀掉后台进程这就导致自动化只跑了一半就被系统中断。解决办法是在系统设置里关闭对 AutoFlow 的电池优化个别系统还要在“最近任务”里给它加锁。这个细节我一开始没注意前几次自动化任务总是神秘夭折后来加了白名单才稳定下来。第三个不同是“无障碍焦点的时效性”。有时屏幕内容已经变了但无障碍服务返回的节点还是旧的AutoFlow 如果立刻执行下一步就会点错位置。我的经验是在关键步骤后增加 500~1000ms 的稳定等待或者用“等待文本出现”来兜底。5.4 自动化工具的合规使用边界别拿来干坏事聊到这里必须补一句关于合规的话。浏览器自动化、移动端自动化都是强大的工具但它们应该被用在合法、合规的范围内比如测试自己的业务系统、抓取有授权或公开的数据、做无障碍辅助操作。不要拿这些工具去破解验证码、绕过付费墙、批量注册、抢占资源、恶意爬取个人信息。这既是法律底线也是工程伦理。我在团队内部使用自动化之前都会和法务确认数据使用边界。不要觉得这是小题大做现实中发生过很多因为自动化脚本“越界”而惹上麻烦的案例。工具越强使用者越要自律——这也是“另一条路”能走长远的前提。6. 我的结论LLM Agent 和传统自动化的正确缝合姿势6.1 把 LLM 用在最需要“理解”的地方把执行交给确定性脚本测完这么多工具我对两者分工的理解清晰了很多。LLM Agent 的真正优势是“语义理解”和“开放世界建模”它适合处理那些没有固定答案、需要动态推理的任务比如“总结这封邮件的内容并写一封得体的回复”“帮我查一下几个平台上的同一款手机哪个更便宜”。而浏览器自动化脚本的核心优势是“确定性和可测量”。它的执行结果可预期成功失败一目了然出现 bug 时可以快速定位。对于生产环境里的任务确定性比智能更重要。为了一次价格抓取我不需要它“聪明地猜出价格在哪”我需要它“准确且迅速地把价格取回来”。所以我现在的正确缝合姿势是把大模型用在上游和下游的“认知”环节——比如从自然语言需求生成脚本骨架、从页面快照里识别业务字段而在成百上千次的高频执行环节全部交给 Playwright 或 AutoFlow 这种确定性工具去跑。这样既享受了大模型的理解能力又避开了它的不确定性和成本。6.2 我给团队的几条选型建议如果你现在正面临选型我这几条经验或许可以参考任务流程明确、页面结构相对稳定直接上 Playwright 或 Selenium不要迷信 LLM Agent。你缺的不是智能而是执行框架。需要识别复杂语义、分类提取非结构化信息让 LLM 做“离线解析”比如把 HTML 文本交给它提取结构化字段再用脚本拿结果去操作页面。页面改版频繁、没有稳定测试标识优先推动前端团队加>
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/9/8 5:22:26
Unity 3D模型展示、标注与拆装动画的工程化实现
2026/9/8 5:22:26
WorkBuddy实战:用效率智能体将周报时间从2小时压缩到10分钟
2026/9/8 5:17:26
Nacos接入达梦数据库实战:SQL方言转换与驱动配置全攻略
2026/9/8 6:02:28
从QEMU仿真源码到硬件复刻:静态评测证据工程实践
2026/9/8 6:02:28
Jellyfin媒体服务器搭建与硬件转码优化全攻略
2026/9/8 6:02:28
自制准直驱执行器:行走机器人关节的力控与调参实战
2026/9/8 6:02:28
汽车OTA升级技术解析:从原理到实践的全流程指南
2026/9/8 6:02:28
GLM-5.3与Flash双模型接入评测:从API到批量任务的完整指南
2026/9/8 5:57:28
Agent测试实战:从传统断言到轨迹验证的三层框架与回归方法论
2026/9/8 0:02:01
中国车企再破谣言,GAC吉利零跑获欧盟安全五星
2026/9/8 0:02:01
Compose Hot Reload新增MCP服务器助AI智能体调试
2026/9/8 0:02:01
你熟悉的GoPro正在悄然改变
2026/9/8 0:43:11
超人会飞不算本事:系统稳定依赖清晰规则与边界设计
2026/9/8 1:13:27
超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论
2026/9/8 2:18:22
基于CNN的调制信号识别:MATLAB实现时频图分类实战