在这篇博客文章中,你将了解:
- Stagehand 是什么,以及它为浏览器自动化提供了什么。
- 将 Stagehand 与 Bright Data 的 Browser API 提供的基于云的隐身浏览器会话结合使用的好处。
- 在 Stagehand 中设置 Browser API 的分步指南。
让我们开始吧!
什么是 Stagehand?
Stagehand 是由 Browserbase 开发的开源浏览器自动化框架。它将自然语言 AI 与确定性代码结合起来。它通过让你选择何时使用每种方法,解决了脆弱的基于选择器的工具(如 Playwright)与不可预测的 AI 代理之间的权衡问题。
它的工作方式是使用底层 LLM 加上受控执行层,将指令转换为浏览器操作和结构化输出。Stagehand 还支持基于浏览器的 AI 代理开发。

它还具备一些能力,使其能够作为一种 AI 网页抓取工具运行。Stagehand 得到了庞大开发者社区的支持,在 GitHub 上拥有超过 22.9k 星标,并且在 npm 上每周下载量超过 100 万。
Stagehand 功能特性
Stagehand 提供的主要功能特性包括:
act()执行:使用简单英语提示执行浏览器操作,如点击、滚动和填写表单。extract()结构化数据:将页面内容提取到严格的 Zod 验证模式中,以便可靠地用于下游。observe()页面感知:在执行操作前检测页面上的可操作元素,提高安全性和精确度。agent()自主工作流:以最少监督端到端运行多步骤浏览器任务。- 自修复自动化:适应 UI 变化,减少脆弱的基于选择器的失败。
- 操作缓存: 通过缓存操作避免冗余的 LLM 调用,确保跨多次运行的高度可预测且注重预算的执行。
- LLM 灵活性:可与多个提供商配合使用,同时保持执行的确定性和可调试性。
- 可组合原语:组合 act、extract、observe 和 agent 来构建自定义自动化管道。
- 面向开发者的工具:专为可维护性、可复现性以及与现代 AI 系统集成而设计。
在官方文档中了解更多。
为什么将 Stagehand 与 Bright Data 的 Browser API 结合使用
像 Stagehand 这样的浏览器自动化工具会遇到相同的核心问题:
- 网站会使用机器人检测系统、验证码、指纹识别和 IP 信誉检查主动拦截自动化流量。这会使自动化变得脆弱,因为脚本可能在测试中可用,但在生产中不可预测地失败。
- 在本地或自管理基础设施上运行许多浏览器实例非常消耗资源。浏览器资源密集,需要大量 CPU 和内存。这使得同时运行许多实例成本高昂,并且难以可靠扩展。
- 管理代理和地理分布会增加运营开销。随着时间推移,对于生产级抓取或 AI 代理工作负载而言,这种复杂性会变得难以维护。

Bright Data 的 Browser API 通过将本地浏览器执行转移到为规模和隐身性而设计的完全托管、基于云的基础设施,解决了这些问题。
你无需在本地处理浏览器,而是可以通过单个 CDP 端点连接。你可以访问远程、预配置的浏览器,并内置代理轮换、验证码破解和高级指纹规避功能。
Bright Data 脱颖而出之处在于其企业级架构,由一个拥有超过 4 亿住宅 IP 的代理网络提供支持。这能够实现高匿名性、全球地理定位和无限并发,同时达到 99.95% 的成功率,并提供受 SLA 支持的 99.99% 正常运行时间。
如何将 Stagehand 与 Browser API 集成
在本章中,你将看到如何使用 Stagehand 自动化远程浏览器实例。具体而言,你将通过 Bright Data 的 Browser API 连接到隐身、反检测、可无限扩展的云端浏览器会话。
请按照以下说明操作。
先决条件
要跟随本教程部分操作,请确保你具备:
- 本地已安装 Node.js 20+(推荐 Node.js 22+)。
- 来自受支持的 Stagehand AI 提供商的 API 密钥(这里,我们将使用 OpenAI API 密钥)。
- 一个 Bright Data 账户。
- 对 Stagehand API 及其 AI 驱动的浏览器自动化能力有基本了解。
第 #1 步:初始化 Stagehand 项目
通过遵循快速入门指南来设置一个新的 Stagehand 项目。或者,运行以下命令:
npx create-browser-app bright-data-stagehand-example
npx create-browser-app 命令会在 bright-data-stagehand-example 目录中创建一个新的 Stagehand 项目。
运行后,你应该会得到:

接下来,进入项目目录:
cd bright-data-stagehand-example
你的项目结构应如下所示:
bright-data-stagehand-example/
├── .cursorrules
├── .env.example
├── claude.md
├── index.ts
├── package.json
├── README.md
└── tsconfig.json
花几分钟探索生成的文件,并熟悉项目结构。重点关注 index.ts,它代表 Stagehand 主文件。
现在,清理 index.ts 文件,只保留:
import { Stagehand } from "@browserbasehq/stagehand";
你很快就会看到如何将 Stagehand 连接到 Bright Data 的 Browser API。干得好!
第 #2 步:配置环境变量读取
你的 Stagehand 云端自动化项目将依赖一些密钥(例如,AI 提供商 API 密钥、Bright Data Browser API 凭据等)。最佳实践不是将它们硬编码在代码中,而是从环境变量加载它们。
默认情况下,Stagehand 不会自动加载 .env 文件。要启用该功能,请先安装 `dotenv 软件包:
npm install dotenv
接下来,在 index.ts 中添加以下内容:
import dotenv from "dotenv";
dotenv.config({
path: ".env",
});
现在,你需要定义一个 .env 文件。你可以通过复制运行 npx create-browser-app 时生成的 .env.example 文件来创建它。否则,手动向你的 Stagehand 项目添加一个 .env 文件:
bright-data-stagehand-example/
├── .cursorrules
├── .env # <---------
├── .env.example
├── claude.md
├── index.ts
├── package.json
├── README.md
└── tsconfig.json
使用你的 AI 提供商 API 密钥(在本例中为 OpenAI)填充 .env 文件:
OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"
将你的 <YOUR_OPENAI_API_KEY> 占位符替换为实际的 OpenAI API 密钥。
Stagehand 将在运行时自动读取 OPENAI_API_KEY env,因此不需要额外配置。太好了!
第 #3 步:开始使用 Bright Data Browser API
现在是获取 Bright Data Browser API 的基于 CDP 的远程连接 URL 的时候了。
如果你还没有,创建一个 Bright Data 账户。如果你已有账户,请登录并进入控制面板:

接下来,从左侧菜单导航到“Web Access > Web Access API”选项:

如果你已经在“My APIs”表中看到一个 Browser API 条目(如下,通过 browser_api API),那就可以继续了:

否则,点击“Create API”按钮上的下拉菜单并选择“Browser API”:

这将启动 Browser API 设置向导。为你的 Browser API 命名(例如,browser_api)并根据你的需求配置该 API:

完成后,点击“Add API”按钮。进入 Browser API 详情页面:

在这里,你将找到基于 CDP 的集成连接详情(“Puppeteer / Playwright”下的 URL)。Browser API WebSocket URL 遵循此格式:
wss://<BROWSER_API_USERNAME>:<BROWSER_API_USERNAME>@brd.superproxy.io:9222
从 Browser API 页面复制 Browser API 用户名和密码,并将它们添加到你的 .env 文件中:
BRIGHT_DATA_BROWSER_API_USERNAME="<BROWSER_API_USERNAME>"
BRIGHT_DATA_BROWSER_API_PASSWORD="<BROWSER_API_PASSWORD>"
稍后你将在 index.ts 中使用这些变量来构建远程 CDP 连接 URL。
现在,你已经拥有通过 Bright Data Browser API 使用 Stagehand 进行云端浏览器自动化所需的所有构建模块。太好了!
第 #4 步:在 Stagehand 中连接到 Bright Data Browser API
在 index.ts 中,首先从环境变量读取 Browser API 凭据:
const BRIGHT_DATA_BROWSER_API_USERNAME = process.env.BRIGHT_DATA_BROWSER_API_USERNAME || "";
const BRIGHT_DATA_BROWSER_API_PASSWORD = process.env.BRIGHT_DATA_BROWSER_API_PASSWORD || "";
接下来,在 main() 函数内初始化 Stagehand,以便通过 CDP WebSocket URL 连接到 Bright Data Browser API:
async function main() {
// configure Stagehand to connect remotely to Bright Data's Browser API
// and use an OpenAI model
const stagehand = new Stagehand({
env: "LOCAL",
localBrowserLaunchOptions: {
cdpUrl: `wss://${BRIGHT_DATA_BROWSER_API_USERNAME}:${BRIGHT_DATA_BROWSER_API_PASSWORD}@brd.superproxy.io:9222`,
},
model: "openai/gpt-5.4-mini",
});
// launch Stagehand and get the browser page
await stagehand.init();
const page = stagehand.context.pages()[0];
// browser automation logic...
// close the Stagehand instance and release the browser resources
await stagehand.close();
}
main().catch(console.error);
上面的代码片段使用根据从环境变量读取的凭据构建的经过身份验证的 Browser API WSS URL 来配置 Stagehand。然后它启动一个远程浏览器会话,并公开一个用于自动化的 page 对象。运行你的自动化逻辑后,它会关闭会话并释放所有远程浏览器资源。
在上面的示例中,我们配置了 OpenAI GPT-5.4 Mini。请注意,任何其他 OpenAI 模型(或受支持的 AI 提供商设置)也都可以使用。
关键部分在 Stagehand 构造函数中。该配置起初可能看起来有点令人困惑,因为要连接到远程浏览器,你仍然需要将 env 设置为 "LOCAL"。然后,在 localBrowserLaunchOptions 内,你需要通过 cdpUrl 字段提供 Bright Data Browser API WSS URL。
因此,即使 env 设置为 "LOCAL",Stagehand 实际上也会连接到 Bright Data 的远程反检测云浏览器实例。
现在你可以用一个简单示例测试该集成,以确认一切正常工作。
第 #5 步:验证 Bright Data Browser API 集成
要检查与 Browser API 的集成是否有效,请尝试以下自动化逻辑:
// connect to the example.com page
await page.goto("https://example.com");
// take the screenshot of the page
await page.screenshot({
path: "screenshot.png",
type: "png",
fullPage: false,
});
这会指示远程浏览器(通过 Bright Data Browser API 暴露)打开 example.com 并捕获屏幕截图。
把它们放在一起:
// index.ts
import { Stagehand } from "@browserbasehq/stagehand";
import dotenv from "dotenv";
// load the environment variables from the .env file
dotenv.config({
path: ".env",
});
// read the Bright Data Browser API credentials
const BRIGHT_DATA_BROWSER_API_USERNAME = process.env.BRIGHT_DATA_BROWSER_API_USERNAME || "";
const BRIGHT_DATA_BROWSER_API_PASSWORD = process.env.BRIGHT_DATA_BROWSER_API_PASSWORD || "";
async function main() {
// configure Stagehand to connect remotely to Bright Data's Browser API
// and use an OpenAI model
const stagehand = new Stagehand({
env: "LOCAL",
localBrowserLaunchOptions: {
cdpUrl: `wss://${BRIGHT_DATA_BROWSER_API_USERNAME}:${BRIGHT_DATA_BROWSER_API_PASSWORD}@brd.superproxy.io:9222`,
},
model: "openai/gpt-5.4-mini",
});
// launch Stagehand and get the browser page
await stagehand.init();
const page = stagehand.context.pages()[0];
// connect to the example.com page
await page.goto("https://example.com");
// take the screenshot of the page
await page.screenshot({
path: "screenshot.png",
type: "png",
fullPage: false,
});
// close the Stagehand instance and release the browser resources
await stagehand.close();
}
main().catch(console.error);
使用以下命令运行脚本:
npm run start
在终端中,你应该会看到类似以下的日志:

重要:日志可能会提到“connecting to local browser”。这是由于所需的 env: "LOCAL" 配置导致的。不过,实际连接是连接到 Bright Data 的远程 Browser API。
执行完成后,screenshot.png 文件将出现在你的项目目录中:
bright-data-stagehand-example/
├── .cursorrules
├── .env
├── .env.example
├── claude.md
├── index.ts
├── package.json
├── README.md
├── screenshot.png # <---------
└── tsconfig.json
打开 screenshot.png,你应该会看到渲染后的 example.com 页面:

这确认 Stagehand 已成功连接到目标站点,并按预期执行了浏览器自动化。
要验证是否使用了 Bright Data Browser API,请检查你的 Bright Data 控制面板:

你应该会看到一个流量峰值,表明已通过远程 CDP 连接从配置的 Browser API 会话中活跃使用。这确认所有 Stagehand 自动化都正确地通过 Bright Data 的 Browser API 路由。太棒了!
第 #6 步:实现真实世界的 AI 驱动远程浏览器自动化
现在,假设你想自动化浏览器逻辑,以从 Yahoo Finance 收集新闻文章数据。

这是一个很好的示例,因为 Yahoo Finance 主页使用无限滚动来动态加载新文章。它也是一个以严格的反机器人和反抓取保护而闻名的网站。
借助 Browser API 提供的隐身和反机器人绕过能力,你可以通过 Stagehand 访问 Yahoo Finance 而不被阻止。
由于你希望抓取的数据遵循特定结构,请先使用 Zod 定义输出数据类型:
import { z } from "zod";
// ...
// structured output schema
const YahooFinanceNewsSchema = z.object({
news: z.array(
z.object({
title: z
.string()
.describe("The visible headline text of the news article"),
articleUrl: z
.string()
.describe("The full article URL"),
imageUrl: z
.string()
.describe("The full image URL"),
source: z
.string()
.optional()
.describe("The publisher name, such as Reuters or Yahoo Finance"),
timestamp: z
.string()
.optional()
.describe("The visible publication time, such as '4h ago'"),
marketMoves: z
.array(
z.object({
ticker: z
.string()
.describe("The stock ticker symbol, such as NVDA or ^GSPC"),
changePercent: z
.string()
.optional()
.describe(
"The visible market percentage change, such as '+2.4%' or '-0.69%'"
),
})
)
.optional()
.describe(
"List of stock tickers mentioned in the article footer with their change percentages"
),
})
),
});
这定义了爬虫数据的预期输出结构。特别是,它与 Yahoo Finance 新闻卡片中可用的信息相匹配:

如果你通过 npx create-browser-app 初始化 Stagehand 应用,则无需手动安装 zod。它已包含在项目依赖项中。否则,使用以下命令安装它:
npm install zod
现在,你可以使用以下内容自动化浏览和提取流程:
// automate the news article loading
await stagehand.act(
`Scroll down multiple times and wait for articles to load in the "More News" section. Repeat until at least 20 news articles are loaded.`,
{
timeout: 90000, // 90-second timeout
}
);
// scrape the news information
const data = await stagehand.extract(
`Scrape all visible news articles`,
YahooFinanceNewsSchema,
{
"timeout": 120000, // 120-second timeout
}
);
这会复制真实用户滚动页面以加载更多文章的行为,但由 AI 指令驱动。然后,它使用 AI 驱动的结构化提取将页面内容转换为定义的模式。
请注意,自动化脚本依赖两个 Stagehand AI 驱动的 API:
.act():在浏览器会话中执行操作(例如,滚动、点击、导航).extract():使用模式从页面中提取结构化数据
太棒了!下一步是导出抓取的数据。
第 #7 步:提取抓取的数据
此时,抓取的数据已经存储在 stagehand.extract() 返回的 data 对象中。最后一步是将其导出到 news.json 文件,以便稍后复用或处理。
使用 Node.js 原生 fs/promises API 实现这一点:
import fs from "fs/promises";
// ...
// save extracted news to a JSON file
await fs.writeFile(
"news.json",
JSON.stringify(data.news, null, 2),
"utf-8"
);
这会写入一个 news.json 文件,其中包含整洁、可读格式的结构化新闻数据。
任务完成!采用 Browser API 作为浏览器 AI 代理的 Stagehand 抓取工作流现已完全实现。
第 #8 步:整合在一起
你用于通过 Stagehand 自动化 Yahoo Finance 抓取的最终 index.ts 脚本将如下所示:
import { Stagehand } from "@browserbasehq/stagehand";
import dotenv from "dotenv";
import { z } from "zod";
import fs from "fs/promises";
// load the environment variables from the .env file
dotenv.config({
path: ".env",
});
// read the Bright Data Browser API credentials
const BRIGHT_DATA_BROWSER_API_USERNAME = process.env.BRIGHT_DATA_BROWSER_API_USERNAME || "";
const BRIGHT_DATA_BROWSER_API_PASSWORD = process.env.BRIGHT_DATA_BROWSER_API_PASSWORD || "";
// structured output schema
const YahooFinanceNewsSchema = z.object({
news: z.array(
z.object({
title: z
.string()
.describe("The visible headline text of the news article"),
articleUrl: z
.string()
.describe(
"The full article URL."
),
imageUrl: z
.string()
.describe(
"The full image URL."
),
source: z
.string()
.optional()
.describe("The publisher name, such as Reuters or Yahoo Finance"),
timestamp: z
.string()
.optional()
.describe("The visible publication time, such as '4h ago'"),
marketMoves: z
.array(
z.object({
ticker: z
.string()
.describe("The stock ticker symbol, such as NVDA or ^GSPC"),
changePercent: z
.string()
.optional()
.describe(
"The visible market percentage change, such as '+2.4%' or '-0.69%'"
),
})
)
.optional()
.describe(
"List of stock tickers mentioned in the article footer with their market change percentages"
),
})
),
});
async function main() {
// configure Stagehand to connect remotely to Bright Data's Browser API
// and use an OpenAI model
const stagehand = new Stagehand({
env: "LOCAL",
localBrowserLaunchOptions: {
cdpUrl: `wss://${BRIGHT_DATA_BROWSER_API_USERNAME}:${BRIGHT_DATA_BROWSER_API_PASSWORD}@brd.superproxy.io:9222`,
},
model: "openai/gpt-5.4-mini",
keepAlive: true,
verbose: 1,
});
// launch Stagehand and get the browser page
await stagehand.init();
const page = stagehand.context.pages()[0];
// go to Yahoo Finance
await page.goto("https://finance.yahoo.com/");
// automate the news article loading
await stagehand.act(
`Scroll down multiple times and wait for articles to load in the "More News" section. Repeat until at least 20 news articles are loaded.`,
{
timeout: 90000, // 90-second timeout
}
);
// scrape the news information
const data = await stagehand.extract(
`Scrape all visible news articles`,
YahooFinanceNewsSchema,
{
"timeout": 120000, // 120-second timeout
}
);
// save extracted news to a JSON file
await fs.writeFile(
"news.json",
JSON.stringify(data.news, null, 2),
"utf-8"
);
console.log("News exported to news.json");
// close the Stagehand instance and release the browser resources
await stagehand.close();
}
main().catch(console.error);
然后,.env 文件将存储:
OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"
BRIGHT_DATA_BROWSER_API_USERNAME="<BROWSER_API_USERNAME>"
BRIGHT_DATA_BROWSER_API_PASSWORD="<BROWSER_API_PASSWORD>"
使用以下命令启动脚本:
npm run start
脚本运行完成后,news.json 文件将出现在你的项目文件夹中。如果你打开它,应该会看到如下结构化数据:

请注意,该文件包含了多次滚动后出现在 Yahoo Finance 主页上的相同文章,但现在采用整洁的结构化格式。
这证明了 Browser API 如何访问动态内容并大规模提取数据,即使是来自具有反机器人保护的网站。
Et voilà!这只是一个示例,但你可以使用 Stagehand 在许多其他场景和用例中自动化 Bright Data Browser API 工作流。
结论
在本文中,你了解了 Stagehand 是什么,以及它如何支持浏览器自动化。具体而言,你看到了如何将它与 Bright Data 的 Browser API 一起使用,以运行高度可扩展、未被检测到的云端浏览器会话。
其结果是一个可扩展到企业级工作负载的浏览器自动化设置。通过相同的集成,你还可以实现由大规模云基础设施支持的代理式浏览器 AI 操作。
创建一个新的 Bright Data 账户,探索我们的面向 AI 的网页数据抓取和浏览器自动化解决方案!