ブログ

Armadilloでpuppeteer使って動的なWebサイトをクローリングする

at_ohsawa
2021年12月27日 19時18分

Armadilloで動的なWebサイトの情報を取得して利用するためのクローラを作ります。クローラによってデータを収集、処理することをクローリングといい、APIの用意されていないWebサイトからブラウザを参照せずに情報を取得しようとするときに必要となる手段のひとつです。

Webサイトが静的なHTMLで構成されているときは、サイトに対してシンプルにHTTPでGET/POSTするだけで期待したHTMLを得ることができますが、JavaScriptで動的にコンテンツを生成するサイトの場合はHTMLだけ取得してもブラウザのレンダリング結果とは同じ情報が得られないことがあります。

ここでは pupeteer というNode.jsのライブラリを使って、chromium の headless モードを呼び出し、GUI環境の無い状態でブラウザを動作させることで、動的なWebサイトであってもJavaScriptによって生成された結果を取得する手順を紹介します。

この記事ではDebian 10(buster)環境を前提にしています。インストールに必要な空き容量は約96MBです。

必要なパッケージとnvmのインストール

# apt update
# apt install libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libgbm1 libasound2 libpangocairo-1.0-0 libxss1 libgtk-3-0 curl libatomic1 chromium-driver
# update-ca-certificates --fresh
# curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash

ここで一旦ログアウトしてログインし直すか、最後のcurlの実行時に指示される環境変数の反映するか、どちらかを実行してください。

Node.jsのインストール

# nvm install node

開発ディレクトリへのpuppeteerのインストール

# mkdir test
# cd test
# npm i puppeteer

余談ですが、ここでインストールするpuppeteerにはheadless cheomeが含まれます(test/node_modules/puppeteer/.local-chromium/linux-938248/chrome-linux/chrome 数字の部分はバージョンごとに異なりますが、ファイルの命名規則は同じはずです)。しかし、これはPC(amd64)向けのバイナリでARM搭載のArmadilloのためには別途インストールが必要なため、この記事の最初にchromiumをインストールしています。

実行

開発ディレクトリ test の中に次のファイルを作って実行すると、example.com のスクリーンショット example.png が取得できます。 といっても、コンソールでは表示できないので、PCにコピーして見ると良いでしょう。

スクリプトの作成

# vi test.js

'''test.js'''

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
        executablePath: '/usr/bin/chromium',
        args: ['--no-sandbox']
  });
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

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

実行

# node ./test.js

Armadillo機種によって異なりますが、chromiumは非常に負荷の大きいプロセスなのでArmadillo-640の場合は実行完了まで30秒程度の時間が必要です。

実行結果の確認

正常に実行完了すると、サイトのスクリーンショットを内部で取得した結果であるexample.pngが生成されています。

# ls 
example.png  node_modules  package-lock.json  package.json  test.js