本文适用于对docker,node有必定了解的童鞋node
今年5月在github上建立的项目,属于比较新的chromium无头浏览器类库。git
选用Puppeteer的主要缘由有两点,github
0.13.0
,咱们采用0.12.0
版本,因0.13.0
版本API作了一些变化没法知足咱们的需求。咱们截图时有以下两个必须解决的场景
npm安装puppeteer时会从google一个网站上下载chromium,由于墙的缘由会下载失败。咱们采用的方式先设置环境变量chrome
set PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
复制代码
阻止install的时候自动下载,而后手工下载chromium后经过docker build打包成一个基础镜像。咱们在Dockerfile中From此镜像,而后再作后续操做。docker
npm instal puppeteer@0.12.0 --save
复制代码
如今可经过docker很快速的进行打包。最终打包后的image里/usr/src/node/包含node代码及chromium目录npm
咱们手动指定chromium目录来运行。api
const browser = await puppteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox'], // docker中运行须要加上这两个args
executablePath: 'chromium/chrome', // 基础镜像已将chromium复制到/usr/src/node/chromium目录下
});
复制代码
经过URL打开网站浏览器
await page.goto(fullUrl, {
waitUntil: 'networkidle',
networkIdleTimeout: 15000,
timeout: 240000
});
复制代码
networkIdleTimeout: 15000
参数表明当前页面网络处于idle状态至少15秒
时导航完毕,避免导出的截图数据不全。
若是直接保存整个页面为图片或PDF是很简单的,有现成的API直接调用。但此次咱们只将某一区域保存为图片,网络
let rect = await page.evaluate(() => {
const element = document.querySelector(
'.class1'
); // 选择包含指定class属性的dom节点
const { x, y, width, height } = element.getBoundingClientRect();
return {
left: x,
top: y,
width,
height,
};
});
await page.screenshot({
path: imagePath,
clip: {
x: rect.x,
y: rect.y,
width: actualWidth,
height: actualHeight
}
});
复制代码
能够在page.evaluate中操做页面元素,因此能够获取指定区域的长宽等信息。这样咱们只需截取那一区域便可。完整的API地址仍是请参阅github官方API文档dom
如上节所说,若是保存整个页面为PDF很简单,由于咱们只保存某一区域,然而保存pdf的API中没有相似page.screenshot中clip参数,个人处理方式就是将上一步保存的图片转为PDF便可。转换方式不少,我采用pdfkit
类库实现。代码就不赘述,能够参考不少DEMO。
由于咱们经过docker+CICD+devops打包部署node服务,puppeteer在docker中也有一些坑,好在官方给出了一系列解决方案。我在实际使用中仍是偶尔发生页面加载失败的状况,指望在将来版本会变得更增强大和稳定。