美文网首页2018武汉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.haomeiwen.com/subject/xkwsbftx.html