Puppeteer简介
Puppeteer 是一个用于控制 Headless Chrome 或 Chromium 浏览器的 Node.js 库。它提供了一个高层次的 API,能够让你以编程方式操作浏览器,从而实现自动化任务,比如生成页面截图和 PDF、抓取网页内容、自动化表单提交、UI 测试等。
简单来讲我们部署一个虚拟浏览器, 通过后台渲染然后把图片输出
安装Puppeteer
使用node.js可以直接将Puppeteer部署为服务
bash
mkdir puppeteer-service
cd puppeteer-service
npm init -y
npm install puppeteer
npm install express
编写js脚本
编写一个用于启动的js脚本, 起名 为indx.js, 将其放在根目录下
javascript
const express = require('express');
const puppeteer = require('puppeteer');
const bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
const app = express();
app.use(bodyParser.json());
app.post('/generate-echarts', async (req, res) => {
const { templateName, data } = req.body;
console.error('请求参数:', data);
if (!templateName) {
return res.status(400).send('缺少模板名称');
}
if (!data) {
return res.status(400).send('缺少ECharts配置参数');
}
const templatePath = path.join(__dirname, 'templates', `${templateName}.html`);
if (!fs.existsSync(templatePath)) {
return res.status(404).send('模板文件不存在');
}
let browser;
try {
// 启动无头浏览器
browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
const content = fs.readFileSync(templatePath, 'utf-8');
await page.setContent(content);
// 等待 #chart 元素加载完成
await page.waitForSelector('#chart', { timeout: 60000 });
// 将配置参数传递给页面并渲染图表
await page.evaluate(data => {
window.postMessage(data, '*');
}, data);
// 等待 ECharts 动画完成
await page.waitForFunction(
() => window.chartRendered === true,
{ timeout: 60000 }
);
const element = await page.$('#chart');
const boundingBox = await element.boundingBox();
if (!boundingBox) {
throw new Error('#chart 元素未能正确加载或未设置尺寸');
}
await page.setViewport({
width: Math.ceil(boundingBox.width),
height: Math.ceil(boundingBox.height)
});
const screenshotBuffer = await element.screenshot();
res.setHeader('Content-Type', 'image/png');
res.send(screenshotBuffer);
} catch (error) {
console.error('生成图表时出错:', error);
res.status(500).send('生成图表时出错');
} finally {
if (browser) {
await browser.close();
}
}
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Puppeteer 服务运行在端口 ${PORT}`);
});
echarts代码
首先创建一个templates文件夹放在根目录下, 然后我们把所有将来要用到生成图片的echarts的html文件放在这个目录下
我们可以再官网女随便找一个echarts图片来进行生成
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>
</head>
<body>
<div id="chart" style="width: 600px;height:400px;"></div>
<script>
// 使用传入的配置参数初始化 ECharts 图表
function renderChart(option) {
var chart = echarts.init(document.getElementById('chart'));
chart.setOption(option);
// 在所有动画完成后触发事件
chart.on('finished', function () {
console.log('ECharts animation finished');
window.chartRendered = true;
});
}
// 等待 Puppeteer 注入配置参数并渲染图表
window.addEventListener('message', function (event) {
renderChart(event.data);
});
</script>
</body>
</html>
启动服务
启动服务只需要在根目录下执行
bash
node index.js
测试请求服务
使用postman请求:http://localhost:3000/generate-echarts
请求体:
bash
{
"templateName": "echart",
"data": {
"title": { "text": "动态 ECharts 示例" },
"tooltip": {},
"xAxis": { "data": ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"] },
"yAxis": {},
"series": [{ "name": "销量", "type": "bar", "data": [5, 20, 36, 10, 10, 20] }]
}
}