1. 程式人生 > >強大的後臺截圖工具puppeteer,phantojs的替代品

強大的後臺截圖工具puppeteer,phantojs的替代品

背景

由於專案首頁上需要大量的圖表,大概超過100張複雜的圖表,複雜的圖表,並且有一個三維的地圖展示,這個對於瀏覽器展示的壓力非常大,測試時普通的機子都無法正常展示圖片。

環境

頁面上的圖表大部分都是基於Echarts圖表繪製的,有動效,最終繪製的圖片應該是canvas。
三維的地圖是用WebGl渲染的。針對這些圖,我們暫時處理辦法是把繪製圖表的圖表作為圖片來展示,減輕客戶端的壓力

OK,有思路了,接下來具體怎麼辦
尋找後臺可用的截圖工具

  1. phantomjs
  2. puppeteer
  3. html2canves
  4. html2image
  5. DJNativeSwing

功能比較

工具 優點 缺點 開發商
phantomjs phantom利用的是webKit核心,全面支援web而不需瀏覽器支援,快速,原生支援各種Web標準。 速度快,使用簡單。 現在這個專案屬於凍結狀態,無人維護,現在2.1版本不支援flex佈局,2.5只有beta版本的。這是官方的說法 Ariya Hidayat 兩名開發者
puppeteer 類似於PhantomJS,但Puppeteer是Chrome官方團隊進行維護的,前景更好 安裝過程中在國內需要依賴google的服務,可能無法訪問 谷歌官方
html2canves 前臺技術,實現比較容易。 無法後臺操作,對瀏覽器有要求 niklasvh
html2image 純java實現。 需要多執行緒的支援 niklasvh

綜合上面的比較和官方的示例,應該是phantomjs和puppeteer兩個方便使用下面來照著官方的示例簡單的寫一個
package.json

{
  "name": "demos",
"version": "0.0.1", "dependencies": { "capturejs": "^0.3.0", "debug": "~2.2.0", "puppeteer": "1.9.0", "qiniu": "^6.1.10", "system": "^1.0.4", "webpage": "^0.3.0" } }

截圖1080p的核心程式碼

const puppeteer = require('puppeteer');
(async () => {
    const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('http://echarts.baidu.com/examples/');
page.setViewport({width:1920*1,height:1080*1});
    let path = 'example.png';
    await page.screenshot({path: path,fullPage:true});
await browser.close();
})();

這麼設定後,初次下載還可以,後來把圖片的解析度設定為8k解析度,這時候有的截圖就沒有下載全
通過新增頁面載入完畢解決問題

const puppeteer = require('puppeteer');
(async () => {
    const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('http://echarts.baidu.com/examples/',{waitUntil :"load|domcontentloaded|networkidle2",timeout:300000});
page.setViewport({width:1920*1,height:1080*1});
    let path = 'example.png';
    await page.screenshot({path: path,fullPage:true});
await browser.close();
})();

後來發現截的圖跟預設的效果不一致,不是透明的,需要設定透明屬性,最終修改完畢如下

const puppeteer = require('puppeteer');
(async () => {
    const browser = await puppeteer.launch();
const page = await browser.newPage();
page._emulationManager._client.send(
            'Emulation.setDefaultBackgroundColorOverride',
            { color: { r: 0, g: 0, b: 0, a: 0 } }
        );
await page.goto('http://echarts.baidu.com/examples/',{waitUntil :"load|domcontentloaded|networkidle2",timeout:300000});
page.setViewport({width:1920*1,height:1080*1});
    let path = 'example.png';
    await page.screenshot({path: path,fullPage:true});
await browser.close();
})();

到此所有問題都已經解決