浏览器 Agent:教 AI 学会"点点点"

月底的周五下午,老李盯着屏幕上那张竞品价格监控表,脸比窗外的乌云还黑。二十个竞品网站,每个要找到产品页面、记录价格、截图存档,两天时间全耗在这上面。他正把保温杯往嘴边送,突然看见小王对着屏幕咧嘴笑。

“笑什么呢?还不帮我整理报价单?”老李没好气。

“老李,我刚让 Agent 帮你把竞品价格全爬下来了,连截图都存好了。”小王把笔记本转过来,一个漂亮的表格赫然在目,最后一列是整齐的价格截图缩略图。

老李差点把枸杞喷出来:“你让 AI 去点网页?你不怕它手滑把我们产品全买了?还是用爬虫写的?”

“不是爬虫。就是让 AI 像人一样打开浏览器,一页一页看,找到价格,复制下来,还知道避开‘立即购买’按钮。它全程录屏,你要不要看回放?”

老李放下杯子,将信将疑地凑了过去。


浏览器 Agent 是怎么“看”网页的?

小王打开一段录屏:浏览器自动打开竞品 A 的官网,鼠标指针在页面上缓缓移动,停在“产品”导航栏上,精准点击,进入列表页,逐一滚动,找到价格元素,高亮、截图、记录。整个过程像一个看不见的手在操作。

“这后面是 Playwright 驱动浏览器,再加上一个视觉理解模型。”小王敲了几下键盘,调出架构图。

“传统爬虫靠 HTML 标签定位,但网站一改版,爬虫就抓瞎。浏览器 Agent 不一样——它真‘看’页面截图,用视觉模型理解内容。‘价格通常在 ¥ 符号附近’‘立即购买按钮通常是橙色大按钮’,这些人类靠视觉判断的东西,Agent 也能学会。”

图:浏览器 Agent 的感知-行动循环——视觉理解 + 自动化操作


元素定位:点哪里,怎么点?

“那它怎么知道这个按钮是‘产品’而不是‘关于我们’?”老李指着录屏问。

“三种定位方式,按优先级来。”小王掰着手指。

第一,语义定位。 视觉模型看完截图后,用自然语言描述目标元素:“页面顶部导航栏中,从左数第二个链接,写着‘产品中心’。” Agent 再调用 Playwright 通过文本或角色定位。它不是说“点坐标(300, 50)”,而是说“点那个写着‘产品中心’的链接”,即使页面布局变了也能自适应。

第二,CSS 选择器回退。 如果视觉模型找不到,它会去翻源码,用 .nav > li:nth-child(2) > a 这种标准选择器。这是传统爬虫的看家本领,作为保底。

第三,坐标兜底。 前两招都不行?那就真的算坐标。视觉模型输出元素在截图中的相对位置,换算成页面绝对坐标点击。这最像人类“看着点”,也最容易因为分辨率变化而出错。

“三种方式结合,准确率就上去了。而且 Agent 操作前会先 hover 过去高亮,确认对了才点击,点错了还能回退——比你当年手滑删库靠谱多了。”小王笑道。

老李白了他一眼。


操作序列规划:从开网页到下单,要几步?

“就算能点按钮,那它怎么知道先点哪个后点哪个?抓价格可不是一步操作。”

“这就用上我们上次聊的任务分解了。”小王打开 Agent 的执行日志,是一系列 Thought 和 Action。

[Thought] 用户要求获取产品 X 的今日售价。我需要:1. 打开网站 2. 搜索产品 3. 进入详情页 4. 找到价格元素 5. 记录。
[Action] goto("https://example.com")
[Observation] 页面加载完成。
[Thought] 首页已打开,顶部有搜索框。我需要点击搜索框输入产品名称。
[Action] click("搜索框", method="semantic")
[Action] type("产品X")
[Action] press("Enter")
...

小王解释道:“浏览器 Agent 内部用的是 ReAct 循环。但它多了一个‘观察’维度——每次操作后的页面截图变化。它不会盲目执行预先写好的步骤,而是根据当前页面状态动态调整。比如搜索后跳到了促销页,它会自己判断‘这不是详情页,需要再点一次’。”

老李若有所思:“这不就是给人写操作手册吗?‘打开网站,搜索产品,点进去,找价格’——只不过看手册的是 AI。”

“对!你给它的指令就是一份高级操作手册,它自己拆成具体动作。”


错误恢复:弹窗、加载慢、验证码

“那网页弹了个广告怎么办?或者突然要登录?”老李的担忧一个接一个。

“这就是浏览器 Agent 最考验工程能力的地方。它有一整套异常处理策略。”

小王在代码里演示了安全回退:

python
# 浏览器 Agent 的安全操作包装(示意)
def safe_click(agent, element_desc, max_retries=3):
    for attempt in range(max_retries):
        try:
            # 执行点击,并等待页面稳定
            agent.click(element_desc)
            agent.wait_for_load_state("networkidle", timeout=5000)
            return True
        except TimeoutError:
            # 可能弹窗拦截,尝试关闭弹窗
            if agent.visible("弹窗关闭按钮"):
                agent.click("弹窗关闭按钮")
                continue
        except Exception:
            # 遇到意外,截图并暂停等待人工指示
            agent.screenshot(f"error_{attempt}.png")
            if attempt == max_retries - 1:
                return False

“遇到弹窗,Agent 会优先找关闭按钮;遇到登录墙,它会暂停并通知你‘需要人工登录’;如果同一个操作失败三次,就放弃这个网站,记录异常,接着跑下一个。绝对不会在同一个坑里死循环。”

老李追问:“验证码呢?”

“目前所有浏览器 Agent 的阿克琉斯之踵。遇到图片验证码,Agent 会自动截图保存,然后暂停,等你人工识别一次。识别过一次后,它会把这段操作录下来,下次遇到类似情况可以回放。但完全自动绕过验证码——现在还没有安全又合法的方案。”


安全模式:防手滑的最后防线

老李最担心的还是那个问题:“你怎么保证它不会点‘购买’?万一它真下单了怎么办?”

小王点开 Agent 的安全配置,里面列着几条铁律。

“第一,视觉黑名单。模型训练时学会了识别‘立即购买’‘提交订单’‘确认支付’这些高危按钮,Agent 在任何页面都不会点击它们。第二,操作拦截。Playwright 层面拦截所有包含 buycheckoutpayment 的 HTTP 请求。第三,金额阈值。只要页面包含 ¥ 符号且后面跟着大于 0 的数字,Agent 会暂停并请求人工确认。”

python
# 浏览器 Agent 安全配置示例
SAFETY_RULES = {
    "forbidden_text": ["立即购买", "提交订单", "确认支付", "删除"],
    "forbidden_urls": ["*/checkout", "*/payment", "*/delete"],
    "require_approval_on": {
        "amount_detected": True,   # 页面包含金额时暂停
        "form_submit": True,       # 提交任何表单前暂停
        "redirect_external": True  # 跳转到外部域名前暂停
    },
    "read_only_mode": True  # 全局只读,禁止任何修改操作
}

“如果你把它设为‘只读模式’,它连表单都不会填,只能获取文本和截图。你那个竞品价格抓取,跑的就是只读模式,绝对安全。”

老李终于放心了,但又问:“那帮我抢特价机票是怎么回事?”

小王眨眨眼:“抢票用的是写模式,但我开了操作日志和二次确认。它选好航班后会截图发给我,我点一下‘确认’它才下单。等于我才是最后拍板的人,它只是帮我填了信息、选了座。”


从竞品抓取到政府申报

老李指着那份已经填好的竞品价格表:“这个表,以后每个月自动跑一次?”

“可以。我已经把配置写成了定时任务,每个月一号凌晨自动执行,早上你就能在邮箱里看到新报表。”

老李沉默了一会儿,又想起一件事:“上周行政说有个政府补贴申报,要在政务网上填一堆表格,格式复杂得要命,能搞定不?”

小王打开另一个测试记录:“已经跑通了。Agent 先读取咱们公司的基本信息文件,然后打开申报网站,一页一页填表,遇到不清楚的字段会暂停,问你‘社保编号填哪个’。填完后生成预览截图让你确认,你点一下‘提交’,它才点提交。”

老李靠在椅背上,拧开保温杯,喝了一口已经微凉的枸杞水。

“嗯……还有点意思。以前我总觉得 AI 只能聊天写诗,没想到它真能干活。”

“老李,你这就是认可了?”

“我没说认可。我是说——下不为例啊。以后有这种机械重复的网页操作,先让 Agent 试,别再让我手动点两天了。”

他站起来走到门口,又折回来:“那什么,你刚才说它视觉理解用的是截图,那如果网页有动画、或者价格是用 Canvas 画的,它还能认出来吗?那个视觉模型是通用的还是专门训练过识别网页元素的?给我看看你的 prompt。”

小王笑着把调试界面的截图调出来,老李端着保温杯,又拉了把椅子坐下。窗外已是黄昏,竞品价格表静静地躺在共享文件夹里,第一次没有带着老李的怨气。

实战教程大纲
代码生成 Agent:你的新"初级开发工程师"?