PHPで特定のサイトのスクリーンショットを取る

PHP PhantomjsというGit-Hubで公開されているライブラリを使って、スクリーンショットを取るためのラッパークラスを作りました。

github.com

↑がGitHubリポジトリのリンクです。サムネイルはダンディーなおじさまですね。

<?php
//phantomjsを使って特定のWebサイトのスクショを取って保存するクラスです。
//jonnnnyw/php-phantomjs のラッパー?ラッピング?したものです。
//参考:https://github.com/jonnnnyw/php-phantomjs

use \JonnyW\PhantomJs\Client;
class ScreenShot{
    private $client;
    private $request;
    private $response;
    private $width;
    private $height;
    private $top;
    private $left;
    private $URL;
    private $timeOut = 30000;
    
    //画面サイズなどを決定する
    function __construct($width, $height, $URL){
        $this->width = $width;
        $this->height = $height;
        $this->top = 0;
        $this->left = 0;
        $this->URL = $URL;
    }
    
    //phantomjs実行クライアントを作成する
    public function MakeClient(){
        $this->client = Client::getInstance();
        $this->client->isLazy(); //ページのレンダリング待ち
        $this->client->getEngine()->setPath(__DIR__ . '/../bin/phantomjs');
    }
    
    //スクショリクエストの詳細を設定する
    //ここでは、ブラウザサイズと同じ範囲を撮影範囲としている
    public function MakeRequest($screenshotFileName){
        $this->request = $this->client->getMessageFactory()->createCaptureRequest($this->URL, 'GET');
        $this->request->setTimeout($this->timeOut); //強制的に終了するまでの時間
        $this->request->setOutputFile($screenshotFileName); //スクショのファイル名
        $this->request->setViewportSize($this->width, $this->height); //ブラウザサイズ
        $this->request->setCaptureDimensions($this->width, $this->height, $this->top, $this->left); //撮影範囲
    }
    
    //リクエストのレスポンス(の受け皿)を作成する
    public function MakeRespose(){
        $this->response = $this->client->getMessageFactory()->createResponse();
    }
    
    //リクエストを送信する
    public function SendRequset(){
        $this->client->send($this->request, $this->response);
    }
    
    //
    public function MakeImg($screenshotFileName){
        $this->MakeClient();
        $this->MakeRequest($screenshotFileName);
        $this->MakeRespose();
        $this->SendRequset();
        //ファイルサイズ 0 byte = 画面取得できてないと判断
        If(filesize($ssName) != 0){
            return true;
        }else{
            return false;
        }
    }
}


//yahooのトップをブラウザの横幅を1000として撮影し、
//screenshot.jpgというファイルに保存する。
$screenshot = new ScreenShot(1000, 750, 'https://www.yahoo.co.jp/'); 
$screenshot->MakeImg('screenshot.jpg'); 

?>

まとめサイトのサムネイル自動生成なんかに使えると思います。というか使っています。ライブラリの名前通り、裏ではPHPがphantomjsを使って対象のサイトを表示し、スクリーンショットを撮影しています。

ちなみにphantomjsというのは、ヘッドレスブラウザという、GUIの無いブラウザの1つです。見た目上は対象サイトを表示しませんが、裏ではブラウジングしており、javascriptで動作を制御することができます。

このライブラリはphpjavascriptのコードを自動生成し、それによってphantomjsを操作しているわけです。よう作りますなあ。ちなみに、jpgやpngだけでなく、pdfでの出力も可能です。もちろん、スクレイピングにも利用できます。

Gistはこちら→ScreenShot.php · GitHub