IE制御ライブラリ

はじめに

RubyからIEを制御するのに便利なライブラリを作ってみた。 基本的な考え方は、

IE制御ライブラリ

まだ作ったばかりなので、ちょこちょこ変わると思います。DL後、"ie_lib.rb"にリネームしてください。

2003/12/4版

IE_LIB 20031204版

2003/11/30版

IE_LIB 20031130版

テストケース

RubyUnitを使ったテストケースです。

IE制御ライブラリで提供しているクラスとメソッド

IE_Wrapper

これから説明する各クラスのスーパークラス。 未定義のメソッドがあったら、IEのオリジナルオブジェクトに転送する機構とかを持っている。

raw

これから説明するクラスはIEオリジナルのオブジェクトをラップしている。 ラップオブジェクトに使えば、中身の生のIEオリジナルのオブジェクトを返す。 例えば、IE::TagElementがAタグエレメントを保持していたら、rawメソッドで生のAタグエレメントを取得できる。

IE Class

IEのOLEオブジェクトをラップするクラス。

new(visible=true)

IEを起動する。引数を省略すれば可視な状態でIEが起動します。戻り値はIEのOLEオブジェクト。

navigate(url)

urlで示されるページを表示する。IEオリジナルのnavigateと違って、ページが表示されるまで戻ってこない。

wait_stable

処理が完了するまでIEを待たせたいときに使う。

document

IEが現在表示中のドキュメントを示すIE::Documentオブジェクトを返す。

IE::Document

IEのDocumentオブジェクトをラップするクラス。

body

表示中のドキュメントのBodyエレメントを示すIE::TagElementを返す。

head

表示中のドキュメントのHeadエレメントを示すIE::TagElementを返す。

frames(index=nil)

IEが表示中のページが複数のフレームから構成されている場合、フレームのリストを示すIE::Framesオブジェクトを返す。 引数でindexを指定すると、index番目のフレームを示すIE::Frameオブジェクトを返す(最初のフレームはindex=0)。

IE::Frames

IEのFrameのコレクションをラップするクラス。

[](index)

index番目のフレームを示すIE::Frameオブジェクトを返す。index=0が最初のフレーム。

size

Frameコレクションに含まれているフレームの数を返す*2

each

Frameコレクションのイテレータ。

  IE.document.frames.each {|frame|
    p frame
  }
  

IE::Frame

IEのFrameオブジェクトをラップするクラス。各フレームの中にDocumentオブジェクトがある。

document

本フレームの中に含まれるDocumentオブジェクトを返す。

IE::TagElementCollection

IEのタグエレメントのコレクションをラップしている。この中に複数のタグエレメントが含まれている。

[](index)

index番目のタグエレメントをラップしているIE::TagElementオブジェクトを返す。

size

コレクションに含まれるタグエレメントの数を返す。

each

TagElementコレクションのイテレータ。

  IE.document.body.tags("A").each {|tag_element|
    p tag_element
  }
  
get_tag_by_title(target_str)
get_tag_by_value(target_str)
get_tag_by_text(target_str)
get_tag_by_name(target_str)
get_tag_by_option(target_str)

タグコレクションの中から目的のタグエレメントを探す。みつかったらTagElementオブジェクトを返す。 複数のTagElementがマッチした場合は配列で返される*3

この2つは正規表現で検索するので、一部でもマッチしているTagElementを返す。

IE::TagElement

IEのタグエレメントをラップするクラス。

tagName

タグの名前を返すメソッド。<IMG>タグエレメントなら"IMG"を返す。

text=

INPUTタグのように文字列の入力可能なタグに文字列をセットする。

click

クリック可能なタグエレメントをクリックする。オリジナルのclickと違って、IEの状態が安定するまで戻ってこない。

tags(tag_name)

現在のタグエレメントに含まれるタグエレメントからtag_nameで示されるタグエレメントのコレクションを返す。 戻りはTagElementCollectionオブジェクト。

まず、TABLEタグエレメントを特定し、その中に含まれるTDタグエレメントのコレクションを得るのに使う。

innerText

タグエレメントが囲んでいる文字列を返す。これで情報を得る。

使い方

Googleで検索するサンプル

役には立たないが、Googleでキーワードを検索するサンプルを示す。目的のタグを見つけるにはコツがあるので、作っていく過程とともに説明してみる。

まず、キーワードを入れるタグとボタンのタグを探すために、全部のINPUTタグエレメントを表示させてみる。

  # ie_sample_01.rb
  require 'ie_lib'
  ie = IE.new
  ie.navigate("http://www.google.com/")
  input_list = ie.document.body.tags("INPUT")
  input_list.each {|element|
    p element
  }
  
  > ruby -Ks ie_sample_01.rb
  IE::TagElement:<INPUT>:[<INPUT maxLength=256 size=55 name=q>]
  IE::TagElement:<INPUT>:[<INPUT type=hidden value=UTF-8 name=ie>]
  IE::TagElement:<INPUT>:[<INPUT type=hidden value=UTF-8 name=oe>]
  IE::TagElement:<INPUT>:[<INPUT type=hidden value=ja name=hl>]
  IE::TagElement:<INPUT>:[<INPUT type=submit value="Google 検索" name=btnG>]
  IE::TagElement:<INPUT>:[<INPUT type=submit value="I'm Feeling Lucky" name=btnI>]
  IE::TagElement:<INPUT>:[<INPUT id=all type=radio CHECKED value="" name=lr>]
  IE::TagElement:<INPUT>:[<INPUT id=il type=radio value=lang_ja name=lr>]
  

この結果から入力欄に'q'という名前がついているのがわかる。よって、input_list.get_tag_by_name("q")で入力タグが手に入る。 取得したタグエレメントに.text="xxx"で文字列を設定する。

検索ボタンは"Google 検索"というラベルが付いているので、input_list.get_tag_by_title("検索")で手に入る*4。取得したタグエレメントにclickメソッドを作用させれば検索結果が表示される。

  require 'ie_lib'
  ie = IE.new
  ie.navigate("http://www.google.com/")
  input_list = ie.document.body.tags("INPUT")
  input_list.get_tag_by_name('q').text = "ruby win32ole"
  input_list.get_tag_by_title("検索").click
  

Yahooの乗り換え案内を使ってみる

会社から帰る時に、Yahooの乗り換え案内を起動して、電車の接続を見るサンプル。 これも、同じく、まずはタグエレメントの一覧をpで表示して、目的のタグを探す。

  # ie_sample_02.rb
  require 'ie_lib'
  
  ie = IE.new
  ie.navigate("http://transit.yahoo.co.jp/")
  input_list = ie.document.body.tags("INPUT")
  input_list.each {|input_element|
    p input_element
  }
  
  > ruby -Ks ie_sample_02.rb
  IE::TagElement:<INPUT>:[<INPUT type=hidden value=select name=val_htmb>]
  IE::TagElement:<INPUT>:[<INPUT onkeypress=yj_set_focus_blur() id=yj_set_focus_here size=14 name=val_from>]
  IE::TagElement:<INPUT>:[<INPUT size=14 name=val_to>]
  IE::TagElement:<INPUT>:[<INPUT type=checkbox value=CHARGE name=val_dsmask_charge>]
  IE::TagElement:<INPUT>:[<INPUT type=checkbox value=AIR name=val_dsmask_air>]
  IE::TagElement:<INPUT>:[<INPUT type=radio value=DEP name=val_timekb>]
  IE::TagElement:<INPUT>:[<INPUT type=radio value=ARR name=val_timekb>]
  IE::TagElement:<INPUT>:[<INPUT type=radio value=LST name=val_timekb>]
  IE::TagElement:<INPUT>:[<INPUT type=radio CHECKED value=NON name=val_timekb>]
  IE::TagElement:<INPUT>:[<INPUT type=submit value=" 探  索 ">]
  

出発駅は"name=val_from"、到着駅は"name=val_to"。「出発時間指定」にチェックを入れたい。このチェックは"value=DEP"だろうと あたりをつける。探索ボタンはget_tag_by_title("探索")で探せばよい。

探索ボタンをクリックすると、ページが表示されるが、駅名が重複する場合は候補が表示される(一発で表示される場合もある)。 その場合、<SELECT>タグで候補が表示される。<SELECT>タグの候補には上記サンプルの場合、"三鷹"と"三鷹台"が表示される。

  require 'ie_lib'
  
  ie = IE.new
  ie.navigate("http://transit.yahoo.co.jp/")
  input_list = ie.document.body.tags("INPUT")
  input_list.get_tag_by_name("val_from").text = "三鷹"
  input_list.get_tag_by_name("val_to").text = "羽村"
  input_list.get_tag_by_title("DEP").click  # 「出発時間指定」にチェックを入れる
  input_list.get_tag_by_title("探索").click # 「探索」ボタンをクリック
  
  # 候補が表示される場合は、
  select_list = ie.document.body.tags("SELECT")
  select_list.get_tag_by_option("三鷹").text = "三鷹"  # もともと選択されているから不要なんだが
  input_list = ie.document.body.tags("INPUT")
  input_list.get_tag_by_title("探索").click # 「探索」ボタンをクリック
  

ミルエネのデータをダウンロード

ミルエネの電力データを数値として取得する

ライセンス

ライセンスはRubyのライセンスに従います。

Copyright (C) 2003 Oka Yasushi <yac@tech-notes.dyndns.org>

You may redistribute it and/or modify it under the same license terms as Ruby.

免責事項

本プログラムは無保証です。作者は、プログラム自身のバグ、あるいは、本プログラムの実行など から発生するいかなる損害に対しても責任を持ちません。

変更履歴

2003/12/4版
2003/11/30版

Initial Release


戻る

*1タグ要素を示すオブジェクト
*2IEにはlengthというプロパティがあるが、Ruby的にはsizeの方がすっきりするので。
*3このメソッドであまり大量のTagElementがマッチしないように注意する。 TagElementCollectionはIE内部の1個オブジェクトをラップしているだけだが、このメソッドで返される配列にたくさんのTagElementが 含まれると、TagElementの数だけIEのオブジェクトをラップすることになる。IEとCOMがどこまで耐えられるか不安だ。
*4タグについている ラベルは改行コードやスペースなどが削除された後、正規表現で探されるので、"Google 検索"では探せない。やるなら"Google検索"で 探す。
*5SELECTタグの 処理は本当は結構めんどくさい。IEライブラリでその辺を隠蔽している。