您好,登录后才能下订单哦!
# Node.js中如何使用Puppeteer库
## 前言
Puppeteer是Google Chrome团队开发的Node.js库,它提供了一套高级API来控制无头(Headless)Chrome或Chromium浏览器。通过Puppeteer,开发者可以自动化完成网页操作、生成PDF/截图、爬取数据等任务。本文将详细介绍如何在Node.js环境中使用Puppeteer库。
## 目录
1. [Puppeteer简介](#puppeteer简介)
2. [环境准备](#环境准备)
3. [基本用法](#基本用法)
4. [常见操作](#常见操作)
5. [高级功能](#高级功能)
6. [性能优化](#性能优化)
7. [常见问题](#常见问题)
8. [实际应用案例](#实际应用案例)
9. [总结](#总结)
## Puppeteer简介
Puppeteer是一个Node库,它通过DevTools协议提供了对Chrome或Chromium的高级控制。主要特点包括:
- 生成页面PDF和截图
- 抓取单页应用(SPA)并生成预渲染内容
- 自动化表单提交、UI测试、键盘输入等
- 创建最新的自动化测试环境
- 捕获网站的时间线跟踪,帮助诊断性能问题
- 测试Chrome扩展程序
Puppeteer默认以无头模式运行浏览器,但可以配置为完整(non-headless)模式。
## 环境准备
### 安装Node.js
确保已安装Node.js(建议版本12+)。可以通过以下命令检查:
```bash
node -v
npm -v
在项目目录中运行:
npm install puppeteer
安装时会自动下载与API兼容的Chromium版本(约170MB Mac,~282MB Linux,~280MB Win)。
如果不想下载Chromium(比如要使用系统已安装的Chrome),可以安装puppeteer-core
:
npm install puppeteer-core
const puppeteer = require('puppeteer');
(async () => {
// 启动浏览器(无头模式)
const browser = await puppeteer.launch();
// 启动浏览器(非无头模式)
// const browser = await puppeteer.launch({ headless: false });
// 打开新页面
const page = await browser.newPage();
// 导航到URL
await page.goto('https://example.com');
// 截图
await page.screenshot({ path: 'example.png' });
// 关闭浏览器
await browser.close();
})();
const browser = await puppeteer.launch({
headless: false, // 是否无头模式
slowMo: 50, // 操作延迟(毫秒)
args: [
'--disable-gpu', // 禁用GPU加速
'--window-size=1280,800' // 窗口大小
]
});
await page.goto('https://example.com', {
waitUntil: 'networkidle2', // 等待网络空闲
timeout: 30000 // 超时时间
});
// 后退
await page.goBack();
// 前进
await page.goForward();
// 刷新
await page.reload();
// 点击元素
await page.click('#submit');
// 输入文本
await page.type('#username', 'admin');
// 获取元素文本
const text = await page.$eval('.title', el => el.textContent);
// 获取多个元素
const links = await page.$$eval('a', anchors =>
anchors.map(a => a.href)
);
// 选择单选按钮
await page.click('input[value="option1"]');
// 选择复选框
await page.click('input[type="checkbox"]');
// 选择下拉框
await page.select('select#colors', 'blue');
// 上传文件
const input = await page.$('input[type="file"]');
await input.uploadFile('/path/to/file');
// 等待选择器
await page.waitForSelector('.result');
// 等待XPath
await page.waitForXPath('//div[@class="result"]');
// 等待函数返回true
await page.waitForFunction(
'document.querySelector("body").innerText.includes("Done")'
);
// 等待超时
await page.waitForTimeout(1000); // 不推荐,优先用其他等待方式
// 监听对话框
page.on('dialog', async dialog => {
console.log(dialog.message());
await dialog.dismiss(); // 或 accept()
});
// 触发alert
await page.evaluate(() => alert('Hello!'));
await page.setRequestInterception(true);
page.on('request', request => {
// 阻止图片请求
if (request.resourceType() === 'image') {
request.abort();
} else {
request.continue();
}
});
// 在页面上下文中执行
const dimensions = await page.evaluate(() => {
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight
};
});
// 传递参数
const result = await page.evaluate(x => {
return Promise.resolve(10 * x);
}, 7);
await page.pdf({
path: 'page.pdf',
format: 'A4',
printBackground: true
});
// 获取所有页面
const pages = await browser.pages();
// 处理iframe
const frame = page.frames().find(f => f.name() === 'myframe');
await frame.click('#button');
await page.setRequestInterception(true);
page.on('request', req => {
const allowTypes = ['document', 'script', 'xhr', 'fetch'];
if (!allowTypes.includes(req.resourceType())) {
req.abort();
} else {
req.continue();
}
});
// 启动时
const browser = await puppeteer.launch({
userDataDir: './user_data' // 保存用户数据
});
// 后续可以复用同一个实例
const promises = urls.map(async url => {
const page = await browser.newPage();
await page.goto(url);
// 处理页面...
await page.close();
});
await Promise.all(promises);
const browser = await puppeteer.launch({
args: [
'--disable-extensions',
'--disable-notifications',
'--disable-accelerated-2d-canvas'
]
});
Q: 安装时下载Chromium失败?
A: 可以设置环境变量跳过下载:
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm install puppeteer
然后手动指定executablePath:
const browser = await puppeteer.launch({
executablePath: '/path/to/chrome'
});
Q: 元素点击不生效?
A: 尝试:
1. 添加等待:await page.waitForSelector('#button')
2. 使用{clickCount: 2}
模拟双击
3. 直接执行JS点击:await page.$eval('#button', btn => btn.click())
Q: 如何绕过反爬机制?
A: 可以尝试:
await page.setUserAgent('Mozilla/5.0...');
await page.setExtraHTTPHeaders({
'Accept-Language': 'en-US,en;q=0.9'
});
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'webdriver', {
get: () => false
});
});
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com', {
waitUntil: 'networkidle2'
});
await page.screenshot({
path: 'fullpage.png',
fullPage: true
});
await browser.close();
})();
const results = await page.evaluate(() => {
const items = document.querySelectorAll('.product');
return Array.from(items).map(item => ({
title: item.querySelector('h3').innerText,
price: item.querySelector('.price').innerText
}));
});
describe('Login Test', () => {
let browser, page;
beforeAll(async () => {
browser = await puppeteer.launch();
page = await browser.newPage();
});
it('should login successfully', async () => {
await page.goto('https://example.com/login');
await page.type('#username', 'testuser');
await page.type('#password', 'password');
await page.click('#submit');
await page.waitForNavigation();
expect(page.url()).toBe('https://example.com/dashboard');
});
afterAll(async () => {
await browser.close();
});
});
// 开始跟踪
await page.tracing.start({ path: 'trace.json' });
// 执行操作
await page.goto('https://example.com');
// 停止跟踪
await page.tracing.stop();
// 分析生成的trace.json文件
Puppeteer为Node.js开发者提供了强大的浏览器自动化能力,无论是网页测试、数据抓取还是性能分析,都能高效完成。本文涵盖了从安装配置到高级应用的完整流程,希望对你掌握Puppeteer有所帮助。
waitFor
系列方法确保元素加载完成puppeteer-cluster
处理大规模任务通过不断实践和探索,你将能够充分利用Puppeteer的强大功能,构建出高效的浏览器自动化解决方案。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。