186
175

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ヘッドレス Chrome Node API 「Puppeteer」

Last updated at Posted at 2018-11-13

Puppeteer

Puppeteer は DevTools プロトコルでヘッドレス Chrome または Chromium を制御するための高水準 API を提供する Node ライブラリです。
ヘッドレスではないフルの Chrome または Chromium を使用することもできます。

インストール

Yarn

Puppeteer をインストールするために、JavaScript パッケージマネージャーのひとつである Yarn をインストールします。

macOS

brew install yarn

nvm を利用している場合は --without-node オプションを付けて Node.js の依存インストールを除外します。

Windows

cinst -y yarn

CentOS

curl --silent --location https://rpm.nodesource.com/setup_8.x | bash - && \
yum -y install nodejs gcc-c++ make yum-utils && \
yum-config-manager --add-repo https://dl.yarnpkg.com/rpm/yarn.repo && \
yum -y install yarn

Puppeteer

yarn add puppeteer

yarn コマンドで Puppeteer をインストールします。最新版の 1.3.0 がインストールされました。

mkdir -p Workspace/puppeteer && cd $_

ブラウザの起動 puppeteer.launch()

通常の起動

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = (await browser.pages())[0];
  await page.setViewport({ width, height });
  await page.goto('https://www.example.com');
})();

情報バーの非表示、ウィンドウの最大化、シークレットモードでの起動

const puppeteer = require('puppeteer');
const headless = false;
const slowMo = 10;
const width = 1280, height = 800;
const args = [
  '--start-fullscreen',
  '--disable-infobars',
  '--incognito',
];

(async () => {
 const browser = await puppeteer.launch({ headless, slowMo, args });
  const page = (await browser.pages())[0];
  await page.setViewport({ width, height });
  await page.goto('https://www.example.com');
})();

API

ブラウザの起動 puppeteer.launch

puppeteer.launch();
パラメータ 説明
headless ブラウザをヘッドレスモードで実行するかどうか。 devtools オプションが true でない限りデフォルトは true
slowMo Puppeteer の動作を指定されたミリ秒単位で遅らせる。何が起こっているかを見ることができて役に立つ。
devtools 各タブに DevTools パネルを自動的に開くかどうか。このオプションが true だと headless オプションは false に設定される。
dumpio ブラウザの process stdout と stderr を process.stdoutprocess.stderr にパイプするかどうか。デフォルトは false
timeout ブラウザインスタンスの開始を待つ最大時間(ミリ秒単位)。デフォルトは 30000 (30秒)。タイムアウトを無効にするには 0 を渡す。
args ブラウザインスタンスに渡す追加の引数。 Chromiumフラグの一覧はここで見られる。
List of Chromium Command Line Switches
オプション 説明
--no-startup-window 起動時にブラウザウィンドウを自動的に開かない(バックグラウンドアプリをホスティングする目的で Chrome を起動するときに使用される)
--no-referrers HTTP-Referer ヘッダーを送信しない
--incognito ブラウザをシークレットモードで直接起動する
--no-default-browser-check デフォルトのブラウザチェックを無効にする
デフォルトのブラウザ情報バーが表示されないようにするUI/ブラウザテストに役立つ
--hide-scrollbars スクリーンショットのスクロールバーを非表示にする
--disable-infobars 一時廃止された 1 が復活した 2
--enable-automation ユーザーにブラウザが自動テストによって制御されていることを通知する

ブラウザの終了 browser.close()

browser.close()

Chromium と開かれている場合はそのページすべてを閉じます。 Browser オブジェクト自体は破棄されたものとみなされ、もう使用できない。

フォーム入力

await page.type('input[name="id"]', 'joe');
await page.type('input[name="id"]', 'joe', {delay: 100});

フォーカス

let button = await page.focus('#login_button');

クリック

await page.click('#login_button');
let button = page.$('#login_button');
await button.click();

let items = await page.$$('#list .item');
let item = await items[2].$('.name');

querySelectorAll

スクリーンショット

await page.screenshot({path: 'screenshot_all.png'});
await let side_nav = page.$('#side_nav');
await side_nav.screenshot({path: 'screenshot_side_nav.png'});

value 値の取得

let login_id = await page.$eval('input[name="login_id"]', el => el.value);

テキストの取得

let text = await page.$eval('.classname', item => {return item.textContent;});

遷移待機

page.click('a[href="index.php"]');
await page.waitForNavigation({timeout: 60000, waitUntil: "domcontentloaded"});
await page.click('a[href="login.php"]');
await page.waitFor('a[href="mypage.php"]', {timeout: 120000});

プルダウンの選択

await page.select('select[name="color"]', 'red');
await page.select('select#colors', 'red', 'green', 'blue');

optionvaluered のものを選択する。
https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageselectselector-values

const scrapingData = await page.evaluate(() => {
    const dataList = [];
    const nodeList = document.querySelectorAll("td.date");
    nodeList.forEach(_node => {
        dataList.push(_node.innerText);
    })
    return dataList;
});

BASIC 認証

const user = 'user';
const pass = 'P@ssw0rd';
await page.setExtraHTTPHeaders({Authorization: `Basic ${new Buffer(`${user}:${pass}`).toString('base64')}`});

ページ遷移

await page.goto('https://example.com/', {waitUntil: 'domcontentloaded'});
let waitUntil = 'domcontentloaded';
await page.goto('https://example.com/', {waitUntil});

waitUntil

オプション 内容
load load イベントが発生するとナビゲーション完了と見なす。デフォルト値。
domcontentloaded DOMContentLoaded イベントが発生するとナビゲーション完了と見なす。
networkidle0 500ミリ秒間にネットワーク接続が0個以下であればナビゲーション完了と見なす。
networkidle2 500ミリ秒間にネットワーク接続が2個以下であればナビゲーション完了と見なす。
https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagegotourl-options

waitFor

waitForNavigation

await page.waitForNavigation({waitUntil:'domcontentloaded'});

waitForSelector

await page.waitForSelector('#contents');

waitForXPath

waitForFunction

スタイルシート操作

await page.evaluate(({}) => {$('#slider').css('display', 'block');},{});

ユーザーエージェントの指定

const userAgent = '';
page.setUserAgent(userAgent);

デバイスの指定

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone X'];

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.emulate(iPhone);
  // other actions...
});

使用可能なデバイスのリストは DeviceDescriptors.js で確認できる。

https://qiita.com/ukyo/items/287169de85576dfed608
https://qiita.com/tomi_shinwatec/items/a68cf7840c3da002c6e0

  1. https://chromium.googlesource.com/chromium/src/+/d869ab3350d8ebd95222b4a47adf87ce3d3214b1

  2. https://bugs.chromium.org/p/chromium/issues/detail?id=820453#c6

186
175
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
186
175

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?