公司最近要根据数据生成一批图片来展示使用,起初由后端完成,然后兜兜转转又跑到了前端来生成。前期打算使用html2canvas.js来完成,但是稳定性太差,最后选择puppeteer来完成这个工作。
关于puppeteer
你可以在浏览器中手动执行的绝大多数操作都可以使用 Puppeteer 来完成!
- 生成页面 PDF。
- 抓取 SPA(单页应用)并生成预渲染内容(即“SSR”(服务器端渲染))。
- 自动提交表单,进行 UI 测试,键盘输入等。
- 创建一个时时更新的自动化测试环境。
- 和浏览器功能直接在最新版本的Chrome中执行测试。
- 捕获网站的 timeline trace,用来帮助分析性能问题。
- 测试浏览器扩展。
github地址github.com/GoogleChrom… 中文文档地址zhaoqize.github.io/puppeteer-a…
思路
- 完成静态页面
- 静态页中获取页面详情动态渲染页面
- 使用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();
})()
部署填坑
- centos6应该是不支持的,结果我们弄了半天,发现要7才行。
- 首次运行可能会报错需要安装一些依赖,具体安装可以看这里github.com/puppeteer/p…
- 祛沙箱设置
const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});
,否则会报错在服务器运行 - 如果截取的图片中文字显示不正确,需要在服务器安装相应字体,在html中指定
- node接口最开始用的pm2后来改成了forever
后记
我们当时是为了批量生成上千张图片用的他,写成了一个node的接口还。在批量生成图片时采用的方法是用for循环不停的调用,生成的一批图片,不过在生成过程中要保持电脑不锁屏,锁屏就会中断。