APIでスクリーンショット取得

先日、こちらのブログ記事をたまたま見つけまして、それによるとGoogle APIの一つを使ってサイトのスクリーンショットが取得できる!?とのことでした。そこで、Google PageSpeed Insights APIを使ったウェブサイトのスクリーンショットを取得にチャレンジしてみました。

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

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

Google PageSpeed Insights API

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

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

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

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

Google Developer Console

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

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

PageSpeed Insights APIを有効化してAPIキー取得

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で保管しておきます。

PHPでクエリを生成

秘密鍵のファイルを入手したものの、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の中身をチェック

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

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

見ると、長々しいbase64データが存在しました!

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

データを見ると、他にも色々と使えそうなデータがたくさん入っていましたが、今回はスクリーンショットの画像データ以外に興味は無しなので、全部取り捨てをしてjsonからこのスクリーンショットのjpeg/base64だけを引っこ抜くとします。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 APIでスクショ取得完成

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

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

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

ランキング上位サイトに限って利用に

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

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

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

おわりに

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