Node.js中如何使用Puppeteer库

发布时间:2021-12-13 15:31:08 作者:iii
来源:亿速云 阅读:352
# 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

安装Puppeteer

在项目目录中运行:

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();
  }
});

执行JavaScript

// 在页面上下文中执行
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);

生成PDF

await page.pdf({
  path: 'page.pdf',
  format: 'A4',
  printBackground: true
});

处理多个页面和iframe

// 获取所有页面
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有所帮助。

最佳实践建议

  1. 总是使用waitFor系列方法确保元素加载完成
  2. 合理复用浏览器实例提高性能
  3. 处理异常情况,避免进程挂起
  4. 考虑使用puppeteer-cluster处理大规模任务
  5. 遵守目标网站的robots.txt和版权规定

扩展学习

通过不断实践和探索,你将能够充分利用Puppeteer的强大功能,构建出高效的浏览器自动化解决方案。 “`

推荐阅读:
  1. 实例:使用puppeteer headless方式抓取JS网
  2. puppeteer 尝试

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

node.js puppeteer

上一篇:Drone与Jenkins举例分析

下一篇:Oracle sharding database的示例分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》