stagehand-automation
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseStagehand Automation
Stagehand自动化
Overview
概述
Stagehand v3 is the state-of-the-art AI browser automation framework that bridges brittle traditional automation with intelligent, self-healing capabilities. Built on Chrome DevTools Protocol (CDP), it's 44% faster than v2 and integrates seamlessly with Claude.
Key Innovation: When DOM changes, AI adapts instead of tests breaking.
Core APIs:
- - Perform actions using natural language
act() - - Extract structured data from pages
extract() - - Identify elements and page state
observe()
Stagehand v3是一款顶尖的AI浏览器自动化框架,它将脆弱的传统自动化与智能自修复能力相结合。基于Chrome DevTools Protocol (CDP)构建,相比v2版本速度提升44%,并可与Claude无缝集成。
核心创新:当DOM发生变化时,AI会自动适配,而非导致测试失败。
核心API:
- - 使用自然语言执行操作
act() - - 从页面提取结构化数据
extract() - - 识别元素与页面状态
observe()
Quick Start (10 Minutes)
快速上手(10分钟)
1. Install Stagehand
1. 安装Stagehand
bash
npm install @browserbase/stagehand zodbash
npm install @browserbase/stagehand zod2. Configure Claude API
2. 配置Claude API
bash
undefinedbash
undefinedAdd to .env
添加到.env文件
ANTHROPIC_API_KEY=your_api_key_here
undefinedANTHROPIC_API_KEY=your_api_key_here
undefined3. Write First Automation
3. 编写首个自动化脚本
typescript
import { Stagehand } from "@browserbase/stagehand";
import { z } from "zod";
async function main() {
const stagehand = new Stagehand({
env: "LOCAL",
modelName: "claude-sonnet-4-20250514",
modelClientOptions: {
apiKey: process.env.ANTHROPIC_API_KEY,
},
});
await stagehand.init();
await stagehand.page.goto("https://news.ycombinator.com");
// AI-powered action - survives UI changes!
await stagehand.act({ action: "click on the first story link" });
// Extract structured data
const data = await stagehand.extract({
instruction: "extract the story title and author",
schema: z.object({
title: z.string(),
author: z.string(),
}),
});
console.log(data);
await stagehand.close();
}
main();typescript
import { Stagehand } from "@browserbase/stagehand";
import { z } from "zod";
async function main() {
const stagehand = new Stagehand({
env: "LOCAL",
modelName: "claude-sonnet-4-20250514",
modelClientOptions: {
apiKey: process.env.ANTHROPIC_API_KEY,
},
});
await stagehand.init();
await stagehand.page.goto("https://news.ycombinator.com");
// AI驱动操作 - 无惧UI变更!
await stagehand.act({ action: "click on the first story link" });
// 提取结构化数据
const data = await stagehand.extract({
instruction: "extract the story title and author",
schema: z.object({
title: z.string(),
author: z.string(),
}),
});
console.log(data);
await stagehand.close();
}
main();4. Run
4. 运行脚本
bash
npx ts-node your-script.tsbash
npx ts-node your-script.tsCore APIs
核心API
act() - Perform Actions
act() - 执行操作
Execute actions using natural language:
typescript
// Click elements
await stagehand.act({ action: "click the login button" });
// Fill forms
await stagehand.act({ action: "fill in the email field with 'test@example.com'" });
await stagehand.act({ action: "enter password 'securepass123'" });
// Navigate
await stagehand.act({ action: "scroll down to the pricing section" });
await stagehand.act({ action: "click the 'Sign Up' button in the header" });
// Complex actions
await stagehand.act({
action: "select 'Premium' from the plan dropdown and click Continue"
});Self-Healing: If the button ID changes from to , Stagehand adapts automatically.
#login-btn#auth-signin使用自然语言执行各类操作:
typescript
// 点击元素
await stagehand.act({ action: "click the login button" });
// 填写表单
await stagehand.act({ action: "fill in the email field with 'test@example.com'" });
await stagehand.act({ action: "enter password 'securepass123'" });
// 页面导航
await stagehand.act({ action: "scroll down to the pricing section" });
await stagehand.act({ action: "click the 'Sign Up' button in the header" });
// 复杂操作
await stagehand.act({
action: "select 'Premium' from the plan dropdown and click Continue"
});自修复特性:如果按钮ID从变更为,Stagehand会自动适配。
#login-btn#auth-signinextract() - Get Structured Data
extract() - 获取结构化数据
Extract data with schema validation:
typescript
import { z } from "zod";
// Simple extraction
const title = await stagehand.extract({
instruction: "get the main page title",
schema: z.object({
title: z.string(),
}),
});
// Complex extraction
const products = await stagehand.extract({
instruction: "extract all products with name, price, and availability",
schema: z.object({
products: z.array(z.object({
name: z.string(),
price: z.number(),
inStock: z.boolean(),
})),
}),
});
// Extract from specific area
const cartItems = await stagehand.extract({
instruction: "get items in the shopping cart",
schema: z.object({
items: z.array(z.object({
name: z.string(),
quantity: z.number(),
price: z.number(),
})),
total: z.number(),
}),
});通过Schema验证提取数据:
typescript
import { z } from "zod";
// 简单提取
const title = await stagehand.extract({
instruction: "get the main page title",
schema: z.object({
title: z.string(),
}),
});
// 复杂提取
const products = await stagehand.extract({
instruction: "extract all products with name, price, and availability",
schema: z.object({
products: z.array(z.object({
name: z.string(),
price: z.number(),
inStock: z.boolean(),
})),
}),
});
// 从指定区域提取
const cartItems = await stagehand.extract({
instruction: "get items in the shopping cart",
schema: z.object({
items: z.array(z.object({
name: z.string(),
quantity: z.number(),
price: z.number(),
})),
total: z.number(),
}),
});observe() - Analyze Page State
observe() - 分析页面状态
Understand page elements and state:
typescript
// Find elements
const elements = await stagehand.observe({
instruction: "find all clickable buttons on this page"
});
// Check state
const loginState = await stagehand.observe({
instruction: "is the user logged in? Look for profile icons or logout buttons"
});
// Identify form fields
const formFields = await stagehand.observe({
instruction: "identify all form input fields and their labels"
});识别页面元素与状态:
typescript
// 查找元素
const elements = await stagehand.observe({
instruction: "find all clickable buttons on this page"
});
// 检查状态
const loginState = await stagehand.observe({
instruction: "is the user logged in? Look for profile icons or logout buttons"
});
// 识别表单字段
const formFields = await stagehand.observe({
instruction: "identify all form input fields and their labels"
});Self-Healing Patterns
自修复模式
Traditional vs Stagehand
传统方案 vs Stagehand
typescript
// TRADITIONAL (Playwright) - Breaks when DOM changes
await page.click('#submit-btn-v2'); // Fails if ID changes
await page.click('.btn-primary:nth-child(2)'); // Fails if order changes
// STAGEHAND - Self-healing
await stagehand.act({ action: "click the submit button" }); // Always works
await stagehand.act({ action: "click the primary action button" }); // Adaptstypescript
// 传统方案(Playwright)- DOM变更时失效
await page.click('#submit-btn-v2'); // ID变更时失败
await page.click('.btn-primary:nth-child(2)'); // 顺序变更时失败
// STAGEHAND - 自修复
await stagehand.act({ action: "click the submit button" }); // 始终可用
await stagehand.act({ action: "click the primary action button" }); // 自动适配When Self-Healing Activates
自修复触发场景
- ID/Class Changes: Button ID changes from to
#old-id#new-id - Structure Changes: Element moves in DOM tree
- Text Changes: Button text changes from "Submit" to "Send"
- Style Changes: CSS classes reorganized
- ID/类名变更:按钮ID从变为
#old-id#new-id - 结构变更:元素在DOM树中的位置移动
- 文本变更:按钮文本从“Submit”变为“Send”
- 样式变更:CSS类重新组织
Caching (Performance Optimization)
缓存(性能优化)
Stagehand v3 caches discovered elements:
typescript
// First call: AI analyzes page, finds element (slow)
await stagehand.act({ action: "click login" });
// Second call: Uses cached selector (fast)
await stagehand.act({ action: "click login" });
// Cache invalidated when page changes significantlyStagehand v3会缓存已发现的元素:
typescript
// 首次调用:AI分析页面,查找元素(速度较慢)
await stagehand.act({ action: "click login" });
// 二次调用:使用缓存的选择器(速度快)
await stagehand.act({ action: "click login" });
// 当页面发生显著变更时,缓存会失效Hybrid Approach: Playwright + Stagehand
混合方案:Playwright + Stagehand
Combine traditional speed with AI resilience:
typescript
import { Stagehand } from "@browserbase/stagehand";
import { test, expect } from "@playwright/test";
test('hybrid test', async () => {
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();
// Use Playwright for stable, fast operations
await stagehand.page.goto('https://app.example.com');
await stagehand.page.fill('[data-testid="email"]', 'test@example.com');
// Use Stagehand for dynamic/fragile elements
await stagehand.act({ action: "click the login button" });
// Use Playwright for assertions
await expect(stagehand.page).toHaveURL(/dashboard/);
// Use Stagehand for complex extraction
const dashboardData = await stagehand.extract({
instruction: "get user stats from dashboard",
schema: z.object({
totalOrders: z.number(),
accountBalance: z.number(),
}),
});
expect(dashboardData.totalOrders).toBeGreaterThan(0);
});结合传统方案的速度与AI的韧性:
typescript
import { Stagehand } from "@browserbase/stagehand";
import { test, expect } from "@playwright/test";
test('hybrid test', async () => {
const stagehand = new Stagehand({ env: "LOCAL" });
await stagehand.init();
// 使用Playwright执行稳定、快速的操作
await stagehand.page.goto('https://app.example.com');
await stagehand.page.fill('[data-testid="email"]', 'test@example.com');
// 使用Stagehand处理动态/脆弱元素
await stagehand.act({ action: "click the login button" });
// 使用Playwright执行断言
await expect(stagehand.page).toHaveURL(/dashboard/);
// 使用Stagehand执行复杂提取
const dashboardData = await stagehand.extract({
instruction: "get user stats from dashboard",
schema: z.object({
totalOrders: z.number(),
accountBalance: z.number(),
}),
});
expect(dashboardData.totalOrders).toBeGreaterThan(0);
});Claude Integration
Claude集成
Model Selection
模型选择
typescript
// Claude Sonnet 4 (recommended - balance of speed/quality)
const stagehand = new Stagehand({
modelName: "claude-sonnet-4-20250514",
modelClientOptions: {
apiKey: process.env.ANTHROPIC_API_KEY,
},
});
// Claude Opus (highest quality, slower)
const stagehand = new Stagehand({
modelName: "claude-opus-4-20250514",
});
// Claude Haiku (fastest, simpler tasks)
const stagehand = new Stagehand({
modelName: "claude-3-5-haiku-20241022",
});typescript
// Claude Sonnet 4(推荐 - 平衡速度与性能)
const stagehand = new Stagehand({
modelName: "claude-sonnet-4-20250514",
modelClientOptions: {
apiKey: process.env.ANTHROPIC_API_KEY,
},
});
// Claude Opus(最高性能,速度较慢)
const stagehand = new Stagehand({
modelName: "claude-opus-4-20250514",
});
// Claude Haiku(最快,适用于简单任务)
const stagehand = new Stagehand({
modelName: "claude-3-5-haiku-20241022",
});Cost Optimization
成本优化
typescript
// Use Haiku for simple actions (cheaper)
const simpleStagehand = new Stagehand({
modelName: "claude-3-5-haiku-20241022",
});
await simpleStagehand.act({ action: "click login" });
// Use Sonnet for complex extraction
const complexStagehand = new Stagehand({
modelName: "claude-sonnet-4-20250514",
});
const data = await complexStagehand.extract({
instruction: "extract all product details with nested specifications",
schema: complexSchema,
});typescript
// 使用Haiku执行简单操作(成本更低)
const simpleStagehand = new Stagehand({
modelName: "claude-3-5-haiku-20241022",
});
await simpleStagehand.act({ action: "click login" });
// 使用Sonnet执行复杂提取
const complexStagehand = new Stagehand({
modelName: "claude-sonnet-4-20250514",
});
const data = await complexStagehand.extract({
instruction: "extract all product details with nested specifications",
schema: complexSchema,
});Estimated Costs
预估成本
| Operation | Model | Est. Cost |
|---|---|---|
| Simple act() | Haiku | ~$0.001 |
| Complex act() | Sonnet | ~$0.005 |
| Simple extract() | Haiku | ~$0.002 |
| Complex extract() | Sonnet | ~$0.01 |
| 操作类型 | 模型 | 预估成本 |
|---|---|---|
| 简单act() | Haiku | ~$0.001 |
| 复杂act() | Sonnet | ~$0.005 |
| 简单extract() | Haiku | ~$0.002 |
| 复杂extract() | Sonnet | ~$0.01 |
MCP Integration
MCP集成
Use Stagehand with Claude Desktop via Model Context Protocol:
typescript
// Stagehand MCP server enables Claude to control browsers
// from Claude Desktop or any MCP-compatible client
import { StagehandMCPServer } from "@browserbase/stagehand/mcp";
const server = new StagehandMCPServer();
server.start();
// Now Claude can call:
// - stagehand.act({ action: "..." })
// - stagehand.extract({ instruction: "..." })
// - stagehand.observe({ instruction: "..." })通过Model Context Protocol将Stagehand与Claude Desktop结合使用:
typescript
// Stagehand MCP服务器允许Claude控制浏览器
// 支持Claude Desktop或任何兼容MCP的客户端
import { StagehandMCPServer } from "@browserbase/stagehand/mcp";
const server = new StagehandMCPServer();
server.start();
// 现在Claude可以调用:
// - stagehand.act({ action: "..." })
// - stagehand.extract({ instruction: "..." })
// - stagehand.observe({ instruction: "..." })Error Handling
错误处理
typescript
try {
await stagehand.act({
action: "click the non-existent button",
timeout: 10000, // 10 second timeout
});
} catch (error) {
if (error.message.includes('timeout')) {
console.log('Element not found within timeout');
} else if (error.message.includes('multiple')) {
console.log('Multiple matching elements found - be more specific');
} else {
throw error;
}
}
// Retry pattern
async function actWithRetry(stagehand, action, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await stagehand.act({ action });
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(r => setTimeout(r, 1000));
}
}
}typescript
try {
await stagehand.act({
action: "click the non-existent button",
timeout: 10000, // 10秒超时
});
} catch (error) {
if (error.message.includes('timeout')) {
console.log('超时未找到元素');
} else if (error.message.includes('multiple')) {
console.log('找到多个匹配元素 - 请更明确');
} else {
throw error;
}
}
// 重试模式
async function actWithRetry(stagehand, action, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await stagehand.act({ action });
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(r => setTimeout(r, 1000));
}
}
}Best Practices
最佳实践
1. Be Specific in Instructions
1. 指令需明确
typescript
// BAD - ambiguous
await stagehand.act({ action: "click button" });
// GOOD - specific
await stagehand.act({ action: "click the blue 'Add to Cart' button below the product image" });typescript
// 差 - 模糊
await stagehand.act({ action: "click button" });
// 好 - 明确
await stagehand.act({ action: "click the blue 'Add to Cart' button below the product image" });2. Use Context
2. 提供上下文
typescript
// Provide context for better accuracy
await stagehand.act({
action: "in the navigation menu, click on 'Settings'"
});
await stagehand.act({
action: "in the user dropdown in the top right, click 'Logout'"
});typescript
// 提供上下文以提升准确性
await stagehand.act({
action: "in the navigation menu, click on 'Settings'"
});
await stagehand.act({
action: "in the user dropdown in the top right, click 'Logout'"
});3. Combine with Playwright for Speed
3. 结合Playwright提升速度
typescript
// Fast: Use Playwright for data-testid elements
await stagehand.page.click('[data-testid="submit"]');
// Resilient: Use Stagehand for dynamic elements
await stagehand.act({ action: "dismiss the cookie banner" });typescript
// 快速:使用Playwright处理带data-testid的元素
await stagehand.page.click('[data-testid="submit"]');
// 韧性:使用Stagehand处理动态元素
await stagehand.act({ action: "dismiss the cookie banner" });4. Schema Validation
4. Schema验证
typescript
// Always use Zod schemas for type safety
const schema = z.object({
title: z.string().min(1),
price: z.number().positive(),
inStock: z.boolean(),
});
const data = await stagehand.extract({
instruction: "get product details",
schema,
});
// data is fully typed!typescript
// 始终使用Zod Schema确保类型安全
const schema = z.object({
title: z.string().min(1),
price: z.number().positive(),
inStock: z.boolean(),
});
const data = await stagehand.extract({
instruction: "get product details",
schema,
});
// data类型完全安全!Use Cases
适用场景
- Self-Healing E2E Tests: Tests that survive UI redesigns
- Web Scraping: Extract data from any website
- Form Automation: Fill complex forms automatically
- Testing AI Chatbots: Interact with conversational UIs
- Cross-Site Workflows: Automate multi-site processes
- 自修复端到端测试:可适应UI重设计的测试
- 网页抓取:从任意网站提取数据
- 表单自动化:自动填写复杂表单
- AI聊天机器人测试:与对话式UI交互
- 跨站点工作流:自动化多站点流程
References
参考资料
- - Complete API reference
references/stagehand-v3-guide.md - - API setup and model selection
references/claude-integration.md - - Advanced patterns
references/self-healing-patterns.md
Stagehand v3 brings AI-powered self-healing to browser automation - tests that adapt instead of break.
- - 完整API参考
references/stagehand-v3-guide.md - - API设置与模型选择
references/claude-integration.md - - 高级模式
references/self-healing-patterns.md
Stagehand v3为浏览器自动化带来AI驱动的自修复能力——测试将自动适配而非失效。