ヘッドレス Chrome スタートガイド

要約

ヘッドレス Chrome Chrome 59 でリリースされますChrome ブラウザをヘッドレス環境で実行する方法です。 基本的に Chrome なしで Chrome をご利用いただけます。Google が提供する最新のウェブ プラットフォーム機能をすべて使用可能 をコマンドラインに追加することもできます。

なぜこれが有用なのでしょうか

ヘッドレス ブラウザは、自動化されたテストやサーバー環境に最適なツールです。 表示する UI シェルは不要です。たとえば、特定の環境に対する PDF を作成することも、ブラウザで URL がどのようにレンダリングされるのかを調べることもできます。

Headless(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 の Stable チャンネルでベータ版を入手できない場合は、以下の方法をおすすめします。 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 はこちらからダウンロードしてください。

コマンドライン機能

ヘッドレス 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 モード(read-eval-print ループ)

--repl フラグは、JS 式を評価できるモードでヘッドレスを実行します。 できます。コマンドラインから直接操作できます。

$ 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
$

ブラウザ UI を使用せずに Chrome をデバッグする場合は、

--remote-debugging-port=9222 を指定して Chrome を実行すると、インスタンスが起動します。 DevTools プロトコルを有効にします。「 プロトコルを使用して Chrome と通信し、 作成します。Sublime、VS Code、Node のようなツールで アプリケーションのリモート デバッグを行うときに使用します。#synergy

ページを表示するためのブラウザ UI がないため、http://localhost:9222 に移動します 別のブラウザで、すべてが機能していることを確認します。診断結果の一覧が クリックして、ヘッドレスがレンダリングする内容を確認できる検査可能なページです。

<ph type="x-smartling-placeholder">
</ph> DevTools リモート <ph type="x-smartling-placeholder">
</ph> DevTools リモート デバッグ UI
をご覧ください。

ここから、使い慣れた DevTools の機能を使用して、検査、デバッグ、微調整を行うことができます。 通常どおりページを表示できますヘッドレスをプログラムで使用する場合は、 ページは、すべての未加工の DevTools プロトコルを ブラウザと通信します

プログラムによる使用(ノード)

操り人形師

Puppeteer は Node ライブラリです。 独自の ML モデルを構築しますヘッドレス制御用の高レベル API と (またはフル)の Chrome。Phantom などの他の自動テスト ライブラリに似ています。 NightmareJS ですが、最新版の Chrome でのみ動作します。

特に、Puppeteer を使用すると、スクリーンショットの撮影、PDF の作成、 ページ間を移動したり、それらのページに関する情報を取得したりします。私がおすすめするライブラリは を使用すると、ブラウザのテストを迅速に自動化できます。複雑さが軽減され、 Pod の起動など、冗長なタスクを処理します。 作成します。

インストールします。

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 よりも下位レベルのライブラリです。もしお望みであれば DevTools プロトコルを直接使用します。

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 の使用

素晴らしい灯台 ウェブアプリの品質をテストするためのツールです。Google Cloud リソースを Chrome は Lighthouse 内で開発され、現在はスタンドアロンで使用するために抽出されています。 chrome-launcher NPM モジュール どこにあるかを見つける Chrome がインストールされ、デバッグ インスタンスが設定され、ブラウザが起動して強制終了される 初期化します。最大のメリットは クロスプラットフォームで 機能する点です ノード!

デフォルトでは、chrome-launcher は Chrome Canary の起動を試行します( インストールされていますが、これを変更して、使用する Chrome を手動で選択することもできます。宛先 まず、npm からインストールします。

npm i --save chrome-launcher

- chrome-launcher を使用してヘッドレスを起動する

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();
});

このスクリプトを実行しても何も起こりませんが、 about:blank を読み込んだタスク マネージャーで Chrome が起動します。覚えておいてください。 ブラウザの UI ではありませんヘッドレスだよ。

ブラウザを制御するには、DevTools プロトコルが必要です。

ページに関する情報の取得

ライブラリをインストールしましょう。

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 を実行できます。おすすめ ヘッドレス 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();

})();

その他のリソース

始めるにあたって役立つリソースをいくつかご紹介します。

ドキュメント

ツール

  • chrome-remote-interface - ノード これは、DevTools プロトコルをラップする
  • Lighthouse - テストの自動化ツール ウェブアプリの品質プロトコルを多用する
  • chrome-launcher - 自動化が可能な Chrome を起動するためのノード モジュール

デモ

  • The Headless Web」- Paul Kinlan の素晴らしいブログ api.ai でのヘッドレスの使用に関する投稿。

よくある質問

--disable-gpu フラグは必要ですか?

Windows でのみ発生します。他のプラットフォームでは不要です。--disable-gpu フラグは、 いくつかのバグについて 一時的な回避策を講じましたこのフラグは、 Chrome。crbug.com/737678 をご覧ください。 をご覧ください。

Xvfb は必要ですか?

いいえ。ヘッドレス Chrome はウィンドウを使用しないため、Xvfb などのディスプレイ サーバーは 不要になりました特に指定しなくても自動テストを実行できます。

Xvfb とは何ですか?Xvfb は Unix 系のシステム向けのインメモリ ディスプレイ サーバーで、 物理ディスプレイを接続せずにグラフィカル アプリケーション(Chrome など)を実行できます。 多くの人が Xvfb を使用して以前のバージョンの Chrome を実行し、「ヘッドレス」を行っている説明します。

ヘッドレス Chrome を実行する Docker コンテナを作成するにはどうすればよいですか?

lighthouse-ci を確認します。機能 サンプル Dockerfile node:8-slim をベースイメージとして使用し、インストール + Lighthouse を実行 App Engine フレキシブル環境で動作します

Selenium、WebDriver、ChromeDriver で使用できますか?

はい。Selenium、WebDriver、ChromeDriver を使用するをご覧ください。

これは PhantomJS とどのように関連していますか?

ヘッドレス Chrome は PhantomJS などのツールに似ています。両方 ヘッドレス環境での自動テストに使用できます。主な違いは、 Phantom は古いバージョンの WebKit をレンダリングに使用しています。 ヘッドレス Chrome では Blink の最新バージョンが使用されます。

現時点では、DevTools プロトコルよりも上位の API も提供されています。

バグはどこに報告すればよいですか?

ヘッドレス Chrome に関するバグについては、crbug.com で報告してください。

DevTools プロトコルのバグについては、github.com/ChromeDevTools/devtools-protocol で報告してください。