《Puppeteer入门使用代码大全》
在自动化测试与网页数据抓取领域,Puppeteer作为一款由Google开发的Node.js库,凭借其强大的浏览器自动化能力,已成为开发者不可或缺的工具。它通过控制Chrome或Chromium浏览器,模拟用户操作、抓取动态内容、生成PDF或截图,甚至实现端到端测试。本文将从基础环境搭建到高级功能应用,系统性地介绍Puppeteer的核心用法,并提供完整的代码示例。
一、Puppeteer简介与环境准备
Puppeteer是一个高级API,通过DevTools协议控制Chromium浏览器。相比传统的Selenium,它无需额外驱动,直接集成Chromium实例,支持无头模式(Headless)和有头模式(Headful)运行。其核心优势包括:
- 支持现代JavaScript框架(React、Vue等)的动态渲染页面抓取
- 提供精准的元素定位与操作接口
- 内置截图、PDF生成、网络请求拦截等功能
- 与Node.js生态无缝集成
1.1 安装Puppeteer
通过npm安装最新版本(需Node.js 12+):
npm install puppeteer
# 或安装精简版(不包含Chromium)
npm install puppeteer-core
1.2 基础模板代码
以下是一个最简单的Puppeteer脚本,启动浏览器并访问页面:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await browser.close();
})();
二、核心功能详解
2.1 页面导航与操作
2.1.1 基本导航
await page.goto('https://example.com', {
waitUntil: 'networkidle2', // 等待网络空闲
timeout: 10000 // 超时设置
});
2.1.2 页面交互
// 点击元素
await page.click('#submit-button');
// 输入文本
await page.type('#username', 'puppeteer');
// 选择下拉框
await page.select('#country', 'US');
// 上传文件
const input = await page.$('input[type=file]');
await input.uploadFile('/path/to/file.jpg');
2.2 元素选择策略
Puppeteer提供多种元素定位方式:
// CSS选择器
await page.$('.class-name');
// XPath
await page.$x('//button[@id="submit"]');
// 文本选择
await page.$eval('*', el => el.innerText.includes('Login'));
// 链式调用示例
const links = await page.$$eval('a', elements =>
elements.map(el => el.href)
);
2.3 动态内容处理
2.3.1 等待特定条件
// 等待元素出现
await page.waitForSelector('#dynamic-content');
// 等待网络请求完成
await page.waitForResponse('https://api.example.com/data');
// 自定义等待函数
await page.waitForFunction(() => {
return document.querySelector('.loaded').innerText === 'Complete';
}, { timeout: 5000 });
2.3.2 处理AJAX请求
// 拦截请求
await page.setRequestInterception(true);
page.on('request', request => {
if (request.url().includes('ads')) {
request.abort();
} else {
request.continue();
}
});
// 修改请求头
await page.setExtraHTTPHeaders({
'User-Agent': 'PuppeteerBot/1.0'
});
三、高级功能实现
3.1 截图与PDF生成
// 全页截图
await page.screenshot({
path: 'fullpage.png',
fullPage: true
});
// 区域截图
const element = await page.$('#header');
await element.screenshot({ path: 'header.png' });
// 生成PDF
await page.pdf({
path: 'report.pdf',
format: 'A4',
margin: { top: '20mm', right: '20mm' }
});
3.2 设备模拟与移动端测试
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone X'];
await page.emulate(iPhone);
await page.goto('https://m.example.com');
3.3 自动化表单填充
async function fillForm(page, data) {
await page.type('#name', data.name);
await page.type('#email', data.email);
await page.select('#country', data.country);
await page.click('#submit');
}
// 调用示例
await fillForm(page, {
name: 'John Doe',
email: 'john@example.com',
country: 'US'
});
四、实际项目案例
4.1 电商价格监控系统
const scrapeProduct = async (url) => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'domcontentloaded' });
const price = await page.$eval('.price', el =>
parseFloat(el.innerText.replace('$', ''))
);
const stock = await page.$eval('.stock', el =>
el.innerText.includes('In Stock')
);
await browser.close();
return { price, stock };
};
// 使用示例
scrapeProduct('https://store.example.com/product/123')
.then(console.log);
4.2 自动化测试框架集成
const { expect } = require('chai');
describe('Login Page Tests', () => {
let browser, page;
before(async () => {
browser = await puppeteer.launch();
page = await browser.newPage();
});
after(async () => {
await browser.close();
});
it('should display error for invalid credentials', async () => {
await page.goto('https://example.com/login');
await page.type('#email', 'wrong@example.com');
await page.type('#password', '123456');
await page.click('#submit');
const error = await page.$eval('.error-message', el => el.innerText);
expect(error).to.include('Invalid credentials');
});
});
五、性能优化与最佳实践
5.1 资源控制
// 限制资源加载
await page.setRequestInterception(true);
page.on('request', request => {
const type = request.resourceType();
if (['image', 'stylesheet', 'font'].includes(type)) {
request.abort();
} else {
request.continue();
}
});
5.2 并行处理
const { promisify } = require('util');
const delay = promisify(setTimeout);
async function processPage(url) {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url);
// 处理逻辑...
await browser.close();
}
// 并行执行
(async () => {
const urls = ['url1', 'url2', 'url3'];
await Promise.all(urls.map(url => processPage(url)));
})();
5.3 错误处理与重试机制
async function safeScrape(url, maxRetries = 3) {
let retries = 0;
while (retries
六、常见问题解决方案
6.1 页面加载超时处理
await page.goto(url, {
waitUntil: 'networkidle0',
timeout: 30000
}).catch(e => {
console.error('Navigation timeout:', e);
});
6.2 元素定位失败排查
// 调试时显示操作步骤
page.on('console', msg => console.log('PAGE LOG:', msg.text()));
// 获取页面HTML用于分析
const html = await page.content();
console.log(html);
6.3 浏览器实例管理
// 持久化浏览器连接(适用于长期运行的服务)
let browser;
async function getBrowser() {
if (!browser) {
browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
}
return browser;
}
// 使用后记得关闭
// await browser.close();
关键词:Puppeteer、Node.js、浏览器自动化、网页抓取、无头浏览器、动态内容处理、截图生成、PDF生成、设备模拟、自动化测试
简介:本文系统介绍Puppeteer的基础使用到高级应用,涵盖环境搭建、页面导航、元素操作、动态内容处理、截图与PDF生成、设备模拟等核心功能,通过实际案例展示电商价格监控和自动化测试实现,并提供性能优化方案和常见问题解决方案。