【JS】用 Puppeteer + Nodejs 构建高效海报 & 截图生成服务
puppeteer
puppeteer 初识
Puppeteer 是 Google Chrome 团队官方的无界面(Headless)Chrome 工具。Chrome 作为浏览器市场的领头羊,Chrome Headless 将成为 web 应用 自动化测试 的行业标杆
那么我们可以用puppeteer来些什么?
- 生成页面的截图或者PDF
- 自动模拟用户行为,表单提交、按钮点击等
- 创建自动化测试环境
- 捕获站点的时间线跟踪,以帮助诊断性能问题。
- 爬取 SPA 页面并进行预渲染(即'SSR')
puppeteer 安装
npm install puppeteer// 下载内核步骤可能会失败,cnpm 或科学上网
puppeteer 主要api
1.启动实例
import * as puppeteer from 'puppeteer'(async () => {
await puppeteer.launch()
})()
2.网页截图
png截图
await page.setViewport({width, height})await page.goto(url)
//对整个页面截图
await page.screenshot({
path: path.resolve(`./screenshot/${fileName}.png`), //图片保存路径
type: 'png',
fullPage: false //边滚动边截图
})
不仅如此 还可以模拟手机的device环境
import * as puppeteer from "puppeteer";import * as devices from "puppeteer/DeviceDescriptors";
const iPhone = devices["iPhone 6"];
(async () => {
const browser = await puppeteer.launch({
headless: false
});
const page = await browser.newPage();
await page.emulate(iPhone);
await page.goto("https://baidu.com/");
await browser.close();
})();
pdf截图
(async () => {const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://example.com/");
await page.pdf({
displayHeaderFooter: true,
path: 'example.pdf',
format: 'A4',
headerTemplate: '<b>Hello world<b/>',
footerTemplate: '<b>Some text</b>',
margin: {
top: "100px",
bottom: "200px",
right: "30px",
left: "30px",
}
});
await browser.close();
})()
基本架构
说明
截图请求接口:此api会直接请求到 node 服务,会携带参数包括:
- 托管页地址 (为要截取网页的地址)
- 要截图的宽高
- 截图的类型 (png/pdf)
截图托管页:静态的html页面。可url传参数去控制变量
node服务收到接口请求后,会请求托管页,构建一个要截取的网页,执行截图操作的api,返回截图buffer数据给请求的接口,到此为止,我们基础架构就整理完毕了
上 demo 代码
// router层const screenshotControllers = require('../controllers/puppeteer')
const router = new KoaRouter()
exports.router = router.post('/api/puppeteer/v1/screenshot', screenshotControllers.api.screenshot)
// conteoller层const service = require('../service/puppeteer')
const screenshot = (ctx, next) => {
return service.api.screenshot(ctx);
}
exports.api = {
screenshot
}
// service层const { getScreenshot } = require('../puppeteer/index')
exports.api = {
screenshot: async (ctx) => {
const { width, height, url, tid} = ctx.request.body
const res = await getScreenshot(url, width, height, tid)
console.log(res)
if (res) {
ctx.body = {
code: 200,
message: '成功',
data: res
}
}
}
}
//具体业务层const puppeteer = require('puppeteer');
const path = require('path')
exports.getScreenshot = async (url, width = 800, height = 600, fileName) => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
//设置可视区域大小,默认的页面大小为800x600分辨率
await page.setViewport({width, height})
await page.goto(url)
//对整个页面截图
await page.screenshot({
path: path.resolve(`./screenshot/${fileName}.png`), //图片保存路径
type: 'png',
fullPage: false //边滚动边截图
})
//执行cos 或 oss 脚本,把图片上传到cdn环境,此处由于调试,暂时省略
await page.close()
await browser.close()
return `${fileName}.png`
}
测试服务可用性
启动 node 服务
启动 psotman 模拟请求接口
1.百度
查看结果
2.掘金
{"url": "https://juejin.cn/",
"width": 720,
"height": 1080,
"tid": 0
}
嗯,看起来也没啥问题
具体业务应用
目前有生成海报的需求,那么我们应该怎么搞?
1.根据UI图,搞定托管页
2.根据传入的变量id,写好后端逻辑,
3.调用node服务,获得图片buffer 或图片cdn地址
await axios({method: 'POST',
url: 'http://xxx/api/puppeteer/v1/screenshot',
data: {
url: `http://xxx/postFrame/home?lecCode=lec${i}`,
width: 335,
height: 525,
tid: `lec${i}`
}
})
以上是 【JS】用 Puppeteer + Nodejs 构建高效海报 & 截图生成服务 的全部内容, 来源链接: utcz.com/a/90489.html