Puppeteer 实战教程:网页WebP高清截屏 + PDF导出(含Linux部署、中文适配、报错解决)

Puppeteer 是 Google 官方推出的 Node.js 无头浏览器工具,可完美渲染动态网页,实现无失真网页截图、标准化PDF导出,广泛应用于报表生成、网页存档、内容预览、自动化截图等场景。 本文整合核心功能代码、Linux环境完整依赖、中文乱码解决方案、Windows/Linux常见报错排查,是一套可直接上线的生产级实操文档,支持 WebP 高清截屏、网页PDF批量导出。

2021/4/15·26 views
Puppeteer 实战教程:网页WebP高清截屏 + PDF导出(含Linux部署、中文适配、报错解决)

Puppeteer 是 Google 官方推出的 Node.js 无头浏览器工具,可完美渲染动态网页,实现无失真网页截图、标准化PDF导出,广泛应用于报表生成、网页存档、内容预览、自动化截图等场景。

本文整合核心功能代码、Linux环境完整依赖、中文乱码解决方案、Windows/Linux常见报错排查,是一套可直接上线的生产级实操文档,支持 WebP 高清截屏、网页PDF批量导出。

一、基础环境安装

1.1 安装依赖包

支持 npm / pnpm / yarn 包管理器,安装核心依赖:

bash 复制代码
npm install puppeteer
# pnpm install puppeteer
# yarn add puppeteer

1.2 Windows 安装报错专属解决

Windows 环境常出现 Chrome 内核下载失败报错:Failed to set up chrome-headless-shell v125.0.6422.78!

解决方案:跳过内置浏览器下载,使用本地浏览器内核

方式1:npm/pnpm(推荐)

在项目根目录新建 .npmrc 文件,写入配置:

ini 复制代码
PUPPETEER_SKIP_DOWNLOAD=true

方式2:yarn 临时配置

bash 复制代码
# CMD 终端执行
set PUPPETEER_SKIP_DOWNLOAD=true

# PowerShell 终端执行
$env:PUPPETEER_SKIP_DOWNLOAD = "true"

# 再执行安装
yarn install

二、Linux(CentOS)环境完整依赖部署

Linux 服务端运行 Puppeteer 必须安装系统依赖,否则会出现浏览器启动失败、沙箱报错、渲染异常等问题,完整一键安装命令如下:

bash 复制代码
# 安装Chromium运行必备系统依赖
yum install -y alsa-lib.x86_64
yum install -y atk.x86_64
yum install -y cups-libs.x86_64
yum install -y gtk3.x86_64
yum install -y ipa-gothic-fonts
yum install -y libXcomposite.x86_64
yum install -y libXcursor.x86_64
yum install -y libXdamage.x86_64
yum install -y libXext.x86_64
yum install -y libXi.x86_64
yum install -y libXrandr.x86_64
yum install -y libXScrnSaver.x86_64
yum install -y libXtst.x86_64
yum install -y pango.x86_64
yum install -y xorg-x11-fonts-100dpi
yum install -y xorg-x11-fonts-75dpi
yum install -y xorg-x11-fonts-cyrillic
yum install -y xorg-x11-fonts-misc
yum install -y xorg-x11-fonts-Type1
yum install -y xorg-x11-utils
yum install -y mesa-libgbm-devel.x86_64

# 更新nss库,修复内核兼容问题
yum update nss -y

三、核心问题:PDF/截图中文不显示解决

Linux 环境默认无中文字体,会导致导出 PDF、WebP 截图中文空白、乱码、方框,专属修复方案:

3.1 检查当前中文字体

bash 复制代码
# 查看系统已安装中文字体
fc-list :lang=zh

若提示命令不存在,先安装字体管理工具:

bash 复制代码
yum install -y fontconfig

3.2 手动安装中文字体

  1. 准备 Windows 自带中文字体(微软雅黑、宋体、黑体等),上传至服务器

  2. 将字体文件移动到系统字体目录:/usr/share/fonts

  3. 执行字体缓存更新命令:

bash 复制代码
# 进入字体目录
cd /usr/share/fonts
# 生成字体索引
mkfontscale
mkfontdir
# 更新系统字体缓存
fc-cache -fv

执行完成后,再次通过 fc-list :lang=zh 可看到中文字体,重启项目即可正常渲染中文。

四、核心功能实战代码

整合 WebP 高清截屏网页PDF导出 双功能,兼容 Windows / Linux,修复中文、模糊、启动报错等问题,为生产可用版本。

javascript 复制代码
const puppeteer = require('puppeteer');
const path = require('path');
const fs = require('fs');

// 自动创建输出目录
const OUTPUT_DIR = path.resolve(__dirname, './puppeteer-output');
if (!fs.existsSync(OUTPUT_DIR)) fs.mkdirSync(OUTPUT_DIR);

/**
 * 网页WebP高清截屏
 * @param {string} url 目标网页地址
 * @param {boolean} fullPage 是否整页截图
 * @param {number} quality 画质 0-100
 * @returns {string} 文件路径
 */
async function captureWebpScreenshot(url, fullPage = true, quality = 90) {
  // 兼容Linux服务端、Windows环境的启动参数
  const browser = await puppeteer.launch({
    headless: 'new', // 新版稳定无头模式
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--disable-dev-shm-usage',
      '--disable-features=HttpsFirstBalancedModeAutoEnable' // 修复HTTP页面拦截报错
    ]
  });

  const page = await browser.newPage();
  // 高清渲染,解决截图模糊问题
  await page.setViewport({ width: 1920, height: 1080, deviceScaleFactor: 2 });
  
  // 等待网页完全加载(动态JS、接口、图片渲染完成)
  await page.goto(url, { waitUntil: 'networkidle0', timeout: 30000 });

  const savePath = path.join(OUTPUT_DIR, `${Date.now()}.webp`);
  // WebP截屏核心配置
  await page.screenshot({
    path: savePath,
    type: 'webp',
    quality,
    fullPage,
    omitBackground: true // 保留透明背景
  });

  await browser.close();
  return savePath;
}

/**
 * 网页导出标准PDF(兼容中文、样式完整)
 * @param {string} url 目标网页地址
 * @returns {string} PDF文件路径
 */
async function exportPageToPdf(url) {
  const browser = await puppeteer.launch({
    headless: 'new',
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--disable-dev-shm-usage',
      '--disable-features=HttpsFirstBalancedModeAutoEnable'
    ]
  });

  const page = await browser.newPage();
  await page.setViewport({ width: 1920, height: 1080 });
  await page.goto(url, { waitUntil: 'networkidle0', timeout: 30000 });

  const savePath = path.join(OUTPUT_DIR, `${Date.now()}.pdf`);
  // PDF生产级配置,解决样式丢失、页眉页脚问题
  await page.pdf({
    path: savePath,
    format: 'A4',
    printBackground: true, // 关键:保留网页背景色/图片
    displayHeaderFooter: false, // 关闭默认网址、时间页眉页脚
    preferCSSPageSize: true, // 优先适配网页CSS页面样式
    margin: { top: '20px', bottom: '20px', left: '20px', right: '20px' }
  });

  await browser.close();
  return savePath;
}

// 测试执行
(async () => {
  const testUrl = 'https://www.baidu.com';
  // 生成WebP截图
  const imgPath = await captureWebpScreenshot(testUrl);
  console.log('WebP截图生成成功:', imgPath);
  // 生成PDF文件
  const pdfPath = await exportPageToPdf(testUrl);
  console.log('PDF文件生成成功:', pdfPath);
})();

五、关键参数详解

5.1 WebP 截屏优势

  • 体积更小:同等画质下,体积仅为 PNG 的 1/3、JPG 的 1/2,适合文件存储、接口返回

  • 画质无损:支持高清渲染、透明背景,适配海报、网页预览场景

  • 兼容性强:所有现代浏览器、服务端均支持解析

5.2 PDF 核心避坑参数

  • printBackground: true:必开!默认关闭会导致网页背景、图片丢失,样式残缺

  • displayHeaderFooter: false:关闭 Chromium 默认自带的多余页眉页脚,保证PDF整洁

  • networkidle0:等待页面无网络请求、动态内容渲染完成后再生成文件,避免内容缺失

六、官方常见报错解决方案(汇总)

6.1 Cannot find module 'puppeteer-core/internal/...'

原因:Node.js 版本过低(低于14)或解析器兼容问题

解决:升级 Node.js 至 16+,升级 jest 等代码解析器版本

6.2 Could not find expected browser locally

原因:浏览器缓存目录异常、未下载内核

解决:自定义缓存目录,执行手动安装命令:

bash 复制代码
npx puppeteer browsers install

6.3 net::ERR_BLOCKED_BY_CLIENT(HTTP页面拦截)

原因:新版 Chrome 开启 HTTPS 优先模式,拦截 HTTP 网页

解决:代码中加入启动参数 --disable-features=HttpsFirstBalancedModeAutoEnable(已整合进示例代码)

6.4 Linux No usable sandbox 沙箱报错

解决:内网/可信环境可开启沙箱跳过参数(生产内网通用)

参数:--no-sandbox --disable-setuid-sandbox(已默认配置)

七、生产环境最佳实践

  1. 环境适配:Linux 服务器必须安装全套系统依赖 + 中文字体,避免渲染异常

  2. 资源释放:每次生成文件后必须 browser.close(),防止浏览器进程堆积、内存溢出

  3. 超时配置:页面加载超时设置30s,适配慢网络、复杂动态页面

  4. 格式优选:截图优先 WebP(体积最优),归档优先 PDF(格式标准化)

  5. 报错兜底:接口业务中增加 try/catch,避免单页面渲染失败导致服务崩溃

(注:部分内容可能由 AI 生成)