【JS】用 Puppeteer + Nodejs 构建高效海报 & 截图生成服务

【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();

})()

基本架构

【JS】用 Puppeteer + Nodejs 构建高效海报 & 截图生成服务

说明

截图请求接口:此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 服务

【JS】用 Puppeteer + Nodejs 构建高效海报 & 截图生成服务

启动 psotman 模拟请求接口

1.百度

【JS】用 Puppeteer + Nodejs 构建高效海报 & 截图生成服务
查看结果
【JS】用 Puppeteer + Nodejs 构建高效海报 & 截图生成服务

2.掘金

{

"url": "https://juejin.cn/",

"width": 720,

"height": 1080,

"tid": 0

}

【JS】用 Puppeteer + Nodejs 构建高效海报 & 截图生成服务

嗯,看起来也没啥问题

具体业务应用

目前有生成海报的需求,那么我们应该怎么搞?

1.根据UI图,搞定托管页
2.根据传入的变量id,写好后端逻辑,

【JS】用 Puppeteer + Nodejs 构建高效海报 & 截图生成服务

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 构建高效海报 &amp; 截图生成服务 的全部内容, 来源链接: utcz.com/a/90489.html

回到顶部