みーのぺーじ

みーが趣味でやっているPCやソフトウェアについて.Python, Javascript, Processing, Unityなど.

ブラウザのスクリーンショットを利用したWebサービスをpuppeteerで作る

URLが含まれるリクエストを受け付けて,そのURLにブラウザでアクセスし,描写された内容をスクリーンショットしてPNG画像を生成し,その画像をレスポンスするWebサービスを作成した時の話です.

なお,このWebサービスはみーが個人的に利用するために作成したものであり,公開しておりません.

Cloud Functionsで実装を試みる

Chromeを自動操作するpuppeteerというNodeライブラリーを使うことにしました.page.screenshot([options])関数があり,簡単に目的のWebサービスが作れそうだからです.

Node.jsが実行可能なサーバーレス環境として,Cloud Functionsを使うことにしました.puppeteerはCloud Functionsでの動作がサポートされているからです.

Running Puppeteer on Google Cloud Functions

The Node.js 10 runtime of Google Cloud Functions comes with all system packages needed to run Headless Chrome.
To use puppeteer, simply list the module as a dependency in your package.json and deploy your function to Google Cloud Functions using the nodejs10 runtime.
puppeteer/troubleshooting.md at main · puppeteer/puppeteer · GitHub

しかし,実際は動作させるのは不可能でした.以下の問題が発生しました.

これらの問題を解決するよりは,自分でDockerfileを作成した方が早そうな気がしてきました.

Cloud Runと料金比較

1ヶ月に1,000,000リクエスト,1リクエストに500msで同時実行せず,100KBの画像を送信する,という想定で料金を計算しました.

CPUとメモリーは,Cloud FunctionsでMemory: 1024MB CPU: 1.4GHzを選択し,Cloud Run でMemory 1GB, vCPU 1を選択し,ブラウザーが動作する環境でなるべく同じになるようにしました.

f:id:atsuhiro-me:20210110121856p:plain:w360

Google Cloud Platform Pricing Calculator

Cloud Functionsが1,667円,Cloud Runが831円でした.意外なことに,Cloud Runの方が安いことがわかりました.原因としては,Cloud Functionsはネットワーク転送に課金があり,今回のようにレスポンスとして画像データのように比較的大きなデータを送信する用途では値段が上がってしまうようです.Cloud Runのネットワーク転送にも課金はありますが*1,プレミアム ティアの料金は外向きのみに適応され,1ヶ月に1TBまでは無料です*2

また,100倍のリクエストを行った場合(100,000,000リクエスト)は,Cloud Functionsが207,688円,Cloud Runが140,769円となり,Cloud Runのほうが安いみたいです.

もしリクエストが少ない場合は,両者ともに無料枠があるので,無料となる場合もあるようです.

したがって,自分でDockerfileを書くならば,Cloud Runの方が安くて簡単だと思われます.

puppeteerを動作させるDockerfile

puppeteerのGitHub レポジトリに,サンプルが掲載されていますので引用します.

FROM node:10

RUN apt-get update && \
    apt-get -y install xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 \
      libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \
      libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
      libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 \
      libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget && \
    rm -rf /var/lib/apt/lists/*

# Add user so we don't need --no-sandbox.
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
    && mkdir -p /home/pptruser/Downloads \
    && chown -R pptruser:pptruser /home/pptruser

# Run everything after as non-privileged user.
USER pptruser

puppeteer/Dockerfile.linux at main · puppeteer/puppeteer · GitHub

これを見本として,自分なりにカスタマイズします.日本語のウェブサイトに対応するために,日本語フォントをインストールするべきです.