先日、こちらのブログ記事をたまたま見つけまして、それによると、Google APIの一つを使ってサイトのスクリーンショットが取得可能!?とのことでしたので、今回はこのGoogle PageSpeed Insights APIを使い、ウェブサイトのスクリーンショットを取得してみた話となります。

以前から、dtnカテゴリの登録リンクのスクリーンショットを取得して、殺風景なカテゴリのリンク部分に表示させたら多少はにぎやかになるかな?とは考えておりましたが、安定して、しかも、簡単に利用できそうなAPIがあまり見つからず、これまでやらずじまいにおりましたが、GoogleのAPIであれば全く問題なさそうなのでやってみました。

今のdtnディレクトリのカテゴリ。昔変わらずシンプルな感じです。

先ほどのブログ記事によれば、このAPIはウェブの表示速度調査を目的として作られたもので、速度分析するにあたり、リンク先データを取得した際にスクリーンショットも取り、それをbase64でエンコードまでしてくれて、しかもレスポンスに乗せて渡してくれるといった作りになっているようです。流石はGoogleさん太っ腹な感じがするAPIです。

ただ、この記事が2017年3月のVersion2のものだったので、今も同じようにスクリーンショットをレスポンスで渡してくれるかどうかが心配でしたが、Google側で用意してあるPageSpeed Insights APIのドキュメント今はVersion5)を見てみると、プロパティ:lighthouseResult.runtimeError.codeの説明として、NO_SCREENSHOTSなるパラメータが存在しているので、スクリーンショット関連の何かがありそうな気がします。

APIレスポンスにそれらしいものが

ということで、早速設定を進めてみます。

APIのチュートリアルを読んでみると、↓のような記載があったりして、お試し程度であればAPIキーも登録せずに利用できるようですが、とりあえずPHPでグルグル回すことも考えてAPIキーは用意してみました。

PageSpeed Insights API を試すだけであれば、API キーは不要です。自動化した方法で API を使用して、1 秒間に複数回クエリを作成する予定であれば、API キーが 1 つ必要です。

GoogleのAPIを使ったことがある方ならGoogle Developer Consoleのアカウントをお持ちとは思いますので、PageSpeed Insights APIを探して、ご利用中のプロジェクトで有効化してAPIキーを取得すれば問題ないようです。

Developer ConsoleでPageSpeed Insights APIを有効化

アカウントが無かったり、プロジェクトを分けたいという場合は、新しいプロジェクトを作成して、 同じようにPageSpeed Insights APIを有効化すればOKです。

APIが無事追加されました

登録されたPageSpeed Insights APIをクリックすると、「クレデンシャルを作りなさい」との警告がでています。

CREATE CREDENTIALSボタンから認証情報を作成へ

このCREATE CREDENTIALSボタンからOAuthの認証情報作成画面に進みますが、今回はAPIキー取得だけできればOKですので、サービスアカウントの作成で済ませておきます。

サービスアカウントの作成

あとは適当な名前を付けて、次へ次へと進むと、キーの作成ボタンがでてくるので作成しておきます。秘密鍵を含むファイルはJSONでもP12でも選べますが、以前にINランキングを作るためにGoogle Analytics APIを利用した際はP12を使ってプログラムを書いていたので、このあたりを流用するため、今回もP12で保管しておきます。

といっても、PageSpeed Insights APIの場合、リクエストURLの末尾にパラメータで&key=yourAPIKeyを足すだけでいいので、認証ファイルを使うことも必要なく実装できそうです。ここまできたら、あとはリクエストURLを組み立てて投げてみます。

//API接続先
$APIurl = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=';

//取得したAPIキー
$yourAPIKey = 'AAAAABBBBBCCCCCC';

//取得したいスクリーンショット先のURL
$TARGET_URL = 'https://www.yahoo.co.jp/'

//クエリを生成
$Requesturl = $APIurl.urlencode($TARGET_URL).'&key='.$yourAPIKey;

//レスポンス取得
$InsightJSON = file_get_contents($Requesturl);

//JSONデコード
$InsightObj = json_decode($InsightJSON, FALSE);

試しにヤフーのURLを付けて投げてみると、返ってきた$InsightObjの中に、$TARGET_URLで指定したヤフーのサイトスピードに関するデータがオブジェクトで山ほど入ってました!!

とりあえずOKそうです。

早速、↓のようなJSON用ヘッダを出力して中身のデータ構造をブラウザでチェックしてみます。

header("Content-Type: text/javascript; charset=utf-8");
echo $InsightObj;

見ると、base64データがありました!

data:image/jpeg;base64が入ってます

jsonデータを見ると色々と使えそうなデータがたくさん入っていましたが、今回はスクリーンショットの画像データ以外に興味は無しなので、全部取り捨てしてjsonからこのスクリーンショットのjpeg/base64だけを引っこ抜くとします。エンコード文字列が長いのですぐに分かると思います。

実際にjsonを見た方が分かりやすいと思いますが、スクリーンショットデータはこのあたりにありました。

$Obj -> lighthouseResult -> audits -> final-screenshot -> details -> data

間にハイフン付きの final-screenshot  なんかがあるので、引っこ抜くのはこんな感じでしょうか。

  $CAPCHA = $InsightObj -> lighthouseResult -> audits -> {'final-screenshot'} -> details -> data;

取得したスクリーンショットデータはきれいにbase64エンコードがされているので、 そっくりそのままDBに貯めておけば画像表示が簡単にできそうです。

echo '<img src="'.$CAPCHA.'">';

おかげ様で、PageSpeed Insights APIを使って、無事きれいなスクリーンショットを手に入れることができました。

難点としては、そもそも指定URLの表示速度を計りつつ、サイト分析をするためのAPIということもあり、指定したURLデータをしっかり取って~分析して~jsonを戻す、といった処理に結構時間がかかるというところでしょうか。。。

スクリーンショット取得APIなんて山ほどあるにも関わらず、そもそもの目的が違うAPIを使ってなんてアホなことやっているんだとGoogleさんから怒鳴られそうですが、スクリーンショット画像がとてもきれいに取れているので、そのあたりは気にせず使ってしまいましょう。

とはいえ、APIのレスポンスもあるので、当初想定していたディレクトリ登録サイトのスクリーンショットを全部取ってカテゴリを賑やかに….というのはレスポンスも考えると非現実的かと思いましたので、dtnディレクトリで登録サイト向けに用意しているランキングのうち、OUTランキングサイト評価ランキングの上位3サイト分に限り、スクリーンショットを取って表示してみることにしました。

出来上がったのが今のランキングページです。ランキング自体はリアルタイムで変動するので、スクリーンショット未取得のサイトが上位に上がった際は、一旦取得中画像を表示させておき、定時cronで取得するとしておきました。

ランキングページが多少華やかになりました

ランキングは多少華やかになりましたが、ランキングデータの一部をbotがクリックしているのか、OUTランキングを見るとディレクトリ型検索エンジンdtnの数値が飛びぬけて高くなっていたりして、このあたりはランキングプログラム側で何かしら対応しないとダメそうですが、それはまた次の機会にしようと思います。。