
关于
浏览器自动化,支持 Web 测试、数据抓取和 AI 代理驱动的网页交互
name: browser-automation description: 浏览器自动化驱动Web测试、数据抓取和AI代理交互。一个不稳定的脚本和一个可靠系统之间的区别在于对选择器、等待策略和反检测模式的理解。 risk: unknown source: vibeship-spawner-skills (Apache 2.0) date_added: 2026-02-27
浏览器自动化
浏览器自动化驱动Web测试、数据抓取和AI代理交互。一个不稳定的脚本和一个可靠系统之间的区别在于对选择器、等待策略和反检测模式的理解。
本技能涵盖Playwright(推荐)和Puppeteer,包含测试、抓取和代理式浏览器控制的模式。关键洞察:Playwright赢得了框架之战。除非你需要Puppeteer的隐身生态系统或仅限Chrome,否则Playwright在2025年是更好的选择。
关键区分:测试自动化(你控制的可预测应用)vs 抓取/代理自动化(会反抗的不可预测网站)。不同的问题,不同的解决方案。
原则
- 使用面向用户的定位器(getByRole、getByText)而非CSS/XPath
- 永远不要添加手动等待 - Playwright的自动等待会处理
- 每个测试/任务应完全隔离,使用全新上下文
- 截图和追踪是你的调试生命线
- CI中使用无头模式,调试时使用有头模式
- 反检测是猫鼠游戏 - 保持更新否则会被封锁
能力范围
- browser-automation
- playwright
- puppeteer
- headless-browsers
- web-scraping
- browser-testing
- e2e-testing
- ui-automation
- selenium-alternatives
边界
- api-testing → backend
- load-testing → performance-thinker
- accessibility-testing → accessibility-specialist
- visual-regression-testing → ui-design
工具
框架
- Playwright - 适用场景:默认选择 - 跨浏览器、自动等待、最佳开发体验 备注:96%成功率,平均4.5秒执行,Microsoft支持
- Puppeteer - 适用场景:仅Chrome、需要隐身插件、现有代码库 备注:大规模75%成功率,但最佳隐身生态系统
- Selenium - 适用场景:遗留系统、特定语言绑定 备注:更慢、更冗长,但最广泛的浏览器支持
隐身工具
- puppeteer-extra-plugin-stealth - 适用场景:需要使用Puppeteer绕过机器人检测 备注:反检测的黄金标准
- playwright-extra - 适用场景:Playwright的隐身插件 备注:puppeteer-extra生态系统的移植
- undetected-chromedriver - 适用场景:Selenium反检测 备注:动态绕过检测
云浏览器
- Browserbase - 适用场景:托管无头基础设施 备注:内置隐身模式、会话管理
- BrowserStack - 适用场景:大规模跨浏览器测试 备注:真实设备、CI集成
模式
测试隔离模式
每个测试在完全隔离的环境中运行,使用全新状态
适用场景:测试、任何需要可重现性的自动化
测试隔离:
每个测试获得独立的:
- 浏览器上下文(cookies、存储)
- 全新页面
- 干净状态
Playwright测试示例
import { test, expect } from '@playwright/test';
// Each test runs in isolated browser context
test('user can add item to cart', async ({ page }) => {
// Fresh context - no cookies, no storage from other tests
await page.goto('/products');
await page.getByRole('button', { name: 'Add to Cart' }).click();
await expect(page.getByTestId('cart-count')).toHaveText('1');
});
test('user can remove item from cart', async ({ page }) => {
// Completely isolated - cart is empty
await page.goto('/cart');
await expect(page.getByText('Your cart is empty')).toBeVisible();
});
共享认证模式
// Save auth state once, reuse across tests
// setup.ts
import { test as setup } from '@playwright/test';
setup('authenticate', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('user@example.com');
await page.getByLabel('Password').fill('password');
await page.getByRole('button', { name: 'Sign in' }).click();
// Wait for auth to complete
await page.waitForURL('/dashboard');
// Save authentication state
await page.context().storageState({
path: './playwright/.auth/user.json'
});
});
// playwright.config.ts
export default defineConfig({
projects: [
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
{
name: 'tests',
dependencies: ['setup'],
use: {
storageState: './playwright/.auth/user.json',
},
},
],
});
面向用户的定位器模式
以用户看到的方式选择元素
适用场景:始终使用 - 选择器的默认方法
面向用户的定位器:
优先级顺序:
1. getByRole - 最佳:匹配无障碍树
2. getByText - 良好:匹配可见内容
3. getByLabel - 良好:匹配表单标签
4. getByTestId - 备选:显式测试契约
5. CSS/XPath - 最后手段:脆弱,避免使用
良好示例(面向用户)
// By role - THE BEST CHOICE
await page.getByRole('button', { name: 'Submit' });
await page.getByRole('link', { name: 'Home' });
await page.getByRole('heading', { name: 'Welcome' });
兼容工具
Claude CodeCursor
标签
前端开发