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です。

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

1
2
3
4
5
6
- .fonts/
- 何かフォントファイル
- node_modules/
- app.json
- package.json
- Procfile

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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を参照することすら出来ないので、実験すら出来ない…。

Author: SUSH
Link: http://blog.sus-happy.net/heroku-webshot/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.