Puppeteer

Puppeteer:掌握無頭瀏覽器自動化的利器

2025-03-03

在現代網頁開發與測試的領域中,自動化工具扮演著不可或缺的角色。Puppeteer 作為 Google Chrome 團隊開發的 Node.js 函式庫,提供了一套高階 API 來控制 Chrome 或 Chromium 瀏覽器,成為許多開發者進行網頁爬蟲、自動化測試與生成預覽內容的首選工具。本文將介紹 Puppeteer 的技術特點、優勢,並特別探討其輕量化版本 puppeteer-core 的使用時機與基礎教學。

什麼是 Puppeteer?

Puppeteer 是一個 Node.js 函式庫,它透過 DevTools Protocol 來控制 Chrome 或 Chromium。預設情況下,Puppeteer 會在安裝時自動下載並安裝一個特定版本的 Chromium,以確保其 API 與瀏覽器版本的相容性。它既可以運行在「無頭模式」(Headless Mode,即無使用者介面),也可以配置為在完整的瀏覽器中執行。

Puppeteer 的主要優勢

相較於其他自動化工具(如 Selenium),Puppeteer 擁有以下幾個顯著特點:

  1. 原生支援與相容性:由於是由 Chrome 團隊維護,Puppeteer 對 Chrome 的新特性支援度極高,且運作穩定性通常優於第三方封裝的驅動程式。
  2. 安裝簡便npm install puppeteer 指令會自動處理 Chromium 的下載與設置,開發者無需手動配置驅動程式路徑即可立即開始使用。
  3. 效能優異:直接透過 DevTools Protocol 與瀏覽器通訊,減少了中間層的轉換消耗,執行速度通常較快。
  4. 功能豐富:除了基本的頁面操作(點擊、輸入),還支援截圖、生成 PDF、攔截網路請求、效能分析(Performance Timeline)、SPA(單頁應用)爬取等進階功能。

特別介紹:Puppeteer-core

在 Puppeteer 的生態系中,有一個名為 puppeteer-core 的套件,這是許多進階使用者或特定部署環境下的選擇。

什麼是 Puppeteer-core?

puppeteer-core 是 Puppeteer 的輕量版本。它與標準版 puppeteer 的主要區別在於:它不會自動下載 Chromium

為什麼選擇 Puppeteer-core?

  1. 節省空間與頻寬:標準版 Puppeteer 下載的 Chromium 大小約在 170MB 到 280MB 之間。在某些 CI/CD 環境、Docker 容器或對空間敏感的伺服器上,如果已經安裝了 Chrome,重複下載 Chromium 是資源浪費。
  2. 連接現有瀏覽器:如果你需要連接到遠端瀏覽器(Remote Browser)或本機已安裝的 Chrome/Edge,使用 puppeteer-core 即可,只需在啟動時指定 executablePath 或使用 browserWSEndpoint 進行連接。
  3. 版本控制:在某些企業環境中,瀏覽器版本由 IT部門統一管理,使用 puppeteer-core 可以確保自動化腳本運行在公司規範的瀏覽器版本上。

初步使用教學

以下將示範如何使用 Puppeteer 進行一個簡單的自動化任務:啟動瀏覽器、前往網頁、並進行截圖。

1. 安裝

如果你是初學者,建議直接安裝完整版:

pnpm install puppeteer

如果你確定環境中已有 Chrome,或想節省空間,可以安裝 core 版:

pnpm install puppeteer-core

2. 基本範例程式碼

這是一個使用標準 puppeteer 的範例。腳本會啟動一個無頭瀏覽器,導航到 Google 首頁,並將畫面存為 example.png

const puppeteer = require('puppeteer');

(async () => {
  // 啟動瀏覽器
  // headless: 'new' 是新版推薦的無頭模式設定
  const browser = await puppeteer.launch({ headless: 'new' });
  
  // 開啟新分頁
  const page = await browser.newPage();
  
  // 設定視窗大小
  await page.setViewport({ width: 1920, height: 1080 });

  // 前往目標網頁
  await page.goto('https://google.com');

  // 自訂操作:這裡示範等待一秒,確保頁面載入
  // 實務上多使用 waitForSelector 等待特定元素出現
  await new Promise(r => setTimeout(r, 1000));

  // 截圖
  await page.screenshot({ path: 'example.png' });

  // 關閉瀏覽器
  await browser.close();
})();

3. 使用 Puppeteer-core 的差異

若使用 puppeteer-core,你必須在 launch 方法中明確指定 executablePath(瀏覽器執行檔路徑) 與 channel(可選)。

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

(async () => {
  const browser = await puppeteer.launch({
    headless: 'new',
    // 必須指定執行檔路徑,以下為 macOS 範例
    executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', 
    channel: 'chrome' 
  });

  const page = await browser.newPage();
  await page.goto('https://google.com');
  await page.screenshot({ path: 'example-core.png' });
  await browser.close();
})();

結語

Puppeteer 以其強大的功能和簡單的 API,大幅降低了瀏覽器自動化的門檻。無論是進行端對端測試(E2E Testing)、生成報告 PDF,或是爬取動態渲染的網站內容,它都是極具效率的工具。對於需要更靈活部署或資源受限的環境,puppeteer-core 則提供了絕佳的輕量化解決方案。掌握這項技術,將能讓你在處理網頁相關的自動化任務時更加得心應手。