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

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

# PhantomJSとは
http://phantomjs.org/
> 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をイントールします。

```bash
brew install phantomjs
```
出力結果

```bash
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の中身

```json:composer.json
{
    "scripts": {
        "post-install-cmd": [
            "PhantomInstaller\\Installer::installPhantomJS"
        ],
        "post-update-cmd": [
            "PhantomInstaller\\Installer::installPhantomJS"
        ]
    },
    "require": {
        "jonnyw/php-phantomjs": "4.*"
    }
}
```
インストール結果

```bash
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を作ってみました。

```php: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/
（何故か動画がうまく表示されてない）
![ダウンロード (1).jpeg](https://qiita-image-store.s3.amazonaws.com/0/134555/de94fb79-dbc7-cc7f-0784-5b21df479896.jpeg)

# 参考資料
* http://phantomjs.org/
* https://github.com/jonnnnyw/php-phantomjs
* https://github.com/ariya/phantomjs