利用NODEJS+Puppeteer实现服务器保存网页为图片和PDF

本文适用于对docker,node有一定了解的童鞋

Puppeteer简介

今年5月在github上创建的项目,属于比较新的chromium无头浏览器类库。

Puppeteer在项目中的实际使用

基础安装

选用Puppeteer的主要原因有两点,

  • 1:GOOGLE官方维护,活跃度很高,个人觉得前途光明。
  • 2:我们的产品在chrome上适配最好。目前最新版本是0.13.0,我们采用0.12.0版本,因0.13.0版本API做了一些变化无法满足我们的需求。我们截图时有如下两个必须解决的场景
    • 网站需要等待当前仪表盘所有查询都完成才可以进行截图操作
    • 我们并不知道所有仪表盘发起的查询会查询多久结束

npm安装puppeteer时会从google一个网站上下载chromium,因为墙的原因会下载失败。我们采用的方式先设置环境变量

    set PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
复制代码

阻止install的时候自动下载,然后手工下载chromium后通过docker build打包成一个基础镜像。我们在Dockerfile中From此镜像,然后再做后续操作。

    npm instal puppeteer@0.12.0 --save
复制代码

现在可通过docker很快速的进行打包。最终打包后的image里/usr/src/node/包含node代码及chromium目录

基本操作

调用puppeteer

我们手动指定chromium目录来运行。

   const browser = await puppteer.launch({
        args: ['--no-sandbox', '--disable-setuid-sandbox'],  // docker中运行需要加上这两个args
        executablePath: 'chromium/chrome', // 基础镜像已将chromium复制到/usr/src/node/chromium目录下
   });
复制代码
保存图片

通过URL打开网站

   await page.goto(fullUrl, {
       waitUntil: 'networkidle',
       networkIdleTimeout: 15000,
       timeout: 240000
   });
复制代码

networkIdleTimeout: 15000参数代表当前页面网络处于idle状态至少15秒时导航完毕,避免导出的截图数据不全。
如果直接保存整个页面为图片或PDF是很简单的,有现成的API直接调用。但这次我们只将某一区域保存为图片,

    let rect = await page.evaluate(() => {
        const element = document.querySelector(
            '.class1'
        );  // 选择包含指定class属性的dom节点
        const { x, y, width, height } = element.getBoundingClientRect();
        return {
            left: x,
            top: y,
            width,
            height,
        };
    });
    await page.screenshot({
        path: imagePath,
        clip: {
            x: rect.x,
            y: rect.y,
            width: actualWidth,
            height: actualHeight
        }
    });
复制代码

可以在page.evaluate中操作页面元素,所以可以获取指定区域的长宽等信息。这样我们只需截取那一区域即可。完整的API地址还是请参阅github官方API文档

保存PDF

如上节所说,如果保存整个页面为PDF很简单,因为我们只保存某一区域,然而保存pdf的API中没有类似page.screenshot中clip参数,我的处理方式就是将上一步保存的图片转为PDF即可。转换方式很多,我采用pdfkit类库实现。代码就不赘述,可以参考很多DEMO。

总结

因为我们通过docker+CICD+devops打包部署node服务,puppeteer在docker中也有一些坑,好在官方给出了一系列解决方案。我在实际使用中还是偶尔发生页面加载失败的情况,期望在未来版本会变得更加强大和稳定。

转载于:https://juejin.im/post/5a68a501f265da3e54693f30

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值