透過 Chrome 無頭模式,您可以在無人值守的環境中執行瀏覽器,且不必顯示任何 UI。也就是說,即使不安裝 Chrome,也能執行 Chrome。
在 Puppeteer 或 ChromeDriver 等專案中,無頭模式是瀏覽器自動化功能的熱門選擇。
使用無頭模式
如要使用無頭模式,請傳遞 --headless
指令列標記:
chrome --headless
使用舊的無頭模式
以前無頭模式是獨立的替代瀏覽器實作,原本是同一個 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 最多等待 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 --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 網址輸出至 stdout,例如:
DevTools listening on ws://127.0.0.1:60926/devtools/browser/b4bd6eaa-b7c8-4319-8212-225097472fd9
接著,我們可以在有標頭的 Chrome 例項中使用 Chrome 開發人員工具遠端偵錯功能,連線至無頭目標並進行檢查。
- 前往
chrome://inspect
,然後按一下「設定」按鈕。 - 輸入 WebSocket 網址中的 IP 位址和通訊埠號碼。
- 在上一個範例中,我輸入了
127.0.0.1:60926
,
- 在上一個範例中,我輸入了
- 按一下「完成」,您應該會看見一個遠端目標,其中列出了其所有分頁和其他目標。
- 按一下「檢查」即可存取 Chrome 開發人員工具,並檢查遠端無頭目標,包括網頁的即時檢視畫面。
意見回饋
我們希望能聽聽您對無頭模式的寶貴意見。如果遇到任何問題,請回報錯誤。