前言:最近实现一个针对页面做截图的功能,一开始是想使用html2canvas,但是发现html2canvas(V1.4.1)针对带有box-shadow属性的input或者button,截图出来后的效果不是很理想,所以考虑使用puppeteer+nodejs去实现,以下是我的实现步骤:
1.创建node项目安装具体依赖包一下(我的node环境是16的)
"axios": "^1.5.1",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"express": "^4.18.2",
"form-data": "^4.0.0",
"multer": "^1.4.5-lts.1",
"puppeteer": "^21.3.8"
2.创建入口文件
const express = require('express')
//导入自定义路由
const puppeteer = require('./routers/puppeteer');
//创建服务器对象
const serverapp = express();
const cors = require('cors');
//设置中间件(每次請求接口都會調用中間件函數)
serverapp.use(puppeteer);
//开启服务器
serverapp.listen(3000,()=>{
console.log('服务器开启成功!')
})
3.在routers文件夹下创建puppeteer文件(主要是执行puppeteer截图功能)
//導入express模板
const express = require('express')// 获取路由对象
const router = express.Router();
//注册bodyParser中间件,用来自动解析请求报文中的urlencode格式的数据,并将数据组装成对象存在request.body属性中
const bodyParser = require('body-parser');
router.use(bodyParser.urlencoded({extended:false}))
// 引入依赖插件
const puppeteer = require("puppeteer");
const fs = require("fs");
const path = require("path");
const axios = require("axios");
const FormData = require("form-data");
let theBrowser = null;
//要截图图片的网站
const websiteUrl = "https://xxx.html";
router.post('/puppeteer',(req,res)=>{
// 启动puppeteer
puppeteer
.launch({
// root 权限下需要取消sandbox
executablePath: '/usr/bin/chromium-browser',//这个路径下面内容有说明
args: ["--no-sandbox"],
headless: true,//开启无头浏览器
})
.then(async (browser) => {
theBrowser = browser;
// 打开浏览器
const page = await browser.newPage();
// tab访问需要截图的页面,使用await可以等待页面加载完毕
await page.goto(websiteUrl, { timeout: 0, waitUntil: "networkidle2" });
const bodyHandle = await page.$("body");
const { height, width } = await bodyHandle.boundingBox();
await bodyHandle.dispose();
// 页面渲染完毕后,开始截图
await page.screenshot({
path: path.join(__dirname, "../puppeteer-img","puppeteerImg.png"),
fullPage: true,
encoding: "binary",
});
// 截图成功后,将截图上传至图片服务器
let _formData = new FormData();
_formData.append("file",fs.createReadStream(path.join(__dirname,"../puppeteer-img", "puppeteerImg.png")));
_formData.append( "path", "xxx");
axios
.post( "https://xxx",_formData)
.then((result) => {
res.send({
msg: '成功',
code: 200,
})
theBrowser.close();
})
.catch((err) => {
res.send({
msg: '失败',
code: 400,
})
theBrowser.close();
});
})
.catch((error) => {
console.log(error)
});
})
// 导出 路由对象
module.exports = router;
4. 在本地控制台运行
注意:把上面代码的executablePath 修改成本地chorme.exe存放路径,我的是C:/Program Files/Google/Chrome/Application/chrome.exe
5.部署到AWS EC2(当然需要安装node环境,但是我不会,哈哈,勿喷)
注意:因为puppeteer需要chromium,所以需要在AWS EC2安装一下,执行以下命令
sudo yum install -y chromium
然后找到chromium的安装地址并替换上面代码中的executablePath