Chrome 無頭模式

Mathias Bynens
Mathias Bynens
Peter Kvitek
Peter Kvitek

透過 Chrome 無頭模式,您可以在無人值守的環境中執行瀏覽器,且不必顯示任何 UI。基本上,您可以不使用 chrome 執行 Chrome。

無頭模式是瀏覽器自動化功能的熱門選擇,可透過 PuppeteerChromeDriver 等專案使用。

使用無頭模式

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

chrome --headless

使用舊版無頭模式

先前,無頭模式是獨立的替代瀏覽器實作,剛好是同一個 Chrome 二進位檔的一部分。不會在 //chrome 中分享任何 Chrome 瀏覽器程式碼。

Chrome 現已統一無頭模式和有頭模式。

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

目前,舊版無頭模式仍可搭配以下項目使用:

chrome --headless=old

在 Puppeteer 中

如何在 Puppeteer 中使用無頭模式:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  headless: 'true', // (default) enables Headless
  // `headless: 'old'` enables old 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'))
  .build();

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

// …

await driver.quit();

詳情請參閱 Selenium 團隊的網誌文章,其中包含使用其他語言繫結的範例。

指令列旗標

下列指令列旗標可在無頭模式中使用。

--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 標記會將目標頁面儲存為名為 output.pdf 的 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 在列印 PDF 前等待最多 5 秒。因此,這項程序最多需要 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

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

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

偵錯

由於 Chrome 在無頭模式下實際上是不可見的,因此解決問題可能會比較棘手。您可以以與有頭 Chrome 非常相似的方式對無頭 Chrome 進行偵錯。

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

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

這會將不重複的 WebSocket 網址輸出至標準輸出,例如:

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 開發人員工具可檢查遠端無頭目標網頁

意見回饋

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