Node.jsライブラリのPuppeteerでスクショしてみた


業務でNode.jsライブラリのPuppeteerが中心的な役割の部分を触っているのでその学習の為に導入して動かしてみようと思いました。

Puppeteerとは?

公式サイト:https://pptr.dev/
パペティアと読みます。Node.jsライブラリで、Google製。
GoogleのWebブラウザ「Chrome」は、UIを持たずコマンドラインやリモートデバッグ機能を通じてWebブラウザを操作できる「Headless Chrome」機能を備えています。Headless Chromeを利用すると人間がWebブラウザをマウスやキーボードで操作することなく、プログラムでHeadless Chromeを起動し、特定のWebページを読み込み、画面キャプチャの取得や、指定された場所をクリックし、値を入力し結果を取得する、といった操作を自動的に行わせることができるようになります。

UIの自動テストとか、スクレイピングなどでも使えて汎用性が高いのですが、この記事ではあくまでもスクショ機能だけを触れていきます。

導入

早速動かしてみましょう、適当に作業ディレクトリを作って、以下のどちらかのコマンドでPuppeteerをインストールします。

npm i puppeteer
or
yarn add puppeteer

まずは公式ドキュメントに載ってる超基本のコードでスクショしてみましょう。
example.jsというファイルに以下のコードを書きます。

const puppeteer = require('puppeteer');

(async () => {
  //ヘッドレスブラウザの起動
  const browser = await puppeteer.launch();
  //タブを開く
  const page = await browser.newPage();
  //指定したURLに遷移
  await page.goto('https://qiita.com/hisashi_matsui');
  //スクショを撮り、ファイル名example.pngにする。
  await page.screenshot({ path: 'example.png' });
  //終了
  await browser.close();
})();

実行します

node example.js

するとルート直下にスクショのPNGファイルが保存されます!

これだけだと、あくまでも基本中の基本なので、もう少しカスタマイズしていきましょう。

ブラウザのサイズを設定
デフォルトだと800 × 600になります。

setViewPort({
  width: 1900,
  height: 1200
})

evaluateメソッド
これを使うと、Nodeではなくブラウザ上(Headless Chrome)でJavaScriptを実行できます。Puppeteerが提供していない高度な処理が必要な場合や、Webページに埋め込まれたJavaScriptを実行する場合などに使用します。

const docTitle = await page.evaluate(() => {
  return document.title
});

console.log(docTitle)
//このコンソールは当然コマンド上に出力されます

第一引数内の関数に引数を渡す場合は第二引数に入れる必要があります。

const a = 15;
const b = 5;
const sum = await page.evaluate((a, b) => {
  return a + b
}, a, b);

console.log(sum) //結果は20

screenshotのオプション
clip: スクショ範囲を細かく指定できます。x,y座標でどこから縦横何pxを撮影するかを設定できます。

path: ファイルの保存先を指定
(Node.js の標準モジュール path が提供している path.join メソッドを使用して、ディレクトリ名あるいはファイル名を結合、この場合あらかじめscreen_shotsという名のフォルダを用意する必要があります)

const path = require('path');
const filepath = path.join(__dirname, 'screen_shots', 'example.png');

await page.screenshot({
  clip: { x: 100, y: 100, width: 300, height: 300 },
  omitBackground: true,
  path: filepath
});

まとめ

このPuppeteerはドキュメントが比較的読みやすかったですし、関連記事も多かったです。
ちなみに、リリース当初はグラデーションとか複雑な描画に弱かったらしいのですが、今は改善されてるみたいです。