TL;DR
無頭 Chrome 是 Chrome 59 的出貨服務。這是在無頭環境中執行 Chrome 瀏覽器的方式。 基本上,跑步 沒有 Chrome 的 Chrome!此方案提供所有現代化網路平台功能 由 Chromium 和 Blink 轉譯引擎導入指令列
為什麼這個實用?
使用無頭瀏覽器,就能夠在裝置上享有自動化測試和伺服器環境 就不需顯示可見的 UI 殼層舉例來說,假設您想針對 正確網頁、建立 PDF 檔,或檢查瀏覽器轉譯網址的方式。
開始無頭 (CLI)
如要開始使用無頭模式,最簡單的方法是開啟 Chrome 二進位檔
建立虛擬機器如果已安裝 Chrome 59 以上版本,請使用 --headless
標記啟動 Chrome:
chrome \
--headless \ # Runs Chrome in headless mode.
--disable-gpu \ # Temporarily needed if running on Windows.
--remote-debugging-port=9222 \
https://www.chromestatus.com # URL to open. Defaults to about:blank.
chrome
應指向安裝的 Chrome。確切位置會
每個平台都會有差異因為我是 Mac,我建立了方便的別名
各個版本的 Chrome 瀏覽器
如果您目前使用的是 Chrome 穩定版,無法取得測試版,建議您
使用 chrome-canary
:
alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"
alias chrome-canary="/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary"
alias chromium="/Applications/Chromium.app/Contents/MacOS/Chromium"
在這裡下載 Chrome Canary。
指令列功能
在某些情況下,您可能不需要透過程式指令碼執行 Headless Chrome。 我們提供了一些實用的指令列標記 執行常見工作
列印 DOM
--dump-dom
標記會將 document.body.innerHTML
列印至 stdout:
chrome --headless --disable-gpu --dump-dom https://www.chromestatus.com/
建立 PDF
--print-to-pdf
標記會建立頁面的 PDF 檔案:
chrome --headless --disable-gpu --print-to-pdf https://www.chromestatus.com/
擷取螢幕畫面
如要擷取網頁的螢幕截圖,請使用 --screenshot
標記:
chrome --headless --disable-gpu --screenshot https://www.chromestatus.com/
# Size of a standard letterhead.
chrome --headless --disable-gpu --screenshot --window-size=1280,1696 https://www.chromestatus.com/
# Nexus 5x
chrome --headless --disable-gpu --screenshot --window-size=412,732 https://www.chromestatus.com/
使用 --screenshot
執行,會在原始碼中產生名為 screenshot.png
的檔案
複製而來的檔案如果需要整頁的螢幕截圖
代表不同問題優質網誌
由 David Schnurr 張貼的貼文退房日
使用無頭 Chrome 做為自動化螢幕截圖工具 。
REPL 模式 (讀取-eval-print 迴圈)
--repl
標記會在您可以評估 JS 運算式的模式中執行 Headless
,請直接在指令列中:
$ chrome --headless --disable-gpu --repl --crash-dumps-dir=./tmp https://www.chromestatus.com/
[0608/112805.245285:INFO:headless_shell.cc(278)] Type a Javascript expression to evaluate or "quit" to exit.
>>> location.href
{"result":{"type":"string","value":"https://www.chromestatus.com/features"}}
>>> quit
$
不使用瀏覽器使用者介面對 Chrome 進行偵錯嗎?
透過 --remote-debugging-port=9222
執行 Chrome 時,系統會啟動執行個體
啟用開發人員工具通訊協定。
通訊協定的用途是與 Chrome 通訊
瀏覽器執行個體。Sublime、VS Code、Node 等工具
遠端偵錯應用程式#synergy
由於沒有瀏覽器 UI 可以查看相關網頁,因此請前往 http://localhost:9222
,檢查一切是否正常運作。您會看到
可檢查的可檢查網頁,查看哪些網頁是無頭介面轉譯:
您可以使用熟悉的開發人員工具功能來檢查、偵錯及調整 將頁面移除如果是透過程式輔助方式使用無頭介面,請按照下列步驟操作: 網頁也是強大的偵錯工具,可查看所有原始開發人員工具通訊協定 以便與瀏覽器通訊
透過程式輔助方式使用 (節點)
布偶操作員
Puppeteer 是節點程式庫 是由 Chrome 團隊負責開發並提供用於控制無頭 API 的高階 API (或完整版) Chrome。類似於 Phantom 等其他自動化測試程式庫 和 NightmareJS,但只能在最新版 Chrome 中運作。
除此之外,Puppeteer 還有許多其他用途 輕鬆拍攝螢幕截圖、建立 PDF 並擷取這些網頁的相關資訊。我推薦圖書館 ,輕鬆快速地自動執行瀏覽器測試。能隱藏 以及處理冗餘工作,例如啟動 Chrome 的偵錯執行個體。
安裝:
npm i --save puppeteer
範例 - 列印使用者代理程式
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch();
console.log(await browser.version());
await browser.close();
})();
例如:擷取頁面的螢幕截圖
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.chromestatus.com', {waitUntil: 'networkidle2'});
await page.pdf({path: 'page.pdf', format: 'A4'});
await browser.close();
})();
查看 Puppeteer 說明文件 。
CRI 程式庫
chrome-remote-interface 是比 Puppeteer API 低階的程式庫建議您可以 並直接使用開發人員工具通訊協定。
正在啟動 Chrome
chrome-remote-interface 不會為您啟動 Chrome,因此您必須 可以好好照顧自己
在 CLI 部分中,我們手動啟動 Chrome,使用的是
--headless --remote-debugging-port=9222
。然而,若要完全自動化測試
想要從您的應用程式中產生 Chrome。
其中一種方法是使用 child_process
:
const execFile = require('child_process').execFile;
function launchHeadlessChrome(url, callback) {
// Assuming MacOSx.
const CHROME = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome';
execFile(CHROME, ['--headless', '--disable-gpu', '--remote-debugging-port=9222', url], callback);
}
launchHeadlessChrome('https://www.chromestatus.com', (err, stdout, stderr) => {
...
});
但如果要一個適用於多種情境的可攜式解決方案,就變得不容易 平台。只要查看這個硬式編碼的 Chrome 路徑 :(
使用 ChromeLauncher
Lighthouse 是件令人驚嘆的
可測試網頁應用程式品質的工具強大的發布模組
Chrome 是在 Lighthouse 中開發的,現已解壓縮以供獨立使用。
chrome-launcher
NPM 模組
會在哪裡找到
已安裝 Chrome、設定偵錯執行個體、啟動瀏覽器並終止瀏覽器
程式執行完畢。最棒的是,跨平台支援
節點!
根據預設,如果 Chrome Canary,chrome-launcher
會嘗試啟動 Chrome Canary
),但你可以手動選取要使用的 Chrome。目的地:
的使用方式,請先從 npm 安裝:
npm i --save chrome-launcher
範例 - 使用 chrome-launcher
啟動 Headless
const chromeLauncher = require('chrome-launcher');
// Optional: set logging level of launcher to see its output.
// Install it using: npm i --save lighthouse-logger
// const log = require('lighthouse-logger');
// log.setLevel('info');
/**
* Launches a debugging instance of Chrome.
* @param {boolean=} headless True (default) launches Chrome in headless mode.
* False launches a full version of Chrome.
* @return {Promise<ChromeLauncher>}
*/
function launchChrome(headless=true) {
return chromeLauncher.launch({
// port: 9222, // Uncomment to force a specific port of your choice.
chromeFlags: [
'--window-size=412,732',
'--disable-gpu',
headless ? '--headless' : ''
]
});
}
launchChrome().then(chrome => {
console.log(`Chrome debuggable on port: ${chrome.port}`);
...
// chrome.kill();
});
執行這個指令碼不容易,但您應該會看到
Chrome 會在載入 about:blank
的工作管理員中啟動。別忘了,上面還有
不包含任何瀏覽器使用者介面我們不是頭緒。
如要控制瀏覽器,我們需要開發人員工具通訊協定!
擷取網頁相關資訊
請安裝程式庫:
npm i --save chrome-remote-interface
範例
範例 - 列印使用者代理程式
const CDP = require('chrome-remote-interface');
...
launchChrome().then(async chrome => {
const version = await CDP.Version({port: chrome.port});
console.log(version['User-Agent']);
});
結果如:HeadlessChrome/60.0.3082.0
範例:檢查網站是否有網頁應用程式資訊清單
const CDP = require('chrome-remote-interface');
...
(async function() {
const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});
// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const {Page} = protocol;
await Page.enable();
Page.navigate({url: 'https://www.chromestatus.com/'});
// Wait for window.onload before doing stuff.
Page.loadEventFired(async () => {
const manifest = await Page.getAppManifest();
if (manifest.url) {
console.log('Manifest: ' + manifest.url);
console.log(manifest.data);
} else {
console.log('Site has no app manifest');
}
protocol.close();
chrome.kill(); // Kill Chrome.
});
})();
範例 - 使用 DOM API 擷取網頁的 <title>
。
const CDP = require('chrome-remote-interface');
...
(async function() {
const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});
// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const {Page, Runtime} = protocol;
await Promise.all([Page.enable(), Runtime.enable()]);
Page.navigate({url: 'https://www.chromestatus.com/'});
// Wait for window.onload before doing stuff.
Page.loadEventFired(async () => {
const js = "document.querySelector('title').textContent";
// Evaluate the JS expression in the page.
const result = await Runtime.evaluate({expression: js});
console.log('Title of page: ' + result.result.value);
protocol.close();
chrome.kill(); // Kill Chrome.
});
})();
使用 Selenium、WebDriver 和 ChromeDriver
Selenium 現已開啟完整的 Chrome 執行個體。也就是 而非完全無頭不過,Selenium 則是 只需要稍微調整設定 就能執行無頭 Chrome我推薦 透過 Headless Chrome 執行 Selenium 體驗 如果你想 實際設定步驟的完整說明,不過, 範例,協助您快速上手。
使用 ChromeDriver
ChromeDriver 2.32 版 使用 Chrome 61,且能與無頭 Chrome 搭配使用。
安裝:
npm i --save-dev selenium-webdriver chromedriver
範例:
const fs = require('fs');
const webdriver = require('selenium-webdriver');
const chromedriver = require('chromedriver');
const chromeCapabilities = webdriver.Capabilities.chrome();
chromeCapabilities.set('chromeOptions', {args: ['--headless']});
const driver = new webdriver.Builder()
.forBrowser('chrome')
.withCapabilities(chromeCapabilities)
.build();
// Navigate to google.com, enter a search.
driver.get('https://www.google.com/');
driver.findElement({name: 'q'}).sendKeys('webdriver');
driver.findElement({name: 'btnG'}).click();
driver.wait(webdriver.until.titleIs('webdriver - Google Search'), 1000);
// Take screenshot of results page. Save to disk.
driver.takeScreenshot().then(base64png => {
fs.writeFileSync('screenshot.png', new Buffer(base64png, 'base64'));
});
driver.quit();
使用 WebDriverIO
WebDriverIO 是位於 Selenium WebDriver 之上的更高階 API。
安裝:
npm i --save-dev webdriverio chromedriver
例如:在 chromestatus.com 篩選 CSS 功能
const webdriverio = require('webdriverio');
const chromedriver = require('chromedriver');
const PORT = 9515;
chromedriver.start([
'--url-base=wd/hub',
`--port=${PORT}`,
'--verbose'
]);
(async () => {
const opts = {
port: PORT,
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: {args: ['--headless']}
}
};
const browser = webdriverio.remote(opts).init();
await browser.url('https://www.chromestatus.com/features');
const title = await browser.getTitle();
console.log(`Title: ${title}`);
await browser.waitForText('.num-features', 3000);
let numFeatures = await browser.getText('.num-features');
console.log(`Chrome has ${numFeatures} total features`);
await browser.setValue('input[type="search"]', 'CSS');
console.log('Filtering features...');
await browser.pause(1000);
numFeatures = await browser.getText('.num-features');
console.log(`Chrome has ${numFeatures} CSS features`);
const buffer = await browser.saveScreenshot('screenshot.png');
console.log('Saved screenshot...');
chromedriver.stop();
browser.end();
})();
其他資源
以下提供幾項實用資源,協助您快速上手:
文件
- 開發人員工具通訊協定檢視者 - API 參考文件
工具
- chrome-remote-interface - 節點 納入開發人員工具通訊協定的模組
- Lighthouse - 自動化測試工具 網頁應用程式品質;大量利用通訊協定
- chrome-launcher: 用於啟動 Chrome 並準備好自動化作業的節點模組
示範
- 「頭戴式網路」- Paul Kinlan 的優質網誌 以上文章說明如何使用 api.ai 來使用 Headless
常見問題
我需要 --disable-gpu
旗標嗎?
僅限 Windows。其他平台不再需要使用這項功能。--disable-gpu
旗標是
可暫時解決幾個錯誤在日後的
。詳情請參閱 crbug.com/737678
瞭解詳情
所以我還需要 Xvfb 嗎?
否。無頭 Chrome 不會使用視窗,因此像 Xvfb 的顯示伺服器是 。沒關係,也能輕鬆執行自動化測試。
Xvfb 是什麼?Xvfb 是一個記憶體內顯示伺服器,適用於類似 Unix 的系統,能讓您 執行圖形應用程式 (例如 Chrome),而無需連接實體螢幕。 許多人會使用 Xvfb 執行舊版 Chrome 來執行「無頭」工作進行測試。
如何建立執行 Headless Chrome 的 Docker 容器?
查看 lighthouse-ci。這個元件設有
Dockerfile 範例
使用 node:8-slim
做為基本映像檔,因此能安裝 +
執行 Lighthouse
。
這項服務可以搭配 Selenium / WebDriver / ChromeDriver 使用嗎?
可以。請參閱使用 Selenium、WebDriver 和 ChromeDriver。
這與 PhantomJS 有何關聯?
無頭 Chrome 與 PhantomJS 等工具類似。兩者皆有 可用於在無頭環境中自動執行測試。主要差異 兩者之間的差別在於 Phantom 使用舊版 WebKit 來呈現 引擎,而 Headless Chrome 使用最新版的 Blink。
目前 Phantom 提供的 API 級別比開發人員工具通訊協定來得高。
該到哪裡回報錯誤?
如果是針對 Headless Chrome 的錯誤,請前往 crbug.com 回報。
如果是開發人員工具通訊協定中的錯誤,請前往 github.com/ChromeDevTools/devtools-protocol 回報。