基于Puppeteer实现动态渲染的网页截图
为什么使用Puppeteer?
实现网页截图有很多种无头浏览器自动化解决方案,其中包括熟知的有:
Selenium:一款非常流行的自动化测试工具,支持多种编程语言和多种浏览器,包括 Chrome、Firefox、Safari、IE 等。功能强大的Chrome自动化工具
PhantomJS:一个已经停止维护的无头浏览器,虽然已经停止更新,但仍然可以使用。不可以截图动态渲染的页面,如VUE开发的站点
Zombie.js:一个使用 Node.js 实现的无头浏览器,提供了基本的浏览器功能,支持 JavaScript、CSS、HTML5 和 WebSockets 等技术。不可以截图动态渲染的页面,如VUE开发的站点
上诉对比来讲,对于简单网页截图来讲,服务器部署方便,内存占用小,API完善是比较好。
环境部署
以下命令使用ubuntu 20.x系统演示,Centos自行搜索相关的yum命令
安装Nodejs 14.16.x-14.18.x,如果你是M芯片的Mac用户最好使用14.18.x,不然打包后的依赖可能不兼容。
然后安装Chromium浏览器:Chromium浏览器是Puppeteer的依赖,需要先安装Chromium浏览器。
apt install chromium-browser
安装中文字体:Chromium浏览器可能需要一些中文字体才能正确显示中文网页。使用以下命令安装中文字体。
apt install fonts-wqy-zenhei
代码实现:
// 启动Headless Chrome浏览器 const browser = await puppeteer.launch({ args: ['--no-sandbox'], timeout: 30000 }); try { // 打开一个新页面 const page = await browser.newPage(); // 导航到目标网页,并等待页面加载完成, 时间5秒 await page.goto(url, {waitUntil: 'networkidle0', timeout: 10000}); // 截取屏幕截图 let timeout = 5500; // 超时时间 const screenshotPromise = page.screenshot({type: 'png', fullPage: true}); const result = await Promise.race([ screenshotPromise, new Promise((_, reject) => setTimeout(() => reject(`截图超时(${timeout}ms)!`), timeout) ) // 超时Promise对象 ]); fs.writeFileSync(filePath, result); // 将截图Buffer对象写入文件 console.log(`截图已保存为 ${filePath}。`); } catch (error) { // 输出错误信息文字 console.log(`截图失败:${error.message}`); } finally { await browser.close(); // 关闭浏览器 }
上面代码已经实现了将网页(包括Vue渲染的动态网页)截图保存到指定的本地目录下。并且此代码片段已经托管到GitHub平台,项目地址:https://github.com/RipperTs/dynamic-webpages
项目运行后会以接口的形式对外提供,查看接口文档说明
评论