Docker で Puppeteer 動かして Slack にスクショを通知してみた

Written by @ryysud

Dec 19, 2017 23:30 · 1084 words · 3 minutes read #web

puppeteer.png

Puppeteer is なに

Headless Chrome を操作できる Node.js のライブラリ。

Puppeteer is a Node library which provides a high-level API to control headless Chrome or Chromium over the DevTools Protocol. It can also be configured to use full (non-headless) Chrome or Chromium.

https://github.com/GoogleChrome/puppeteer

Headless Chrome は Chrome をGUIを表示しない状態(Headless)で動作させるモード。2017年6月頃にリリースされた Chrome59 から搭載された機能らしい。この GIGAZINE の記事 がわかりやすい。どうでもいいことですが Puppeteer(人形遣い) というシンプルなプロダクト名も個人的に好きです。また、Puppeteer は Chrome DevTools のチームが開発しているとのこと。

Node.js で簡単に Chrome を操作できるぜ!
スクリプト書けば可能性無限大だね!やったー!っていうやつですね。

早速遊んでみる

Node.js v6.4.0 以上が必須のようですが、サンプルコードは async/await などの Node.js v7.6.0 以上で使えるもので書かれているので、今回は最新 LTS の v8.9.3 を使っていこうと思います。
※ 2017年12月19日現在

Docker を用いてスクリプトを実行する際に、愚直に依存ライブラリを1つずつチェックしてインストールしていくのも良いですが、親切な方が Puppeteer 実行時に必要なライブラリがインストールされる Dockerfile を公開してくださっている(インターネット最高)ので、そちらを使うと簡単に実現できます。
https://qiita.com/QUANON/items/59c468adfff0278f20bb

では、サンプルコードを参考にスクリーンショットを実行するスクリプトを実行してみます。

# Dockerfile を作成
$ cat Dockerfile
FROM node:8.9.3

RUN apt-get update \
 && apt-get install -y \
      gconf-service \
      libasound2 \
      libatk1.0-0 \
      libc6 \
      libcairo2 \
      libcups2 \
      libdbus-1-3 \
      libexpat1 \
      libfontconfig1 \
      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

WORKDIR /app
RUN yarn add puppeteer

COPY ./screenshot.js .

ENTRYPOINT ["node", "/app/screenshot.js"]

# サンプルコードを参考にスクリプトを作成
$ cat screenshot.js
const puppeteer = require('puppeteer');

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

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

# Docker Image のビルド
$ docker build -t docker-puppeteer .

# スクリプトの実行
$ docker run --rm -v $(pwd):/tmp -w /tmp docker-puppeteer

# ファイルオープン
$ open example.png

なんかデフォルト値が効いてしまい綺麗ではないですが、無事スクリーンショットが撮れました!

example.png

ちなみにサンプルコードコピペで –no-sandbox を付与しないと以下のようなエラーが出力されますのでご注意を。

(node:2429) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Failed to launch chrome!
[1219/163502.010890:ERROR:zygote_host_impl_linux.cc(90)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.


TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

(node:2429) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

スクリーンショットを Slack 通知してみる

screenshot2slack.png

Puppeteer で取得したスクリーンショットのファイルを Slack API 経由でアップロードすることが出来ました!単純なスクリプトなので、興味があるかたはどうぞご覧になって下さい。 https://github.com/ryysud/screenshot2slack

感想

スクリプトさえ書いてしまえは色々とやれそうなので活用していきたいと思いました。

参考資料