Puppeteer(Headless Chrome)でDOMの追加・変更を検知する

October 11, 2019

Headless Chromeでサイトにアクセスして、DOMの追加や変更を検知してなにか(例えばDOMがロードされたタイミングでスクショを撮ったりなど)処理をしたい場面が結構あります。

そういうときに使えるのがPage.waitForメソッドです。

このメソッドはwaitForSelectorとかのラッパー関数なのでセレクタも指定することができます。

使い方

.selectorというクラスがbodyのどこかのDOMに足されるまで待つという処理になります。

await page.goto("http://hoge.com");
await page.waitForSelector(".selector");

デモコードを用意しました。 https://github.com/SatoshiKawabata/puppeteer-waitfor-example

index.htmlはこんな感じで、3秒ごとにDOMにnotify-〇〇というクラスが付与されるだけのプログラムです。

<div id="target"></div>
<script>
  let cnt = 0;
  setInterval(() => {
    const target = document.getElementById("target");
    target.classList.add("notify-" + cnt);
    cnt++;
  }, 3000);
</script>

main.jsでは、notify-〇〇クラスが付与されるまで処理を待つような感じになっています。

const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto("http://127.0.0.1:8080");
  let cnt = 0;
  while (cnt < 10) {
    const selector = ".notify-" + cnt;
    await page.waitForSelector(selector);
    console.log("notify", ".notify-" + cnt);
    cnt++;
  }
  await page.close();
  await browser.close();
})();

実行は下記2つのコマンド

npm run serve
npm run main

実行結果

notify .notify-0
notify .notify-1
notify .notify-2
notify .notify-3
notify .notify-4
notify .notify-5
notify .notify-6
notify .notify-7
notify .notify-8
notify .notify-9