Chrome 無頭模式

Mathias Bynens
Mathias Bynens
Peter Kvitek
Peter Kvitek

透過 Chrome 無頭模式,您可以在無人監管的環境中執行瀏覽器,且不會顯示任何 UI。也就是說,您可以在沒有 Chrome 的情況下執行 Chrome。

無頭模式是瀏覽器自動化的熱門選擇,例如透過 PuppeteerChromeDriver 等專案。

使用無頭模式

如要使用無頭模式,請傳遞 --headless 指令列標記:

chrome --headless

使用舊版無頭模式

先前,無頭模式是獨立的替代瀏覽器實作項目,與 Chrome 二進位檔一併發布。並未分享任何 Chrome 瀏覽器程式碼 //chrome

Chrome 現在提供統一的無頭和有頭模式。

無頭模式會與 Chrome 共用程式碼。

自 Chrome 132.0.6793.0 起,舊版無頭模式僅適用於名為 chrome-headless-shell獨立二進位檔,可在此下載

在 Puppeteer 中

如要在 Puppeteer 中使用無頭模式,請按照下列步驟操作:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  headless: true,  // (default) enables Chrome Headless mode
  // `headless: 'shell'` enables Headless Shell (old headless)
  // `headless: false` enables "headful" mode
});

const page = await browser.newPage();
await page.goto('https://developer.chrome.com/');

// …

await browser.close();

如要進一步瞭解如何在 Puppeteer 中使用 Headless,請參閱這裡的資源。

在 Selenium-WebDriver 中

如要在 Selenium-WebDriver 中使用無頭模式,請按照下列步驟操作:

const driver = await env
  .builder()
  .setChromeOptions(options.addArguments('--headless'))
  .build();

await driver.get('https://developer.chrome.com/');

// …

await driver.quit();

如要瞭解詳情 (包括使用其他語言繫結的範例),請參閱 Selenium 團隊的網誌文章

指令列旗標

無頭模式和無頭 Shell 提供下列指令列旗標。

--dump-dom

--dump-dom 旗標會將目標網頁的序列化 DOM 列印至 stdout。例如:

chrome --headless --dump-dom https://developer.chrome.com/

這與列印 HTML 原始碼不同,後者可透過 curl 達成。為了提供 --dump-dom 的輸出內容,Chrome 會先將 HTML 程式碼剖析為 DOM,執行可能變更 DOM 的任何 <script>,然後將該 DOM 轉換回 HTML 的序列化字串。

--screenshot

--screenshot 標記會擷取目標網頁的螢幕截圖,並以 screenshot.png 格式儲存在目前的工作目錄中。與 --window-size 旗標搭配使用時,這個旗標會顯得格外實用。

例如:

chrome --headless --screenshot --window-size=412,892 https://developer.chrome.com/

--print-to-pdf

--print-to-pdf 標記會將目標網頁儲存為 PDF,並在目前的工作目錄中命名為 output.pdf。例如:

chrome --headless --print-to-pdf https://developer.chrome.com/

您可以視需要新增 --no-pdf-header-footer 旗標,省略列印頁首 (包含目前日期和時間) 和頁尾 (包含網址和頁碼)。

chrome --headless --print-to-pdf --no-pdf-header-footer https://developer.chrome.com/

注意:--no-pdf-header-footer 旗標背後的功能先前可透過 --print-to-pdf-no-header 旗標使用。如果使用舊版,可能需要改回舊的旗標名稱。

--timeout

--timeout 旗標會定義最長等待時間 (以毫秒為單位),之後即使網頁仍在載入,--dump-dom--screenshot--print-to-pdf 也會擷取網頁內容。

chrome --headless --print-to-pdf --timeout=5000 https://developer.chrome.com/

--timeout=5000 旗標會告知 Chrome 等待最多 5 秒,再列印 PDF。因此,這項程序最多需要 5 秒才能完成。

--virtual-time-budget

--virtual-time-budget 可做為任何時間相關程式碼 (例如 setTimeout/setInterval) 的「快轉」功能,強制瀏覽器盡快執行網頁的任何程式碼,同時讓網頁認為時間確實流逝。

為說明其用途,請參考這個示範,其中每秒會遞增、記錄及顯示計數器,並使用 setTimeout(fn, 1000)。相關程式碼如下:

<output>0</output>
<script>
  const element = document.querySelector('output');
  let counter = 0;
  setInterval(() => {
    counter++;
    console.log(counter);
    element.textContent = counter;
  }, 1_000);
</script>

一秒後,網頁會顯示「1」;兩秒後顯示「2」,依此類推。 以下說明如何擷取 42 秒後的頁面狀態,並儲存為 PDF 檔:

chrome --headless --print-to-pdf --virtual-time-budget=42000 https://mathiasbynens.be/demo/time

--allow-chrome-scheme-url

如要存取 chrome:// 網址,必須使用 --allow-chrome-scheme-url 旗標。 這個旗標自 Chrome 123 版起開放使用。範例如下:

chrome --headless --print-to-pdf --allow-chrome-scheme-url chrome://gpu

偵錯

由於 Chrome 在無頭模式下實際上是隱藏的,因此解決問題可能聽起來很棘手。您可以使用與有頭 Chrome 非常類似的方式,偵錯 Headless Chrome。

使用 --remote-debugging-port 指令列旗標,以無頭模式啟動 Chrome。

chrome --headless --remote-debugging-port=0 https://developer.chrome.com/

這會將專屬的 WebSocket 網址列印到 stdout,例如:

DevTools listening on ws://127.0.0.1:60926/devtools/browser/b4bd6eaa-b7c8-4319-8212-225097472fd9

在有頭 Chrome 執行個體中,我們可以使用 Chrome 開發人員工具遠端偵錯,連線至無頭目標並檢查。

  1. 前往 chrome://inspect,然後按一下「設定…」按鈕。
  2. 輸入 WebSocket 網址中的 IP 位址和通訊埠號碼。
    • 在先前的範例中,我輸入了 127.0.0.1:60926
  3. 按一下「完成」,您應該會看到「遠端目標」,以及列出的所有其他目標和分頁。
  4. 按一下「檢查」即可存取 Chrome 開發人員工具,並檢查遠端無頭目標,包括網頁的即時檢視畫面。

Chrome 開發人員工具可以檢查遠端無頭目標網頁

意見回饋

期待收到您對無頭模式的意見回饋。如果遇到任何問題,請回報錯誤