結果だけでなく過程も見てください

たい焼きさんの日々の奮闘を綴る日記です。

perlでWebクライアント (3) Seleniumを使う

前回の続きです。

前回はWWW::Mechanizeの使用を試みましたが、
色々と調べた結果、ボタンがJavaScriptになっているものは
JavaScript部分を自分で実装する必要があり、
難易度が高く挫折してしまう人が多いとのことでした。

自分はWebの知識がほとんどないので、これに代わる簡単な方法はないものかと
探していたところ見つけたのが、SeleniumというWebテストツールを使う方法でした。
PerlにはTest::WWW::Seleniumというモジュールがあるので、これを使えばいけそうですね。

SeleniumはもともとWebアプリケーションのテストを自動的に行うもので、
例えば・・・

1.テキストボックスに数値を入れてボタンを押す。
2.遷移したページで「このボタンをクリック」というリンクを探してクリックする
3.遷移先は1.で入れた値を計算して表示するページ。そのページに正しい値が表示されているかチェックする

といったことが可能です。

今回自分がやりたいことは

1.フォームにIDとパスワードを入れる
2.ボタン(JavaScriptで実行されるもの。今回の最大の敵)を押す
3.遷移先のページにあるテキストボックスに単語を入力
4.検索ボタンを押す
5.画面に出力された結果から必要な情報を取り出しcsvとかで出力

というものです。どうでしょう、Seleniumを使えばなんとなくできそうですね。

それではさっそくSeleniumを導入してみましょう。
プラットフォームはWindowsです。
Seleniumを使用するための構成は以下の図のようになります。


各アプリケーションのバージョン

当方のバージョンを書いておきます。すべてWindowsです。

Firefox 15.0.1
Selenium IDE 1.7.3
Selenium IDE:Perl Formatter 1.0.3
Selenium RC 2.25.0
JDK 1.6.0_23
Firebug 1.10.3

Firefox周りのインストール

FirefoxFirefoxのアドオンSelenium IDEPerl Formatterをインストールしてください。
http://www.mozilla.jp/firefox/

Selenium IDEFirefoxで行った一連の操作(テストケースと呼びます)の
記録、編集、デバッグを行うことができます。

Perl FormatterはSelenium IDEのテストケースをPerlスクリプトとして出力するものです。
このスクリプトを実行すればSelenium IDEのテストが実行されるというわけです。

Selenium RCのインストール

Selenium RCはテストをするホストで動作します。
テストケースが始まるとIEFirefoxchromeなどのブラウザを起動してテストを実施します。
Selenium RCが任意のブラウザをキックできるので、1つテストケースを用意
すれば様々なブラウザでテストすることが可能となります。

selenium RCはJavaで動作しますので、先にJavaを入れておいてください。
入れるのはJREではなく、JDKですよ。
http://www.oracle.com/technetwork/java/javase/downloads/jdk7u7-downloads-1836413.html

続いてSelenium RCをダウンロードして任意のディレクトリ配置してください。
http://seleniumhq.org/download/

Selenium RCを起動しましょう。
C:\tempにjarファイルをダウンロードしたとすると

java -jar "C:\temp\selenium-server-standalone-2.25.0.jar" -interactive

と、コマンドプロンプトから実行してサーバを起動してください。
以下のように出力されるはずです。ポート4444でサーバ起動したことがわかりますね。
ファイアウォールは通しておいてください。

2012/09/19 21:21:59 org.openqa.grid.selenium.GridLauncher main
情報: Launching a standalone server
21:21:59.343 INFO - Java: Sun Microsystems Inc. 19.0-b09
:
21:21:59.546 INFO - Started SocketListener on 0.0.0.0:4444
21:21:59.546 INFO - Started org.openqa.jetty.jetty.Server@14a9972
Entering interactive mode... type Selenium commands here (e.g: cmd=open&1=http://www.yahoo.com)

環境変数PATHにFirefoxのモジュールがある場所を通す

Firefoxが以下のようにインストールされている場合

C:\Program Files\Mozilla Firefox\firefox.exe

環境変数PATHには以下を追加します。

C:\Program Files\Mozilla Firefox

Webページの構成

次に、対象となるWebページの構成を見てみましょう。
Webページの情報はFirefoxのアドオンFirebug等で調査しています。

ログインページは以下のようになっています。
IDとパスワードを入力してログインボタンを押下します。

ログイン後の、情報検索ページです。
検索ワードに商品名を入れて、[検索する]ボタンを押下します。

検索結果はテーブルで返ってきます。
あとは普通にHTMLを解析して情報を取得しましょう。

やってみよう

PerlSeleniumモジュールと通して上述した処理を自動化します。
商品名には「ピアノ教本」と入れて検索をしています。
まずはSelenium IDEを使用して、Seleniumに与える指示内容を作成しましょう。

ログインページに移動してSelenium IDEを起動してください。

Firefoxの[ツール]→[Selenium IDE]

Selenium IDEが起動すると、ブラウザ上で行った操作が自動的に
記録されていくはずです。当方の環境で、上で説明した操作を行った結果は以下のようになります。

なぜか、IDとパスワードの入力については反応してくれませんでした。。。
が、出力したPerlスクリプトにIDとパスワードを入力するコードを追加
すればいいので特に問題はないでしょう。

Perlコードは以下のように辿って出力してください。

Selenium IDEの[ファイル]→[テストケースをエクスポート]→[Perl]

出力されたコードです。

use strict;
use warnings;
use Time::HiRes qw(sleep);
use Test::WWW::Selenium;
use Test::More "no_plan";
use Test::Exception;

my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                    port => 4444, 
                                    browser => "*chrome", 
                                    browser_url => "http://www.sample.com/" );

$sel->click_ok("id=LoginBtn");
$sel->wait_for_page_to_load_ok("30000");
$sel->type_ok("id=SearchWord", "ピアノ教本");
$sel->click_ok("name=SearchSubmit");
$sel->wait_for_page_to_load_ok("30000");

ここにIDとパスワードを入力するコードを加えましょう。
IDを「taiyaki」、パスワードを「hogehogepass」とします。
またchromefirefoxに変えときましょう。(これは変えなくてもいいのかな?)

変更後のコードは以下のようになります。

use strict;
use warnings;
use Time::HiRes qw(sleep);
use Test::WWW::Selenium;
use Test::More "no_plan";
use Test::Exception;

my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                    port => 4444, 
                                    browser => "*firefox", 
                                    browser_url => "http://www.sample.com/" );

$sel->type_ok("id=LoginID", "taiyaki");
$sel->type_ok("id=LoginPasswd", "hogehogepass");
$sel->click_ok("id=LoginBtn");
$sel->wait_for_page_to_load_ok("30000");
$sel->type_ok("id=SearchWord", "ピアノ教本");
$sel->click_ok("name=SearchSubmit");
$sel->wait_for_page_to_load_ok("30000");

このperlスクリプトをファイルに出力して実行すれば、
自動的にFirefoxが起動し、IDとパスワードが入力され、
次々とページが遷移していくでしょう。

このコードだけだと、検索結果が表示された直後にFirefoxがkillされてしまいます。
必要に応じて以下のコードでページ情報を取得してファイル出力するなどの処理を追加してくださいね。

@html = $sel->get_body_text();

また毎回Firefoxを起動/killするのが嫌だという人は
ログインするコードの後をwhile文などで囲って定期的に
検索→結果取得を繰り返すようにしましょう。
コードとしては以下のようになるでしょうか。
ここでは検索ページのURLを「http://www.sample.com/search」としています。

use strict;
use warnings;
use Time::HiRes qw(sleep);
use Test::WWW::Selenium;
use Test::More "no_plan";
use Test::Exception;

my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                    port => 4444, 
                                    browser => "*firefox", 
                                    browser_url => "http://www.sample.com/" );

$sel->type_ok("id=LoginID", "taiyaki");
$sel->type_ok("id=LoginPasswd", "hogehogepass");
$sel->click_ok("id=LoginBtn");
$sel->wait_for_page_to_load_ok("30000");

while(1)
{
  $sel->type_ok("id=SearchWord", "ピアノ教本");
  $sel->click_ok("name=SearchSubmit");
  $sel->wait_for_page_to_load_ok("30000");

  # ここで情報を取得してファイルに追記
  my @html = $sel->get_body_text();

  # ページを検索ページに戻しておく
  $sel->open_ok( "/search" );

  # 1時間後に検索
  sleep( 3600 );
}

あまりエラーケースが考えられていませんが、
とりあえず動作させるだけならこれで十分だと思います。
自分もまだわからない部分が多いのですが、また機会をみていろいろと紹介したいと思います。

プライバシーポリシー お問い合わせ