ラボ > PHP:selenium(セレニウム)

セレニウムの基本型

作成日:2018-11-26, 更新日:2019-05-29

基本

PHP、セレニウムを使ってみる」で作った「makeChrom()」でドライバを起動させる。

入力待ち状態にする(プログラムを終了させない)

たぶん、ムリ(※エラーを出せば待ち状態のままになる)

単純に確認したいだけなら、適当に「sleep()」とかいれてあげれば、すぐには終了されない。

formを実行

// URLを開く
$driver->get($url);

// formタグの「id=〇〇〇」で探す
$wrapForm = $driver->findElement(WebDriverBy::id(〇〇〇));

// formタグの中にある「name=〇〇〇」を探して「□□□」を入力する
$wrapForm->findElement(WebDriverBy::name(〇〇〇))->sendKeys(□□□);

// formタグにある検索ボックスを送信:formなのでsubmit
$wrapForm->submit();

// プログラムを終了させない:cmdは「ctrl+c」で終了させる
$driver->wait()->until(WebDriverExpectedCondition::titleIs('aaaa'));

要素の取得(findElement(対象) / findElements(対象))

▼1個取得:findElement(対象)

$element = $driver->findElement(WebDriverBy::cssSelector('div.header'));
// $element will be instance of RemoteWebElement

$headerText = $element->getText();

▼複数取得:findElements(対象):「s」がついた複数形になる

$elements = $driver->findElements(WebDriverBy::cssSelector('ul.foo > li'));
// $elements is now array - containing instances of RemoteWebElement (or empty, if no element is found)

foreach ($elements as $element) {
    var_dump($element->getText());
}

対象(WebDriverBy::〇〇〇())

Css selector CSSの指定(?)から探す WebDriverBy::cssSelector('h1.foo > small')
Xpath WebDriverBy::xpath('(//hr)[1]/following-sibling::div[2]')
Id 「id="〇〇〇"」で直指定 WebDriverBy::id('heading')
Class name 「class="〇〇〇"」で直指定 WebDriverBy::className('warning')
Name attribute (on inputs) 「name="〇〇〇"」で直指定 WebDriverBy::name('email')
Tag name タグ名 WebDriverBy::tagName('h1')
Link text リンクテキスト(完全一致?) WebDriverBy::linkText('Sign in here')
Partial link text リンクテキスト(部分一致?) WebDriverBy::partialLinkText('Sign in')

他、個人的によく使う

要素の親要素 WebDriverBy::xpath('..')
要素の親の親要素 WebDriverBy::xpath('../..')

値の取得やクリックとか

Getting text of an element テキスト取得
$txt = 〇〇->getText();
Clicking an element (link, checkbox, etc.) クリックする
〇〇->click();
Typing into text field formに値を入力
$input = 入力する値;
〇〇->sendKeys($input);
How to clear the existing value in text field formの値のクリア
〇〇->clear();
How to check if an element is visible 要素が可視かチェック
$elm = 〇〇->findElement(〇〇);
if ( $elm->isDisplayed() ) {
    // do something...
}
How to reload the page ページのリロード
$driver->navigate()->refresh();
Get attribute of an element 属性の値取得
$attr = 取得したい属性名;
$val = 〇〇->getAttribute($attr);
Get value of an input element value値(属性名が「value」)
$attr = 'value';
$val = 〇〇->getAttribute($attr);
Take a screenshot ページのスクリーンショット
$filename = __DIR__ . '/myfile.png';
$screenshot = $driver->takeScreenshot();
file_put_contents($filename, $screenshot);

他、個人的によく使う

要素のHTMLを取得(innerHTML、outerHTML)
$html = 〇〇->getAttribute('innerHTML');
ページ遷移(戻る、更新とか)
$url = 'http://〇〇〇〇〇';
$driver->navigate()->to($url);

▼進む・戻る・更新

$driver->navigate()->forward();  // 進む
$driver->navigate()->back();     // 戻る
$driver->navigate()->refresh();  // 更新

基本型のサンプル

下記の「testLogin($url)」のトコを自サイトにあわせてゴニョゴニョ修正する必要あり。

<?php
  use Facebook\WebDriver\Chrome\ChromeDriver;
  use Facebook\WebDriver\WebDriverBy;
  use Facebook\WebDriver\WebDriverExpectedCondition;
  
  require_once __DIR__ . '/vendor/autoload.php';
  
  function makeChrom() {
    putenv('webdriver.chrome.driver=' . __DIR__ . '\bin\chromedriver.exe');
    return ChromeDriver::start();
  }
  
  function openChrom($url) {
    // Chromeを起動
    $driver = makeChrom();
    
    // URLを開く
    $driver->get($url);
    
    // adding cookie
    $driver->manage()->deleteAllCookies();
    $cookie = new Cookie('cookie_name', 'cookie_value');
    $driver->manage()->addCookie($cookie);
    
    return $driver;
  }
  
  // ===========================================================
  function testLogin($url) {
    // URLをChromeで開く
    $driver = openChrom($url);
    
    // フォームを取得(「id="〇〇〇〇"」を取得)
    $elmForm = $driver->findElement(WebDriverBy::id(〇〇〇〇));
    
    // ログインIDをセット(「name="email"」にセット)
    $elmForm->findElement(WebDriverBy::name('email'))->sendKeys(〇〇〇〇);
    
    // ログインPWをセット(「name="pwd"」にセット)
    $elmForm->findElement(WebDriverBy::name('pwd'))->sendKeys(〇〇〇〇);
    
    // form送信
    //$elmForm->submit();  // 送信ボタンクリックでJSを走らせてゴニョゴニョさせているなら、コレは使えない。
    $elmForm->findElement(WebDriverBy::id('btnLogin'))->click();  // (「id="btnLogin"」をクリック)
    
    // 例外処理が走って落ちるので・・・sleep()にする
    //$driver->wait()->until(
    //    WebDriverExpectedCondition::titleContains('About')
    //);
    //$aryElms = $driver->findElements(WebDriverBy::tagName('h2'));
    //foreach ( $aryElms as $rowElm ) {
    //  echo $rowElm->getText() . "\n";
    //}
    
    // ▼sleep()よりは「do-while()」で毎秒チェックさせるのがよさげ
    sleep(5);
    
    // 現在のURLが「https://〇〇〇〇/」だったら「h2」タグのテキストを全部出力
    if ( $driver->getCurrentURL() == 'https://〇〇〇〇/' ) {
      // findElements:まとめて取得(複数形になる)
      $aryElms = $driver->findElements(WebDriverBy::tagName('h2'));
      foreach ( $aryElms as $rowElm ) {
        echo $rowElm->getText() . "\n";
      }
    }
    else {
      echo 'err' . "\n";
    }
    
    // 上記のsleepよりは下記のほうが良さげ
    // $cnt = 0;
    // do {
    //   if ( タイトルが等しいかチェックなどの諸条件 ) {
    //     break;
    //   }
    //   
    //   sleep(1);
    //   $cnt++;
    // }
    // while( 10 < $cnt ); // 最大回数
    
    //調べていたら「close()」と「quit()」の表記があった。どっちが正解なのかは不明だけど、どっちもエラーにはならない
    //$driver->close();
    $driver->quit();
  }
  
  // ログインフォームのテスト
  $url = 'https://〇〇〇〇〇〇';
  testLogin($url);

関連項目

PHP、セレニウムを使ってみる

公式

facebook/php-webdriver - PHPで使うメソッドたちの説明とか