用 Python 搭建 Browser Use Agent,先给 Agent 一个模型、一个独立的 Browser 会话和一个能核对答案的任务。示例从本地网页读取标题和编号。Pydantic 校验返回格式,Python 程序再逐项比对网页上的值。
有用户在 GitHub 上报告过动作校验错误。旧版运行中,模型生成的浏览器动作未通过校验,任务无法继续。下面的示例按开源快速入门和输出格式文档编写,已核对接口,未做端到端运行。
要点
应用需要自行控制浏览器会话、任务和结果校验时,使用 Browser Use Python 库。
第一个任务用本地 HTML 和未登录任何账户的新浏览器会话。
浏览器和模型的运行位置可以分别选择。Chromium 在本地运行时,
ChatBrowserUse仍会调用托管模型。history.is_successful()是 Agent 自报的状态。结合服务器日志和实际字段核对结果。测试页只放已知文本,省去表单、文件上传和账号。
先选浏览器和模型运行在哪里
模型决定要发出什么动作,浏览器负责打开网页并执行动作,Python 程序连接两者。先判断任务需要浏览器 Agent、固定的 Playwright 脚本,还是只要网页搜索。
| 方案 | 浏览器位置 | 适用情况 |
|---|---|---|
| Python 库与本地浏览器 | 运行脚本的机器 | 读取回环地址的测试页,在 Python 中验收 |
| Python 库与远程浏览器 | 脚本可连接的远程会话 | 已有远程浏览器资源,目标网页对它可达 |
| Browser Use Cloud 托管 Agent | 托管环境 | 需要托管 Agent API,且目标网页对它可达 |
下文用第一种方式。按快速入门把 BROWSER_USE_API_KEY 放进环境变量或本地 .env,避免把密钥加入版本库。在安装了 uv 的新项目目录执行下列命令。
uv init --python 3.12
uv add browser-use
uvx browser-use install安装步骤会准备 Chromium。需要复现环境时保留锁文件。模型适配器文档列出了 ChatOllama 等选项。换模型后继续用同一测试页和同一组预期值,既检查浏览器动作,也检查最终输出。Cloud 快速入门另有认证和会话配置。
有位 Reddit 上的测试人员 想用自托管模型把客户数据留在内部环境。遇到同样的要求,就应另选本地模型。本例交给模型的只有虚构测试数据。
准备一个答案已知的测试页
将下面的 HTML 保存为 fixture/index.html。页面只包含测试文字和虚构编号。另开终端运行 HTTP 服务,它只提供 fixture 目录。
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Inventory fixture</title>
<main>
<h1>Inventory Check</h1>
<p>Reference code: BU-741</p>
</main>
</html>uv run python -m http.server 8765 --bind 127.0.0.1 --directory fixture127.0.0.1 指向运行浏览器的机器。远程浏览器打开这个地址会访问远程机器自己。本例让服务和浏览器在同一台机器上,需要排查时可先手动打开测试页。
运行 Agent 并逐项核对
在项目根目录保存 check_page.py。Browser 参数文档说明导航域名限制,Agent 参数文档说明怎样设置输出类型。把 URL 放进任务,预期值只留在验证代码里,模型需要从网页取得答案。
import asyncio
from tempfile import TemporaryDirectory
from browser_use import Agent, Browser, ChatBrowserUse
from pydantic import BaseModel
URL = "http://127.0.0.1:8765/"
class PageCheck(BaseModel):
heading: str
reference: str
async def main():
with TemporaryDirectory(prefix="browser-use-fixture-") as profile:
browser = Browser(
headless=True,
user_data_dir=profile,
allowed_domains=["127.0.0.1"],
accept_downloads=False,
)
try:
agent = Agent(
task=(
f"Open {URL} and read its visible heading and reference code. "
"Return only those two values. Do not interact with any form."
),
browser=browser,
llm=ChatBrowserUse(),
output_model_schema=PageCheck,
)
history = await agent.run(max_steps=5)
result = history.structured_output
expected = PageCheck(heading="Inventory Check", reference="BU-741")
if result != expected:
raise RuntimeError("The output does not match the fixture.")
print(result.model_dump_json())
finally:
await browser.stop()
if __name__ == "__main__":
asyncio.run(main())uv run python check_page.py如果脚本成功打印结果,标题应为 Inventory Check,编号应为 BU-741。两项都是测试页预设的值。如果出现不匹配,先查历史记录,再考虑调整步数。增加步数可能只是多重复几次错误动作。
分开检查访问、输出和副作用

先在服务器日志里查这次运行是否请求了 /,再对照 history.urls()、history.errors() 和脚本输出。访问记录和对象校验各自回答一个问题。输出格式文档也区分了任务结束、Agent 自报成功和外部可验证的结果。
独立会话可避免把日常账户带进测试。连接已有浏览器会改变 Agent 能接触的会话和 Cookie。导航白名单只管导航。后续接入真实应用时,用只读测试账号,并在服务端限制写入权限。具体边界见浏览器 Agent 安全风险。
从第一个失败环节开始排查
| 现象 | 先看哪里 | 下一步 |
|---|---|---|
| 浏览器启动但服务未收到请求 | 运行位置、回环地址、端口、导航规则 | 从运行 Chromium 的机器打开测试页 |
| 模型服务拒绝请求 | 密钥、端点、适配器、模型权限 | 先读服务商错误,再调浏览器 |
| 历史记录里出现动作校验错误 | 模型适配器和 Browser Use 版本 | 用官方文档列出的适配器重跑 |
| 对象可解析但字段不符 | 浏览器观察内容和模型抄录值 | 逐项对照 HTML 和请求日志 |
另一个远程 CDP 问题记录了浏览器协议调用挂起。它和动作校验失败发生在不同环节,也都是特定版本的个案。以自己的错误日志确定排查顺序。
遇到可能创建记录或发送消息的任务,超时后先到目标系统确认是否已经执行,再决定是否重试。这个只读测试页可以重复访问,再对照请求日志。
什么时候值得用 Python
需要下游代码消费并核验结构化字段时,适合保留 Python 集成。URL 和选择器稳定、步骤固定时,可直接用浏览器脚本。只想临时核对页面文字,打开测试页就够了。Tabbit 与 Browser Use 对比和 Agentic Browser 入门解释了浏览器界面与代码集成的不同用途。
第一次运行以页面确实收到请求且两个字段匹配为验收目标。此后每次只更换浏览器、模型或目标页面中的一项,再用相同方式核对。
常见问题
使用 Python 库一定要申请 Browser Use API Key 吗?
示例的 ChatBrowserUse 需要 Browser Use 密钥。其他适配器各有配置,本地 Ollama 可以不用这个密钥。
能接本地 Ollama 模型吗?
可以。官方列出了 ChatOllama。需要确认具体模型既能生成浏览器动作,也能按指定结构返回结果。
如何让第一次任务保持只读?
使用没有写入端点和账号的测试页,并启用独立浏览器会话。接入真实应用时,还要在服务端配置只读权限。
为什么远程浏览器打不开 localhost?
回环地址指向远程浏览器所在机器。本教程应把浏览器和测试页服务放在同一台机器,或提供远程环境可访问的测试端点。
history.is_successful() 有什么用?
它记录 Agent 对本次任务的判断。还要独立检查目标网页和返回字段,才能确认任务完成。
structured_output 为空要先查什么?
先查看历史中的导航、模型服务和动作错误。确认设置了 output_model_schema 且任务确实到达完成阶段,再调整结构或步数。