動かざることバグの如し

殿、温めておいたバグがこちらでございます

Cloud Functions+Puppeteerでサーバーレスなスクレイピング

いやこれはありだと思った。

準備

そもそもGCPのアカウントがないと始まらないのは当然として、手元の環境でgcloudコマンドがアカウント紐付いた状態で叩ける必要がある。(コマンドでCloud Functionsへデプロイをするため)

gloudのインストールは以下を参考に

qiita.com

コード

今回はyarnではなくnpmでやる。適当なディレクトリでnpm init -y

Puppeteerのインストール

npm install puppeteer -y

すると以下のファイルが生成される

package.json

{
  "name": "puppeteer_sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "puppeteer": "^1.7.0"
  }
}

index.jsを用意して以下

const puppeteer = require('puppeteer');
let page;

async function getBrowserPage() {
  const browser = await puppeteer.launch({args: ['--no-sandbox']});
  return browser.newPage();
}

exports.screenshot = async (req, res) => {
  const url = req.query.url;

  if (!url) {
    return res.send('params["url"] is blank');
  }

  if (!page) {
    page = await getBrowserPage();
  }
  await page.setViewport({ width: 1366, height: 768 });
  await page.goto(url);
  const imageBuffer = await page.screenshot({quality: 20, fullPage: true, type:'jpeg'});
  res.set('Content-Type', 'image/jpeg');
  res.send(imageBuffer);
};

デプロイ

いざデプロイ screenshotは任意 URLの一部になる。

gcloud beta functions deploy screenshot --trigger-http --runtime nodejs8 --memory 1024MB

結構時間かかるが、しばらくすると以下のようなレスポンスが返ってくるはず

Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 1024
entryPoint: screenshot
httpsTrigger:
  url: xxxxxxxxxxxxxxxxxxxxxxxxxxx
labels:
  deployment-tool: cli-gcloud
name: xxxxxxxxxx
runtime: nodejs8
serviceAccountEmail: xxxxxxxx@appspot.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
status: ACTIVE
timeout: 60s
updateTime: '2018-09-03T13:48:58Z'
versionId: '4'

返ってきた値のhttpsTriggerがCloud FunctionsのAPIエンドポイントになるので

https://httpsTriggerのURL?url=http://example.com/

でアクセスすると無事にhttp://example.com/のキャプチャ画像が表示されるはず

以下はgithubをフルスクリーンで撮ったキャプチャ画像だけど結構綺麗に取れてる。日本語フォントもいけるし結構いいのでは。

f:id:thr3a:20180903230328j:plain

欠点

デバッグが超絶やりづらい

公式ドキュメント上ではCloud Functionsのローカル上でのデバッグ方法載ってるけど手順が悪いのかうまくいかない。。。。