PuppeteerでWebページの差分をscreenshot画像で確認する方法

PuppeteerでWebページの差分確認

PuppeteerでWebページの差分確認はページ内のテキストを取得すれば簡単にできるが、それだと画像や余白などの変化に気付くことができない。

そのため、Webページの画像や余白などの差分を確認するには修正前と修正後のスクリーンショット画像を比較する必要がある。

これらを手作業でやるのは手間がかかるが、Puppeteerとresemblejsを使用すればコマンドを入力するだけで簡単にできる。

resemblejsとは

その名の通り画像の差分(diff)を確認するためのもの。

Puppeteerはスクリーンショット画像は保存できるが、画像の差分までは検出できないためresemblejsも使用する。

インストール手順

まずmkdir my-diffのような適当なフォルダを作成してcd my-diffで移動する。

次にnpm init -yを実行した後に以下のコマンドでpuppeteerとresemblejsをインストールする。

npm i -D puppeteer resemblejs

インストールが完了したらdiff.jsのようなファイルを作成して画像差分を確認するためのコードを作成する。

実行する際はnode diff.js [URL]となる。iwb.jpの場合は以下の通り。

node diff.js https://iwb.jp/
 

スクリーンショット画像はフルページの場合はfullPage: trueを付ける。差分画像はscreenshot.diff.pngという名前で生成される。iwb.jpの場合は毎回広告部分が変わることが多いので2回実行すれば差分が出る。

// diff.js
const puppeteer = require('puppeteer');
const resemble = require("resemblejs");
const fs = require('fs');
const NK2 = { waitUntil: 'networkidle2' };

puppeteer.launch({
    headless: false,
    slowMo: 100,
  })
  .then(async browser => {
    const page = await browser.newPage();
    const url = await page.evaluate(() => prompt('URLを入力'));
    fs.access('screenshot.png', err => {
      if (!err) {
        fs.rename('screenshot.png', 'screenshot.old.png', () => {});
      }
    });
    await page.goto(url, NK2);
    await page.screenshot({path: 'screenshot.png', fullPage: true});
    fs.access('screenshot.old.png', err => {
      if (!err) {
        resemble('screenshot.png')
          .compareTo('screenshot.old.png')
          .ignoreColors()
          .onComplete(function(data) {
            fs.writeFileSync('screenshot.diff.png', data.getBuffer());
            console.log('差分画像を作成しました。');
            if (data.misMatchPercentage > 0.01) {
              console.log('差分があります。');
            } else {
              console.log('差分はありません。');
            }
        });
      } else {
        console.log('最初の画像を保存')
      }
    });
    browser.close();
  });