Chrome 無頭模式

Mathias Bynens
Mathias Bynens
Peter Kvitek
Peter Kvitek

Chrome 59 在 2017 年推出無頭模式,讓您能在無人看管的環境中執行瀏覽器,而不會看到任何可見的 UI。也就是說,即使沒有 Chrome,也可以執行 Chrome。

透過 PuppeteerChromeDriver 等專案,無頭模式是瀏覽器自動化的熱門選擇。以下是使用無頭模式的基本指令列範例,為指定網址建立 PDF 檔案:

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

無頭介面的運作方式

在探討 Headless 的運作方式之前,建議您先瞭解「舊的」頭戴式運作方式。先前的指令列程式碼片段使用 --headless 指令列旗標,表明 Headless 只是一般 Chrome 瀏覽器的運作模式。但出乎意料,這並不正確。 事實上,舊的 Headless 是獨立的替代瀏覽器實作項目,原本是同一個 Chrome 二進位檔的一部分。也不會分享 //chrome 中的任何 Chrome 瀏覽器程式碼。

實作及維護獨立的 Headless 瀏覽器會帶來大量工程負擔。此外,Headless 是一項獨立的實作,因此有專屬的錯誤和功能,無法在頭版 Chrome 中呈現。這會造成自動化瀏覽器測試出現混淆,這類測試可能會在無頭模式下傳入,但在無頭模式下失敗,甚至反過來。

此外,「無頭」也排除了任何仰賴瀏覽器擴充功能安裝的自動化測試。其他瀏覽器層級函式也是如此;除非 Headless 另外有獨立的實作,否則不受支援。

Chrome 團隊現已整合無頭和頭版模式。

新版 Chrome Headless 不再是獨立的瀏覽器實作方式,現在會改為與 Chrome 共用程式碼。

新的無頭模式自 Chrome 112 起推出。在這個模式下,Chrome 會建立 但不會顯示任何平台視窗所有其他函式 (現有和未來) 均可使用,沒有限制。

使用無頭模式

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

chrome --headless=new

目前,下列使用者仍可使用舊的無頭模式:

chrome --headless=old

在 Puppeteer 中

如何在 Puppeteer 中啟用新的無頭模式:

import puppeteer from 'puppeteer';

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

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

// …

await browser.close();

Selenium-WebDriver 中

如何在 Selenium-WebDriver 中使用新的無頭模式:

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

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

// …

await driver.quit();

如需詳細資訊,包括使用其他語言繫結的範例,請參閱參議院團隊的網誌文章

指令列旗標

全新「無頭」模式提供下列指令列旗標。

--dump-dom

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

chrome --headless=new --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=new --screenshot --window-size=412,892 https://developer.chrome.com/

--print-to-pdf

--print-to-pdf 標記會將目標頁面以名為 output.pdf 的 PDF 格式儲存在目前的工作目錄中。例如:

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

您可以選擇新增 --no-pdf-header-footer 標記,藉此省略列印標頭 (包含目前的日期和時間) 和頁尾 (包含網址和頁碼)。

chrome --headless=new --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=new --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 秒後「2」等。 如果要在 42 秒後擷取網頁狀態並儲存為 PDF 檔,方法如下:

chrome --headless=new --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=new --print-to-pdf --allow-chrome-scheme-url chrome://gpu

偵錯

由於 Chrome 在無頭模式下會確實隱藏,因此解決問題可能並不容易。您可以透過與有頭 Chrome 類似的方式,對 Headless Chrome 偵錯。

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

chrome --headless=new --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,然後點選「Configure...」按鈕。
  2. 輸入 WebSocket 網址中的 IP 位址和通訊埠號碼。
    • 在上一個範例中,我輸入了 127.0.0.1:60926
  3. 按一下 [完成]。您應該會看見一個遠端目標,其中列出了其所有分頁和其他目標。
  4. 按一下「檢查」即可存取 Chrome 開發人員工具,並檢查遠端無頭目標,包括網頁的即時檢視畫面。

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

意見回饋:

我們希望能聽聽您對新的無頭模式的意見。如果遇到任何問題,請回報錯誤