Skip to content
chrome-automation logo

Chrome 浏览器自动化

chrome-automation

Chrome 浏览器自动化操作。当用户需要自动化浏览器操作、网页测试、数据抓取或 UI 自动化时使用此技能。

SKILL.md

Full skill instructions

Chrome 浏览器自动化

功能说明

此技能专门用于 Chrome 浏览器自动化,包括:

  • 网页自动化操作
  • E2E 测试
  • 网页截图和 PDF 生成
  • 表单自动填充
  • 动态网页数据抓取
  • 性能测试和监控

使用场景

  • "自动化登录网站并抓取数据"
  • "批量截取网页截图"
  • "自动化测试购物流程"
  • "监控网站性能指标"
  • "自动填写表单并提交"
  • "生成网页 PDF 报告"

技术栈

自动化工具

  • Puppeteer:Chrome DevTools Protocol
  • Playwright:跨浏览器自动化
  • Selenium:经典自动化框架
  • Cypress:现代 E2E 测试框架

辅助工具

  • puppeteer-extra:Puppeteer 插件系统
  • puppeteer-stealth:反检测插件
  • chrome-launcher:Chrome 启动器

核心功能

1. 页面导航

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  headless: false,  // 显示浏览器
  slowMo: 50        // 减慢操作速度
});

const page = await browser.newPage();

// 导航到页面
await page.goto('https://example.com', {
  waitUntil: 'networkidle2'  // 等待网络空闲
});

// 前进后退
await page.goBack();
await page.goForward();
await page.reload();

await browser.close();

2. 元素操作

// 点击元素
await page.click('#submit-button');

// 输入文本
await page.type('#username', '[email protected]');
await page.type('#password', 'password123');

// 选择下拉框
await page.select('#country', 'CN');

// 上传文件
const fileInput = await page.$('input[type="file"]');
await fileInput.uploadFile('/​path/​to/​file.pdf');

// 等待元素
await page.waitForSelector('.result', { timeout: 5000 });

// 获取元素文本
const text = await page.$eval('.title', el => el.textContent);

// 获取多个元素
const items = await page.$$eval('.item', elements =>
  elements.map(el => el.textContent)
);

3. 表单自动化

async function fillForm(page: Page) {
  // 填写文本输入框
  await page.type('#name', '张三');
  await page.type('#email', '[email protected]');
  await page.type('#phone', '13800138000');

  // 选择单选按钮
  await page.click('input[name="gender"][value="male"]');

  // 选择复选框
  await page.click('#agree-terms');
  await page.click('#subscribe-newsletter');

  // 选择下拉框
  await page.select('#city', 'beijing');

  // 填写日期
  await page.type('#birthday', '1990-01-01');

  // 填写文本域
  await page.type('#message', '这是一条测试消息');

  // 提交表单
  await page.click('button[type="submit"]');

  // 等待提交完成
  await page.waitForNavigation();
}

4. 数据抓取

async function scrapeData(url: string) {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.goto(url);

  // 等待内容加载
  await page.waitForSelector('.product-list');

  // 抓取数据
  const products = await page.$$eval('.product-item', items =>
    items.map(item => ({
      title: item.querySelector('.title')?.textContent,
      price: item.querySelector('.price')?.textContent,
      image: item.querySelector('img')?.src,
      link: item.querySelector('a')?.href
    }))
  );

  await browser.close();
  return products;
}

5. 截图和 PDF

// 全页截图
await page.screenshot({
  path: 'screenshot.png',
  fullPage: true
});

// 元素截图
const element = await page.$('.chart');
await element.screenshot({ path: 'chart.png' });

// 生成 PDF
await page.pdf({
  path: 'page.pdf',
  format: 'A4',
  printBackground: true,
  margin: {
    top: '20px',
    right: '20px',
    bottom: '20px',
    left: '20px'
  }
});

6. 性能监控

async function measurePerformance(url: string) {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // 开始性能追踪
  await page.tracing.start({ path: 'trace.json' });

  await page.goto(url, { waitUntil: 'networkidle2' });

  // 停止追踪
  await page.tracing.stop();

  // 获取性能指标
  const metrics = await page.metrics();
  console.log('性能指标:', metrics);

  // 获取 Performance API 数据
  const performanceData = await page.evaluate(() => {
    const timing = performance.timing;
    return {
      loadTime: timing.loadEventEnd - timing.navigationStart,
      domReady: timing.domContentLoadedEventEnd - timing.navigationStart,
      firstPaint: performance.getEntriesByType('paint')[0]?.startTime
    };
  });

  await browser.close();
  return performanceData;
}

高级功能

1. 拦截和修改请求

await page.setRequestInterception(true);

page.on('request', request => {
  // 阻止图片加载
  if (request.resourceType() === 'image') {
    request.abort();
  }
  // 修改请求头
  else if (request.url().includes('api')) {
    request.continue({
      headers: {
        ...request.headers(),
        'Authorization': 'Bearer token'
      }
    });
  }
  else {
    request.continue();
  }
});

2. 模拟移动设备

const iPhone = puppeteer.devices['iPhone 12'];

await page.emulate(iPhone);
await page.goto('https://example.com');

3. 处理弹窗

// 处理 alert/​confirm/​prompt
page.on('dialog', async dialog => {
  console.log(dialog.message());
  await dialog.accept();  // 或 dialog.dismiss()
});

// 处理新窗口
const newPagePromise = new Promise(resolve =>
  browser.once('targetcreated', target => resolve(target.page()))
);

await page.click('a[target="_blank"]');
const newPage = await newPagePromise;

4. Cookie 管理

// 设置 Cookie
await page.setCookie({
  name: 'session',
  value: 'abc123',
  domain: 'example.com'
});

// 获取 Cookie
const cookies = await page.cookies();

// 删除 Cookie
await page.deleteCookie({ name: 'session' });

5. 执行 JavaScript

// 在页面上下文中执行代码
const result = await page.evaluate(() => {
  return document.title;
});

// 传递参数
const sum = await page.evaluate((a, b) => {
  return a + b;
}, 5, 3);

// 暴露函数给页面
await page.exposeFunction('md5', (text: string) => {
  return crypto.createHash('md5').update(text).digest('hex');
});

E2E 测试示例

Playwright 测试

import { test, expect } from '@playwright/​test';

test.describe('登录功能', () => {
  test('成功登录', async ({ page }) => {
    await page.goto('https://example.com/​login');

    await page.fill('#email', '[email protected]');
    await page.fill('#password', 'password123');
    await page.click('button[type="submit"]');

    await expect(page).toHaveURL('https://example.com/​dashboard');
    await expect(page.locator('h1')).toContainText('欢迎');
  });

  test('登录失败提示', async ({ page }) => {
    await page.goto('https://example.com/​login');

    await page.fill('#email', '[email protected]');
    await page.fill('#password', 'wrongpass');
    await page.click('button[type="submit"]');

    await expect(page.locator('.error')).toBeVisible();
    await expect(page.locator('.error')).toContainText('用户名或密码错误');
  });
});

Cypress 测试

describe('购物车功能', () => {
  beforeEach(() => {
    cy.visit('/​products');
  });

  it('添加商品到购物车', () => {
    cy.get('.product-item').first().within(() => {
      cy.get('.add-to-cart').click();
    });

    cy.get('.cart-badge').should('contain', '1');
  });

  it('从购物车删除商品', () => {
    cy.get('.cart-icon').click();
    cy.get('.cart-item').first().within(() => {
      cy.get('.remove-button').click();
    });

    cy.get('.cart-empty').should('be.visible');
  });
});

反检测技术

Puppeteer Stealth

import puppeteer from 'puppeteer-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';

puppeteer.use(StealthPlugin());

const browser = await puppeteer.launch({
  headless: true,
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-blink-features=AutomationControlled'
  ]
});

const page = await browser.newPage();

// 设置真实的 User-Agent
await page.setUserAgent(
  'Mozilla/​5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/​537.36'
);

// 设置视口大小
await page.setViewport({
  width: 1920,
  height: 1080
});

// 隐藏 webdriver 标识
await page.evaluateOnNewDocument(() => {
  Object.defineProperty(navigator, 'webdriver', {
    get: () => false
  });
});

最佳实践

1. 错误处理

async function robustScrape(url: string) {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  try {
    await page.goto(url, {
      waitUntil: 'networkidle2',
      timeout: 30000
    });

    const data = await page.evaluate(() => {
      // 数据提取逻辑
    });

    return data;
  } catch (error) {
    console.error('抓取失败:', error);
    // 截图保存错误现场
    await page.screenshot({ path: 'error.png' });
    throw error;
  } finally {
    await browser.close();
  }
}

2. 并发控制

import pLimit from 'p-limit';

async function scrapeMultiplePages(urls: string[]) {
  const browser = await puppeteer.launch();
  const limit = pLimit(5);  // 最多 5 个并发

  const results = await Promise.all(
    urls.map(url =>
      limit(async () => {
        const page = await browser.newPage();
        try {
          await page.goto(url);
          return await page.evaluate(() => {
            // 提取数据
          });
        } finally {
          await page.close();
        }
      })
    )
  );

  await browser.close();
  return results;
}

3. 资源优化

// 禁用不必要的资源
await page.setRequestInterception(true);
page.on('request', request => {
  const resourceType = request.resourceType();
  if (['image', 'stylesheet', 'font'].includes(resourceType)) {
    request.abort();
  } else {
    request.continue();
  }
});

// 设置超时
page.setDefaultTimeout(10000);
page.setDefaultNavigationTimeout(30000);

注意事项

  • 遵守网站的 robots.txt 和服务条款
  • 控制请求频率,避免对服务器造成压力
  • 使用代理池避免 IP 被封
  • 妥善处理验证码和登录
  • 定期更新浏览器版本
  • 注意内存泄漏,及时关闭页面和浏览器
  • 使用无头模式提高性能
  • 保存日志和错误截图便于调试

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View