Manikantasai Playwright Automation

Polar Sponsor
爱发电 赞助
.NET 9.0

使用Playwright API直接进行浏览器自动化。导航网站、与元素交互、提取数据、截图、生成PDF、录制视频,自动化复杂工作流程。比MCP方法更可靠。

Playwright浏览器自动化.

功能概述

Playwright浏览器自动化.是一项面向实际任务的技能,主要用于Direct Playwright API 用于可靠浏览器自动化而无需MCP复杂.;XQQ 快速启动.;

核心要点

  • Best Practices.;
  • Use Locators (Auto-waiting).;
  • Prefer User-Facting Attions.Han.。

使用与执行

它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;

结果检查与注意事项

若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。该技能适合用于一次性任务,也可以接入自动化工作流,与其他技能或上层代理配合完成更完整的业务链路;在组合使用时,应明确每一步的输入输出关系,并避免不同步骤之间出现参数冲突。

Playwright 浏览器自动化

直接使用 Playwright API 实现可靠浏览器自动化,无需 MCP 的复杂性。

安装

# 安装 Playwright
npm install -g playwright

# 安装浏览器(一次性操作,每个约 100MB)
npx playwright install chromium
# 可选:
npx playwright install firefox
npx playwright install webkit

# Ubuntu/Debian 系统依赖(需 root 权限):
sudo npx playwright install-deps chromium

快速开始

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: true });
  const page = await browser.newPage();
  
  await page.goto('https://example.com');
  await page.screenshot({ path: 'screenshot.png' });
  
  await browser.close();
})();

最佳实践

1. 使用 Locator(自动等待)

// ✅ 推荐:具备自动等待与重试机制
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByLabel('Username').fill('user');
await page.getByPlaceholder('Search').fill('query');

// ❌ 不推荐:元素未就绪时可能失败
await page.click('#submit');

2. 优先使用面向用户的属性

// ✅ 推荐:对 DOM 结构变更具备弹性
await page.getByRole('heading', { name: 'Welcome' });
await page.getByText('Sign in');
await page.getByTestId('login-button');

// ❌ 不推荐:脆弱的 CSS 选择器
await page.click('.btn-primary > div:nth-child(2)');

3. 处理动态内容

// 等待网络空闲
await page.goto('https://spa-app.com', { waitUntil: 'networkidle' });

// 等待特定元素出现
await page.waitForSelector('.results-loaded');
await page.waitForFunction(() => document.querySelectorAll('.item').length > 0);

4. 使用 Context 实现隔离

// 每个 Context = 独立会话(含独立 Cookie、Storage)
const context = await browser.newContext();
const page = await context.newPage();

// 同一 Context 中可创建多个页面
const page2 = await context.newPage();

5. 网络请求拦截

// 模拟 API 响应
await page.route('**/api/users', route => {
  route.fulfill({
    status: 200,
    body: JSON.stringify({ users: [] })
  });
});

// 屏蔽资源加载
await page.route('**/*.{png,jpg,css}', route => route.abort());

常见模式

表单自动化

// 填写表单
await page.goto('https://example.com/login');
await page.getByLabel('Username').fill('myuser');
await page.getByLabel('Password').fill('mypass');
await page.getByRole('button', { name: 'Sign in' }).click();

// 等待跳转或结果
await page.waitForURL('/dashboard');
await expect(page.getByText('Welcome')).toBeVisible();

数据提取

// 提取表格数据
const rows = await page.$$eval('table tr', rows =>
  rows.map(row => ({
    name: row.querySelector('td:nth-child(1)')?.textContent,
    price: row.querySelector('td:nth-child(2)')?.textContent
  }))
);

// 使用 JavaScript 执行提取
const data = await page.evaluate(() => {
  return Array.from(document.querySelectorAll('.product')).map(p => ({
    title: p.querySelector('.title')?.textContent,
    price: p.querySelector('.price')?.textContent
  }));
});

截图与 PDF 生成

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

// 元素截图
await page.locator('.chart').screenshot({ path: 'chart.png' });

// 生成 PDF(仅 Chromium 支持)
await page.pdf({ 
  path: 'page.pdf', 
  format: 'A4',
  printBackground: true 
});

视频录制

const context = await browser.newContext({
  recordVideo: {
    dir: './videos/',
    size: { width: 1920, height: 1080 }
  }
});
const page = await context.newPage();

// ... 执行操作 ...

await context.close(); // 视频将自动保存

移动设备模拟

const context = await browser.newContext({
  viewport: { width: 375, height: 667 },
  userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0)',
  isMobile: true,
  hasTouch: true
});

身份认证

// 方法 1:HTTP Basic Auth
const context = await browser.newContext({
  httpCredentials: { username: 'user', password: 'pass' }
});

// 方法 2:Cookie
await context.addCookies([
  { name: 'session', value: 'abc123', domain: '.example.com', path: '/' }
]);

// 方法 3:LocalStorage
await page.evaluate(() => {
  localStorage.setItem('token', 'xyz');
});

// 方法 4:复用认证状态
await context.storageState({ path: 'auth.json' });
// 后续使用:await browser.newContext({ storageState: 'auth.json' });

高级功能

文件上传/下载

// 文件上传
await page.setInputFiles('input[type="file"]', '/path/to/file.pdf');

// 文件下载
const [download] = await Promise.all([
  page.waitForEvent('download'),
  page.click('a[download]')
]);
await download.saveAs('/path/to/save/' + download.suggestedFilename());

对话框处理

page.on('dialog', dialog => {
  if (dialog.type() === 'alert') dialog.accept();
  if (dialog.type() === 'confirm') dialog.accept();
  if (dialog.type() === 'prompt') dialog.accept('My answer');
});

Frame 与 Shadow DOM

// 按名称获取 Frame
const frame = page.frame('frame-name');
await frame.click('button');

// 按定位器获取 Frame
const frame = page.frameLocator('iframe').first();
await frame.getByRole('button').click();

// Shadow DOM
await page.locator('my-component').locator('button').click();

追踪(调试)

await context.tracing.start({ screenshots: true, snapshots: true });

// ... 运行测试 ...

await context.tracing.stop({ path: 'trace.zip' });
// 在 https://trace.playwright.dev 查看追踪记录

配置选项

const browser = await chromium.launch({
  headless: true,        // 无界面运行
  slowMo: 50,           // 每步延时 50ms(用于调试)
  devtools: false,      // 是否打开 DevTools
  args: ['--no-sandbox', '--disable-setuid-sandbox'] // Docker/Ubuntu 场景常用
});

const context = await browser.newContext({
  viewport: { width: 1920, height: 1080 },
  locale: 'ru-RU',
  timezoneId: 'Europe/Moscow',
  geolocation: { latitude: 55.7558, longitude: 37.6173 },
  permissions: ['geolocation'],
  userAgent: 'Custom Agent',
  bypassCSP: true,      // 绕过内容安全策略(Content Security Policy)
});

错误处理

// 设置超时并重试
try {
  await page.getByRole('button', { name: 'Load' }).click({ timeout: 10000 });
} catch (e) {
  console.log('按钮未找到或不可点击');
}

// 检查元素是否存在
const hasButton = await page.getByRole('button').count() > 0;

// 自定义条件等待
await page.waitForFunction(() => 
  document.querySelectorAll('.loaded').length >= 10
);

Sudoers 配置

为 Playwright 浏览器安装配置 sudo 权限:

# /etc/sudoers.d/playwright
username ALL=(root) NOPASSWD: /usr/bin/npx playwright install-deps *
username ALL=(root) NOPASSWD: /usr/bin/npx playwright install *

参考资料

相关专题

更多
LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

2026.09.30

0

10

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

2026.09.30

0

14

LLVM IR中间表示入门指南
LLVM IR中间表示入门指南

本专题整理LLVM IR的核心概念,包括中间表示作用、模块结构、函数、基本块、SSA形式、类型系统和常见语法,帮助新手理解LLVM编译流程中的关键层。

2026.09.30

0

12

PDF转图片方法
PDF转图片方法

需要把 PDF 页面用于上传、预览、分享或图片归档时,PDF 转图片方法专题整理 JPG/PNG 格式选择、逐页导出、清晰度设置、批量下载和结果检查等流程,帮助用户稳定完成 PDF 图片化处理。

2026.09.30

0

26

PixTV AI视频生成与无限画布创作
PixTV AI视频生成与无限画布创作

PixTV专题整理AI视频与视觉内容创作相关功能使用教程,涵盖AI生图、视频生成、无限画布、多模型创作、素材管理、声音音乐及视频剪辑等功能,帮助用户快速掌握PixTV从创意到成片的完整制作方法。

2026.09.29

0

15

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

2026.09.23

0

15

Buffalo框架路由与请求处理实操指南
Buffalo框架路由与请求处理实操指南

本专题讲解Buffalo框架路由与请求处理机制,涵盖路由注册与分组、资源路由、Handler编写规范、Context上下文方法、参数绑定、中间件编写挂载、Session与Cookie读写、Flash消息及错误页面定制方法。

2026.09.23

0

15

Buffalo框架零基础入门教程
Buffalo框架零基础入门教程

本专题整理Buffalo框架入门内容,涵盖Go环境准备、buffalo CLI安装、新项目生成、目录结构说明、dev热加载启动、数据库连接配置与常见报错排查,帮助新手按约定优于配置的思路跑通第一个Buffalo框架应用。

2026.09.23

0

15

Conan创建软件包配方指南
Conan创建软件包配方指南

本专题介绍通过conanfile.py创建软件包的方法,讲解包名、版本、依赖和构建设置等基础信息,以及source、build、package、package_info等常用方法的作用及编写思路。

2026.09.22

0

12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习