美文网首页武汉21天写作
使用 Puppeteer 生成 PDF

使用 Puppeteer 生成 PDF

作者: ForBravo | 来源:发表于2018-08-13 15:56 被阅读2次

基本介绍

Puppeteer 是一个 node 库,他提供了一组通过 DevTools Protocol
用来操纵 Chrome 和 Chromium 的高层次 API。

Puppeteer 可以用来做几乎所有可以手动在浏览器里面做的事情,目前主要用来做如下工作:

  1. 利用网页生成 PDF、图片
  2. 爬取SPA应用,并生成预渲染内容(即“SSR” 服务端渲染)
  3. 自动化表单提交、UI测试、键盘输入等
  4. 创建一个最新的自动化测试环境。可以直接在最新版 Chrome 中测试最新的 JavaScript 和 浏览器功能。
  5. 捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题
  6. 测试 Chrome 插件

Puppeteer 是 Chrome 官方团队进行维护的,因此相较于其他竞品例如 PhantomJS 有着更好的稳定性和前景。

安装

Puppeteer 需要 NodeJS 版本不低于6.4.0,但是为了使用 async / await 机制,NodeJS 版本建议不低于 7.6.0。

npm install puppeteer --save

通过如上命令安装 Puppeteer 时同时会下载最新版 Chromium。

生成 PDF

使用 Puppeteer 生成 PDF 只需要几行代码。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.pdf({path: 'example.pdf'});
  await browser.close();
})();

大概解读一下上面几行代码:

  1. 通过 puppeteer.launch() 创建一个浏览器实例 Browser 对象
  2. 通过 Browser 对象创建页面 Page 对象
  3. 调用 page.goto() 跳转到指定的页面
  4. 调用 page.pdf() 生成 PDF 文件
  5. 关闭浏览器

大部分方法都可以通过设定参数来来达到定制化效果

  • puppeteer.launch() 方法可以通过设定 executablePath 来指定运行的 Chrome 或 Chromium 路径。
  • page.goto() 方法跟浏览器一样可以指定一个网页 url 或者本地文件。
  • page.pdf() 可以指定打印格式,自定义页头页尾等。

每个方法的详细 API 可以通过官方 API 文档进行查询。

不难发现,通过 Puppeteer 生成 PDF 的步骤跟手动使用 Chrome 浏览器把网页打印成 PDF 格式的步骤几乎一样。可见其设计哲学更符合人类的使用习惯,更自然。

在 Docker 中使用

在 Docker 中使用 Puppeteer 稍显复杂,因为其 node 库中自带的 Chromium 缺少一些依赖。这些依赖在桌面环境中一般都已自带,但是在 Docker 的 node 源镜像例如 node-alpine 或者 node-slim 是缺失的。所以,在 Docker 中使用 Puppeteer 需要首先安装这些缺失的依赖。

以 node-aipine 源镜像为例

FROM node:9-alpine
RUN apk update && apk upgrade && \
    echo http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories && \
    echo http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories && \
    apk add --no-cache \
      zlib-dev \
      xvfb \
      xorg-server \
      dbus \
      ttf-freefont \
      chromium \
      nss \
      ca-certificates \
      dumb-init

这些命令会安装 Chromium 以及其必要的依赖。安装 Chromium 是因为可以以 node-alpine 或者 node-slim 镜像为基础,安装好 Chromium 和其他依赖以后打包新的 image 作为项目中使用的 docker 源。这样可以极大的减少 docker build 的时间。

加入下面环境变量可以使得 Puppeteer 跳过下载自带的 Chromium。

ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true

程序使用 Puppeteer 时需要加入如下参数

const browser =  await puppeteer.launch({
    executablePath: '/usr/bin/chromium-browser',
    args: ['--disable-dev-shm-usage', '--no-sandbox']
});

executablePath 参数指定的是 aipine 版 Chromium 的启动路径。
args 参数中的 --disable-dev-shm-usage 是为了解决 Docker 中 /dev/shm 共享内存太小不足以支持 Chromium 运行的问题,详见 TIPS
args 参数中的 --no-sandbox 是为了避免 Chromium 在 Linux 内核中由 sandbox 导致的启动问题。

网友评论

    本文标题:使用 Puppeteer 生成 PDF

    本文链接:https://www.meiwen.com.cn/subject/xkwsbftx.html

    栏目导航