puppeteer批量生成图片

2,279 阅读2分钟

公司最近要根据数据生成一批图片来展示使用,起初由后端完成,然后兜兜转转又跑到了前端来生成。前期打算使用html2canvas.js来完成,但是稳定性太差,最后选择puppeteer来完成这个工作。

关于puppeteer

你可以在浏览器中手动执行的绝大多数操作都可以使用 Puppeteer 来完成!

  • 生成页面 PDF。
  • 抓取 SPA(单页应用)并生成预渲染内容(即“SSR”(服务器端渲染))。
  • 自动提交表单,进行 UI 测试,键盘输入等。
  • 创建一个时时更新的自动化测试环境。
  • 和浏览器功能直接在最新版本的Chrome中执行测试。
  • 捕获网站的 timeline trace,用来帮助分析性能问题。
  • 测试浏览器扩展。

github地址github.com/GoogleChrom… 中文文档地址zhaoqize.github.io/puppeteer-a…

思路

  1. 完成静态页面
  2. 静态页中获取页面详情动态渲染页面
  3. 使用puppeteer根据需求将页面所需截取图片,并按照需求命名保存,以便其他同事上传图片做对应

开工

完成静态页,页面接受所需参数,请求接口。

页面展示无问题,使用puppeteer打开该静态页面(www.baidu.com为例),根据需求将所需html截取为图片保存在本地文件夹。

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({
        executablePath: '', // 指定浏览器位置,由于下载未成功报相关错误时可自行下载指定位置
        headless: true //是否弹出浏览器 默认true不弹
    })

     const page = await browser.newPage();
                await page.goto('www.baidu.com', {
                    waitUntil: 'networkidle0',
                    timeout: 0 //批量生成时以防超时自动中断
                } );
                await page.setRequestInterception(true);
                await page.on('requestfinished', request => {
                    //监听请求结束,更多配置可以在github上查一下
                })
                await page.waitFor(3000); // 延迟时间毫秒
                //获取页面Dom对象
                let body = await page.$('#xxx'); // 根据id获取需要截取的html也可以根据其他截取或者整个截取
            
                //调用页面内Dom对象的 screenshot 方法进行截图
                await body.screenshot({
                    path: '/Users/xxx/Documents/xxx/puppeteer/img/' + xxx + 'xxx' + '.png'
                }); // 自定义截图位置和名字
                let bodyBig = await page.$('#xxx'); //截取另一张图
                //调用页面内Dom对象的 screenshot 方法进行截图
                await bodyBig.screenshot({
                    path: '/Users/xxx/Documents/xxx/puppeteer/img/' + xxx + '_xxx' + '.png'
                });
                await browser.close();
})()

部署填坑

  1. centos6应该是不支持的,结果我们弄了半天,发现要7才行。
  2. 首次运行可能会报错需要安装一些依赖,具体安装可以看这里github.com/puppeteer/p…
  3. 祛沙箱设置 const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});,否则会报错在服务器运行
  4. 如果截取的图片中文字显示不正确,需要在服务器安装相应字体,在html中指定
  5. node接口最开始用的pm2后来改成了forever

后记

我们当时是为了批量生成上千张图片用的他,写成了一个node的接口还。在批量生成图片时采用的方法是用for循环不停的调用,生成的一批图片,不过在生成过程中要保持电脑不锁屏,锁屏就会中断。