天天看點

PhantomJS替代品Puppeteer火了!Puppeteer-Core是什麼?

作者:進階前端進階

大家好,很高興又見面了,我是"進階前端進階",由我帶着大家一起關注前端前沿、深入前端底層技術,大家一起進步,也歡迎大家關注、點贊、收藏、轉發!

PhantomJS替代品Puppeteer火了!Puppeteer-Core是什麼?

進階前端進階

前言

最近在研究将 DOM 内容轉化為圖檔的方法,嘗試過 phantomJs、webshot、html2canvas、dom-to-image 等諸多方案,但是遇到的問題一個比一個多。比如常見的:背景圖無法渲染到最終生成的圖檔上、絕對定位的限制、圖檔尺寸的限制等等。幸運的是最終遇到了 Puppeteer 這個庫,本地測試了一下,發現和預期非常契合。是以書寫此文,将這個好東西分享給大家。

1.Puppeteer 取代 phantomJs

以前用過 phantomJs,研究幾天後發現 phantomJs 雖然在業内有一定的影響力,但後繼乏力,主要還是缺乏維護人員,導緻項目依賴的 chrome 核心版本太低,無人解決的 BUG 太多,現在已經越來越滿足不了真實的前端模拟以及各種新的特性需求(比如高版本 Chrome 的執行環境特性,比如 JS 執行和渲染等都相差很大)。

PhantomJS替代品Puppeteer火了!Puppeteer-Core是什麼?

圖檔來自:Marko Anastasov

谷歌浏覽器在 17 年開發了 Chrome Headless 特性,并同時推出了 puppeteer,可以了解成日常使用的 Chrome 的無界面版本以及對其進行操控的 js 接口套裝。 借助 puppeteer,實際上是通過調用 Chrome DevTools 開放的接口與 Chrome 通信,Chrome DevTools 的接口很複雜,但 puppeteer 對其進行了封裝,開發者調用起來還是很友善的。

2.puppeteer vs. puppeteer-core

自 v1.7.0 以後的每個版本,puppeteer 團隊都會釋出兩個軟體包,分别為 puppeteer 和 puppeteer-core,兩者的使用場景有明顯的差異。

puppeteer

puppeteer 是用于浏覽器自動化的産品。安裝後,它将下載下傳一個版本的 Chromium, 然後使用 puppeteer-core 驅動。

作為最終使用者産品,puppeteer 支援大量友善的 PUPPETEER _ * env 變量來調整其預設行為。

puppeteer-core

puppeteer-core 是一個庫,可以幫助驅動任何支援 DevTools 協定的産品。 安裝了 puppeteer-core 不會自動下載下傳 Chromium。 作為庫,puppeteer-core 是通過程式設計接口完成驅動的,而忽略所有 PUPPETEER_ * env 變量。

puppeteer 和 puppeteer-core 異同

puppeteer-core 和 puppeteer 之間的差別主要包括以下兩個:

  • puppeteer-core 在安裝後不會自動下載下傳 Chromium。
  • puppeteer-core 忽略所有 PUPPETEER _ * env 變量。

在大多數情況下,開發者直接使用 puppeteer 包即可。不過,如果想在 DevTools 協定的基礎上建構另一個終端使用者産品或庫,則應該使用 puppeteer-core。比如:

  • 使用 puppeteer-core 建構一個 PDF 生成器,然後編寫一個自定義的 install.js 腳本,下載下傳 headless_shell 而不是 Chromium 來節省磁盤空間。
  • 将 Puppeteer 打包在 Chrome 插件 / 浏覽器中使用 DevTools 協定,在這裡不需要下載下傳額外的 Chromium 二進制檔案。
  • 建構一套工具,其中 puppeteer-core 是核心組成,并且希望将 install.js 腳本的執行推遲到即将使用 Chromium 之前。

3.使用 puppeteer-core

使用 puppeteer-core 時,需要首先導入它:

const puppeteer = require('puppeteer-core');           

然後,需要使用時顯式調用 puppeteer.connect([options])或 puppeteer.launch([options])。下面的示例首先打開 google 官網,然後使用 puppeteer 進行截圖操作。

const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
// 啟動Chrome執行個體
const page = await browser.newPage();
// 建立page執行個體
await page.goto('https://google.com');
//打開頁面位址
await page.screenshot({ path: 'google.png' });
// 頁面截圖
await browser.close();
//關閉浏覽器           

以下示例在 developer.chrome.com 中搜尋帶有文本“automate beyond recorder”的博文,單擊第一個結果并列印博文的完整标題。

import puppeteer from 'puppeteer';

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://developer.chrome.com/');
  // 設定螢幕尺寸
  await page.setViewport({width: 1080, height: 1024});
  // 在搜尋框中輸入内容
  await page.type('.search-box__input', 'automate beyond recorder');
  // 等待并點選第一個結果
  const searchResultSelector = '.search-box__link';
  await page.waitForSelector(searchResultSelector);
  await page.click(searchResultSelector);
  // 使用唯一字元串找到完整标題
  const textSelector = await page.waitForSelector(
    'text/Customize and automate'
  );
  const fullTitle = await textSelector.evaluate(el => el.textContent);
  // 列印完整标題
  console.log('The title of this blog post is "%s".', fullTitle);
  await browser.close();
})();           

3.puppeteer vs. puppeteer-core 資料對比

目前 puppeteer 在 Github 上有 88.2k 的 star,8.8K 的 fork,有超過 370K 的項目使用它。同時對比過去一年 puppeteer vs. puppeteer-core 的下載下傳資料,如下圖所示,兩者幾乎都處于同步上升狀态。

PhantomJS替代品Puppeteer火了!Puppeteer-Core是什麼?

根據 NPM 的最新下載下傳資料,puppeteer 的周平均下載下傳量大約 3960K,而 puppeteer-core 的周平均下載下傳量大約為 3271K,兩者不分伯仲。是以,開發者可以根據自己的需求來選擇到底使用哪一個庫。在文章前面部分還提到過 phantomjs,我們将三者放在一起來看,如下圖所示:

PhantomJS替代品Puppeteer火了!Puppeteer-Core是什麼?

總體來看,phantomjs 在 puppeteer、puppeteer-core 之間幾乎毫無競争優勢。當然,資料隻是代表過去一年的時間,考慮到 phantomjs 項目的諸多問題,比如不再維護,衰減也在情理之中,但是可以确信的是 phantomjs 曾經也瘋狂過。

4.本文總結

本文主要和大家介紹PhantomJS的替代品Puppeteer,同時和Puppeteer-Core進行了對比,講述了為什麼會有Puppeteer-Core的存在。因為篇幅有限,文章并沒有過多展開,如果有興趣,文末的參考資料提供了優秀文檔以供學習。最後,歡迎大家點贊、評論、轉發、收藏!

參考資料

https://learnku.com/docs/puppeteer/3.1.0/puppeteer-vs-puppeteer-core/8538

https://codeburst.io/a-guide-to-automating-scraping-the-web-with-javascript-chrome-puppeteer-node-js-b18efb9e9921

https://learnku.com/f2e/t/44845#94a9d3

https://github.com/ariya/phantomjs

https://www.jianshu.com/p/56babda610f9

https://www.educative.io/answers/puppeteer-vs-puppeteer-core

https://semaphoreci.com/blog/2018/03/27/phantomjs-is-dead-use-chrome-headless-in-continuous-integration.html

封面圖檔:來自作者“Sam Crowther”的文章:https://www.kasada.io/what-is-puppeteer-developers-fraudsters-love-it/