Puppeteerを使用したスクレイピングとスクリーンショット

こんにちは。

キラメックスの伊藤です。

皆さんは情報収集をどのように行なっていますでしょうか? Twitterはてなブログ、HackerNewsなど様々なメディアがあり情報が輻輳している世の中ですので効率的に情報収集したいですよね。

今回は、情報収集(スクレイピング)を行いながらページのスクリーンショットを行う方法をご紹介できればと思います。

スクレイピングで用いるBotとしてPuppeteerを使用しました。(他にもSeleniumなどがあります) Puppeteerについては下記を参考にしていただければと思います。

developers.google.com

お気づきになられましたでしょうか!?
PuppeteerはChromeを開発しているGoogle謹製のスクレイピングツールなのです。

1. インストール
yarn add puppeteer
2. スクレイピング

TechAcademyのトップページをスクレイピングしてみたいと思います。 下記がコードになります。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.goto("https://techacademy.jp/", { waitUntil: ['networkidle0'] });

  contents = await page.evaluate(() => {
    var contents = []
    document.getElementById("header-accordion-course")
            .getElementsByTagName("a")
            .forEach(tag => contents.push(tag.innerText))
    return contents;
  });

  await contents.forEach(content => console.log(content));

  await browser.close();
})();

コース名の一覧が取得できたかと思います。

f:id:kiramex-ito:20210719100526p:plain
実行結果

3. スクリーンショット

トップページをスクリーンショット(画像化)してみたいと思います。 先ほどのコードに下記の部分に追記します。

(async () => {
  ...
  await page.goto("https://techacademy.jp", { waitUntil: ['networkidle0'] });

  await scrollToBottom(page);
  await page.screenshot({ path: 'screenshot.png', fullPage: true });
  ...
  await browser.close();
})()

async function scrollToBottom(page) {
  const scrollHeight = await page.evaluate(() => {
    return document.documentElement.scrollHeight;
  })
  let currentPosition = 0;

  while (currentPosition < scrollHeight) {
    const nextPosition = currentPosition + 1200;

    await page.evaluate(function (scrollTo) {
      return window.scrollTo(0, scrollTo);
    }, nextPosition);
    await page.waitForNavigation({ waitUntil: 'load', timeout: 500 })
              .catch(_ => {});

    currentPosition = nextPosition;
  }
}

scrollToBottom関数は、画像の遅延読込対策でスクロールしながら画像を表示させる関数です。 実行するとトップページのスクリンーンショットができると思います。

4. まとめ

今回は、Puppeteerを用いたスクレイピングスクリーンショットの方法をご紹介いたしました。 今回の紹介範囲ではありませんが、一部分の要素のみをスクリーンショットも可能です。 スクレイピングスクリーンショットなどができると色々と応用ができそうですね!

それでは、Happy Programming.