# 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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。