Herokuで日本語を含むページのスクリーンショットを撮ってみた

Herokuで日本語を含むページのスクリーンショットを撮ってみた

追記(2018/07/16)

PhantomJSが開発終了していたのを、記事を公開してから気づいたので、Puppeteerに乗り換えるなどを行った方が良いかと思います。


Node.jsはnpm scriptsでしか使ってなかったのですが、URLを入力➝スクリーンショットを撮る仕組みが欲しくなったので、Node.jsをぼちぼち触ってみました。

文字化けが発生する

今回は「とりあえず撮れれば良い」というレベルでしたので、込み込みで入っていそうな、node-webshotを利用したので、スクリーンショットを撮るまでは非常に簡単でしたが、Paas環境ににアップロードすると日本語が□□□みたいに表示されるようになってしまいました。

原因は明確で、日本語フォントが入っていないことが原因なのですが、PaaS環境にどうやってフォントをインストールすれば良いのか調べてみた所、Herokuでは解決方法が見つかったので、Herokuで開発を行うことにしました。

Herokuでフォントをインストール

方法は参考ページ(Heroku環境でフォントを追加する – r7kamura – Medium)そのままで、.fontsというフォルダを用意して、そこにフォントファイルを追加してやればOKです。

つまり、こんな感じのディレクトリ構造になります。

- .fonts/
  - 何かフォントファイル
- node_modules/
- app.json
- package.json
- Procfile

Basic認証環境下も対応したい

これも参考ページ(node-webshotでベーシック認証サイトのキャプチャを取得する - Qiita)そのままで、node-webshotのオプションのcustomHeadersに、Authorizationを追加してやればOKです。

他で利用する箇所があったので、Base64化にcrypto-jsを利用しています。

import * as CryptoJS from "crypto-js";
import * as webshot from "node-webshot";

// ユーザ名とパスワード
const user = "username";
const pass = "password";

// Base64化
const wordArray = CryptoJS.enc.Utf8.parse(user + ":" + pass);
const base64Auth = "Basic " + CryptoJS.enc.Base64.stringify(wordArray);

// スクリーンショット
const url = "http://example.com";
const file = "export.ong";
webshot(url, file, {
    customHeaders: {
        Authorization: base64Auth,
    },
});

雑感

スクリーンショットを撮るのなんて面倒臭そうだなぁ、と思っていたら、いつの間にか便利なライブラリがたくさん増えていて、基本的な操作は特に問題なく利用することができました。

ローディングがあるページなどは撮影までの遅延時間を設ければ良さそうなので、よっぽどのことがなければPhantomJSを直接触る必要は無さそうですね。

また、PaaS環境も慣れているPHPばかりで利用していましたが、Node.jsでも問題なく実行ができました。しかし、Heroku以外で日本語フォントを利用できるPaaS環境は無いかなぁ…?本当はFirebase Functionsで利用したいんだけど、そもそも無料プランでは外部URLを参照することすら出来ないので、実験すら出来ない…。