寝ても覚めてもこんぴうた

プログラム書いたり、ネットワーク設計したり、サーバ構築したり、車いじったり、ゲームしたり。そんなひとにわたしはなりたい。

Appengine (Node.js/Standard) 環境でHeadless Chromeを利用してサイトのスクリーンショットを取得する

過去に2回ほどGAE/Nodeの記事 これこれ を書きましたが、もともとはこのHeadless ChromeをAppengine上で利用したかったのでそれを試したかったため。

Headless Chromeを利用することで、Webページのスクリーンショットだったり、JavaScriptが動いていないとデータの取得が難しいSPA的なページのクローリングを行ったりすることができる。

基本的には こちら のドキュメントをなぞって進めます。

というわけで早速スクリーンショット取得を試してみましょう!

node projectの初期設定を行う

nodeのプロジェクトを作成するディレクトリへ移動し、以下のコマンドを実行します。

npm init

基本的にはすべて エンター で進めて良いと思います。

npm startのスクリプトを追加する

以下の値を package.json 内に追加します

"scripts": {
  "start": "node app.js"
}

expressとpuppetterを依存モジュールとして追加する

以下のコマンドを実行し、インストールされるのを待ちます。

npm install express puppeteer --save

app.jsファイルを作成し処理を記述する

app.js ファイルを作成し、以下の内容を記述します

const express = require('express');
const puppeteer = require('puppeteer');
const app = express();

app.use(async (req, res) => {
  const url = req.query.url;

  if (!url) {
    return res.send('Please provide URL as GET parameter, for example: <a href="/?url=https://example.com">?url=https://example.com</a>');
  }

  const browser = await puppeteer.launch({
    args: ['--no-sandbox']
  });
  const page = await browser.newPage();
  await page.goto(url);
  const imageBuffer = await page.screenshot();
  browser.close();

  res.set('Content-Type', 'image/png');
  res.send(imageBuffer);
});

const server = app.listen(process.env.PORT || 8080, err => {
  if (err) return console.error(err);
  const port = server.address().port;
  console.info(`App listening on port ${port}`);
});

ローカルでテスト実行する

以下のコマンドを実行し、ローカルでテスト用サーバを起動します。

npm start

起動したコンテンツには http://localhost:8080/?url=https://example.com という形のURLでアクセスします。

キャプチャした画像が画面に表示されれば成功です。

作成したアプリケーションをデプロイする

デプロイする際には app.yaml が必要です
Headless Chromeを利用する場合には多くのメモリを必要とするため、以下のように instance_class を指定することが推奨されているようです。
ただし、インスタンスクラスを上げることで無料枠が減るので注意しましょう。

runtime: nodejs8
instance_class: F4_1G

Appengineにデプロイします

app.yaml が配置されたディレクトリで以下のコマンドを実行します。

gcloud app deploy --project {PROJECT_ID}

デプロイしたサービスを確認する

以下のコマンドを実行するとブラウザが起動します

gcloud app browse --project {PROJECT_ID}

http://YOUR_PROJECT_ID.appspot.com/?url=https://example.com のようにアクセスすると、example.comにアクセスしたスクリーンショットが表示されます。

これでいろいろ楽しいことができそう!

enjoy!