本文適用於對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中也有一些坑,好在官方給出了一系列解決方案。我在實際使用中仍是偶爾發生頁面加載失敗的狀況,指望在將來版本會變得更增強大和穩定。