GoogleCloudFunctions with puppeteerでウェブページのスクリーンショット取得

お疲れ様です、町田です。先日、日本時間の8/16日にGoogleCloudFunctionsが正式にpuppeteerのサポートを発表しました、なので今回は、GoogleCloudFunctions with puppeteerでウェブページのスクリーンショット取得を試したいと思います。
概要
puppeteerは、Chromeで行うブラウジングの動作をjavascriptで記述し、操作を自動化することができるjavascriptのライブラリです、中ではheadlessChromeが動いています。
また、GoogleCloudFunctionsはAmazonLambdaと同様関数実行をサポートするクラウドサービスです。
これら2つを組み合わせることで、自身でサーバー管理を行わず、手軽にブラウザ操作の自動化をしようという試みです。
今回は、’FOXHOUND株式会社’でgoogle画像検索したときの一覧画面のスクリーンショットを取得してみたいと思います。
環境構築
この記事ではmacOS HighSierraを使用しています。自分のOSに合わせて適宜読み替えてください。
nodeのインストール
公式ホームページのnode.jsや、brewなど各種パッケージマネージャからインストールします。
GoogleCloudFunctionsはnode v8までの対応となっていますが、今回はnode v8以上であれば特に問題ありません。
google-cloud-sdkのインストールとプロジェクトの作成
次にgcloud コマンドライン ツールの使用の始める前にの1~6を行い、プロジェクトの作成等とcliの準備とbeta componentsの追加を行います。今回自分はgcf-with-puppeteer
という名前でGCPプロジェクトを作成しました。gloud init
などの際に作成したプロジェクトを選択しておきます。
また、cliのインストール確認として以下のコマンドを打ち込んで
リストにbetaがあることが確認できれば準備完了です。
以上で環境構築は終了です。
GoogleCloudFunctionsの作成
コーディングの準備
適宜プロジェクトのフォルダを作成しそこで作業を開始します。また、メインとなるindex.jsとpackage.jsonも作成しておきます。
> mkdir gcf-with-puppeteer && cd gcf-with-puppeteer
> touch index.js package.json
package.jsonに以下をコピペしてください
{
"name": "gcf-with-puppeteer",
"version": "0.0.1",
"dependencies": {
"puppeteer": "^1.7.0"
}
}
コピーできたらnpm install
します。
> npm install
コーディング
index.jsを編集します、以下のようになりました。
const puppeteer = require('puppeteer');
let page;
const search_query = "FOXHOUND株式会社";
async function getBrowserPage() {
// Launch headless Chrome. Turn off sandbox so Chrome can run under root.
const browser = await puppeteer.launch({
args: ['--no-sandbox']
});
return browser.newPage();
}
exports.getFoxHoundFirstImage = async (_, res) => {
if (!page) {
page = await getBrowserPage();
}
const navigationPromise = page.waitForNavigation();
// 検索クエリとともにグーグルへアクセス
await page.goto(`https://www.google.co.jp/search?q=${search_query}`, {
waitUntil: 'networkidle2'
});
await navigationPromise;
// 画像タブへ切り替え
const image_tabs = await page.$x("//div[@id='hdtb-msb-vis']//a[text()='Images']");
await image_tabs[0].click();
await navigationPromise;
// 画像表示まで間隔が開くので待つ
await await page.waitFor(10000)
// スクリーンショットを取得し、レスポンスで返す
const imageBuffer = await page.screenshot();
res.set('Content-Type', 'image/png');
res.send(imageBuffer);
};
デプロイしてアクセスしてみましょう。
> gcloud beta functions deploy getFoxHoundFirstImage --trigger-http --runtime nodejs8 --memory 1024MB
デプロイ完了後に表示されたhttps://us-central1-gcf-with-puppeteer.cloudfunctions.net/getFoxHoundFirstImage
にアクセスすると
このような画像が表示されました!(※プライバシー保護のためマスク多めです。)
最後に
ローカルでpuppeteerを実行するのとほぼ変わらず、クラウド上に置くことで各種ログの管理までしてくれるため、とても便利に感じました。ただ、課金が発生する可能性があるため、試した場合はプロジェクトの削除を忘れずに!
参考
- https://cloud.google.com/functions/docs/quickstart
- https://cloud.google.com/blog/products/gcp/introducing-headless-chrome-support-in-cloud-functions-and-app-engine