PhantomJSを使ってスクリーンキャプチャなど色々試してみた


はじめまして。イエシルグループエンジニアのりゅうです。
こないだ偶然で担当プロジェクトのテスト(Capybara)がエラーになってハマって、PhantomJS周りまでを調査してみました。

PhantomJSとは

PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.

WebkitベースのHeadlessブラウザで、DOMハンドリング、CSSセレクター、JSON、CanvasとSVGをサポートしております。

PhantomJSのインストール

コメンドライン(mac)

mac上で、brewを使ってphantomjsをイントールします。

brew install phantomjs

出力結果

NPC0201:~ livesense$ sudo brew install phantomjs
==> Downloading https://homebrew.bintray.com/bottles/phantomjs-2.1.1.el_capitan.bottle.1.tar.gz
Already downloaded: /Users/livesense/Library/Caches/Homebrew/phantomjs-2.1.1.el_capitan.bottle.1.tar.gz
==> Pouring phantomjs-2.1.1.el_capitan.bottle.1.tar.gz
🍺  /usr/local/Cellar/phantomjs/2.1.1: 49 files, 51.0M

composer

今回はphantomjs phpのライブラリを使いますから、composerを使って、パッケージを管理します。
composer.jsonの中身

composer.json
{
    "scripts": {
        "post-install-cmd": [
            "PhantomInstaller\\Installer::installPhantomJS"
        ],
        "post-update-cmd": [
            "PhantomInstaller\\Installer::installPhantomJS"
        ]
    },
    "require": {
        "jonnyw/php-phantomjs": "4.*"
    }
}

インストール結果

NPC0201:sample livesense$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing twig/twig (v1.28.2)
    Downloading: 100%         

  - Installing symfony/yaml (v3.2.0)
    Downloading: 100%         

  - Installing symfony/filesystem (v3.2.0)
    Downloading: 100%         

  - Installing symfony/dependency-injection (v3.2.0)
    Downloading: 100%         

  - Installing symfony/config (v3.2.0)
    Downloading: 100%         

  - Installing jakoch/phantomjs-installer (2.1.1)
    Downloading: 100%         

  - Installing jonnyw/php-phantomjs (v4.5.1)
    Downloading: 100%         

symfony/yaml suggests installing symfony/console (For validating YAML files using the lint command)
symfony/dependency-injection suggests installing symfony/expression-language (For using expressions in service container configuration)
symfony/dependency-injection suggests installing symfony/proxy-manager-bridge (Generate service proxies to lazy load them)
Writing lock file
Generating autoload files
  - Installing phantomjs (2.1.1)
    Downloading: 100%    

スクリーンキャプチャのコード(API的な)

PhantomJSを使って画面のキャプチャは簡単に撮れるから、そのAPIを作ってみました。

index.php
<?php

require __DIR__ . '/../vendor/autoload.php';

use JonnyW\PhantomJs\Client;

$web_url = $_GET['web_url'];
$output_file = '/data/' . sha1($_SERVER['REQUEST_URI']) . '.jpg';

if (file_exists($output_file)) {
    header('Content-type: image/jpeg');
    readfile($output_file);
} else {
    // ファイルを分割してserviceクラスなどにまとめたほうがよい
    $viewport_width = 1600;
    $viewport_height = 1000;

    $client = Client::getInstance();
    $client->getEngine()->setPath('/usr/bin/phantomjs'); // phantomjs path
    $request = $client->getMessageFactory()->createCaptureRequest(
        $web_url, // url
        'GET',  // method
        3000);  // timeout(second)

    $client->getEngine()->addOption('--proxy=host:port');
    $request->setQuality(75); // default 75
    $request->setCaptureDimensions($width, $height); // キャプチャ範囲
    $request->setFormat('jpeg'); // pdf, png, jpeg, bmp, ppm, gif
    $request->setOutputFile($output_file);
    $request->setViewportSize($viewport_width, $viewport_height);
    $response = $client->getMessageFactory()->createResponse();
    $client->send($request, $response);
    header('Content-type: image/jpeg');
    readfile($output_file);
}

次はIESHILトップページのキャプチャです。
http://localhost/?web_url=https%3A//www.ieshil.com/
(何故か動画がうまく表示されてない)

参考資料