PHP&Selenium、イベント発生時に処理を実行

今回はPHP版のseleniumでイベント発生時に何かアクションを起こしたい時の設定方法を紹介したいと思います。

まず普通にseleniumが動くように設定します。インストール諸々を済ませて以下を実行するとGoogleのホームページに遷移して10秒待ってウィンドウを閉じます。

<?php

require_once './vendor/autoload.php';

use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\WebDriverExpectedCondition;
use Facebook\WebDriver\WebDriverBy;

function test()
{
    // selenium
    $host = 'http://localhost:4444/wd/hub';
    // chrome ドライバーの起動
    $driver = RemoteWebDriver::create($host,DesiredCapabilities::chrome());
    // 画面サイズをMAXに
    $driver->manage()->window()->maximize();
    // Googleへ遷移 
    $driver->get('https://www.google.co.jp/');
    // 10秒待つ
    sleep(10);

    // ブラウザを閉じる
    $driver->close();
}

test();

このコードに、イベントを追加したいときは、まずWebDriverEventListenerというinterfaceを実装したEventCaptureというクラスを用意します。

<?php
use Facebook\WebDriver\WebDriverEventListener;
use Facebook\WebDriver\Exception\WebDriverException;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\Support\Events\EventFiringWebDriver;
use Facebook\WebDriver\Support\Events\EventFiringWebElement;

class EventCapture implements WebDriverEventListener{
    public function beforeNavigateTo($url, EventFiringWebDriver $driver){ }

    public function afterNavigateTo($url, EventFiringWebDriver $driver){
        // URL遷移時の読み込み時間を出力
        result = $driver->executeScript("return (window.performance.timing.loadEventEnd - window.performance.timing.requestStart) / 1000");   
                echo($result);
    }

    public function beforeNavigateBack(EventFiringWebDriver $driver){ }

    public function afterNavigateBack(EventFiringWebDriver $driver){ }

    public function beforeNavigateForward(EventFiringWebDriver $driver){ }

    public function afterNavigateForward(EventFiringWebDriver $driver){ }

    public function beforeFindBy(WebDriverBy $by, $element, EventFiringWebDriver $driver){ }

    public function afterFindBy(WebDriverBy $by, $element, EventFiringWebDriver $driver){ }

    public function beforeScript($script, EventFiringWebDriver $driver){ }

    public function afterScript($script, EventFiringWebDriver $driver){ }

    public function beforeClickOn(EventFiringWebElement $element){ }

    public function afterClickOn(EventFiringWebElement $element){ }

    public function beforeChangeValueOf(EventFiringWebElement $element){ }

    public function afterChangeValueOf(EventFiringWebElement $element){ }

    public function onException(WebDriverException $exception, EventFiringWebDriver $driver = null){}
}

ここにafterNavigateToを参考にイベント発生時に行いたい処理を適当に記述すればオッケーです。 今回はURLを遷移するたびにURL遷移にどのくらい時間がかかったかを出力します。ページの読み込み時間に関する詳細はこちらを参考にしてください。 これを先ほどのtestクラスで生成すれば、URLを遷移するたびにページの読み込み時間が表示されます。

実装するとこんな感じになります。先ほどのEventCaptureはEventCapture.phpというファイルにして呼び出すようにします(長いので)。

<?php

require_once './vendor/autoload.php';
require_once '/EventCapture.php'; //追加!!

use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\WebDriverExpectedCondition;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\Support\Events\EventFiringWebDriver; //追加!!

function test()
{
    // selenium
    $host = 'http://localhost:4444/wd/hub';
    // chrome ドライバーの起動
    $driver = RemoteWebDriver::create($host,DesiredCapabilities::chrome());
    // 画面サイズをMAXに
    $driver->manage()->window()->maximize();

    // eventによる割り込み処理を発生させるための設定
    $eventHandler = new EventFiringWebDriver($driver); // 通常のwebdriverからeventに反応するeCaptureをインスタンス化
    $eCapture = new EventCapture($driver); // さっき書いたEventCaptureクラスをインスタンス化
    $eventHandler->getDispatcher()->register($eCapture); // さっき書いたEventCaptureクラスを登録
    $driver = $eventHandler; // 通常のwebdriverからeventに反応するeCaptureにdriverを更新

    // Googleへ遷移 
    $driver->get('https://www.google.co.jp/');
    // 10秒待つ
    sleep(10);

    // ブラウザを閉じる
    $driver->close();
}

test();

これを実行するとGoogleのホームページに遷移するのにどれくらい時間がかかったかが出力されるはずです。

僕は今からこれを使って、管理しているサイトじゅうを遷移させて、どこが処理にもたついているのかを出力するコードを実装したいと思います。 皆さんもいろんなイベントをうまく活用してみてください