■ Windows アプリケーションで Web ページを表示 ■
.NET Framework 2.0 では、HTML 等の Web ページを Windows フォーム上に表示する為の WebBrowser コントロール(System.Windows.Forms 名前空間)が新たに追加されて居り、非常に手 軽にWeb ページの表示が出来る様に成って居る(.NET Framework 1.x では、ActiveX コントロールで 有るIE 用のコンポーネントを直接利用する必要が有り、少し面倒だった)。
WebBrowser コ ン ト ロ ー ル を 利 用 す る に は 、 WebBrowser ク ラ ス の イ ン ス タ ン ス を 生 成 し て WebBrowser コントロールを作成し、フォーム上に追加する。後は表示し度い Web ページの URL を(文 字列等で)パラメータに指定して、WebBrowser コントロールの Navigate メソッドを呼び出す丈で有 る。次のコードは、此れを実際に実装した例で有る。
Visual Basic
Private webBrowser1 As WebBrowser Sub New( )
……省略……
' WebBrowser コントロールを作成とフォーム上に追加 webBrowser1 = New WebBrowser( )
Me.Controls.Add( webBrowser1 ) ' Web ページを表示 webBrowser1.Navigate( "http://www.atmarkit.co.jp/fdotnet/" ) End Sub C#
private WebBrowser webBrowser1; public Form1( )
{
……省略……
// WebBrowser コントロールを作成とフォーム上に追加 webBrowser1 = new WebBrowser( );
this.Controls.Add( webBrowser1 ); // Web ページを表示 webBrowser1.Navigate( "http://www.atmarkit.co.jp/fdotnet/" ); } 此れを実行すると、右の様な画面が表示される筈で有る。
猶、WebBrowser コントロールは、Visual Studio 2005 のツールボックス 内に標準で提供されるコモンコントロールで有る。従って、通常のコント ロールと同じ様に、ツールボックスからWidows フォームデザイナ上にド ラッグ&ドロップで追加する事も出来る。
W
■ WebBrowser コントロールに依り Web ページからリンクや画像を抽出 ■
Web ページの HTML からリンク文字列(及び、其の URL)や画像の URL を抜き出し度い場合、単純 な方法と仕ては、HTML ドキュメントをダウンロードし、正規表現等に依り<A>タグや<IMG>タグを 抜き出す事が出来る。併し、此の方法では、HTML ドキュメントの構造が複雑な場合や、ページ作成者 のタグの閉じ忘れ等迄に対応し様とすると非常に困難に成る。
其の様な場合には、.NET Framework 2.0 の標準コントロールで有る WebBrowser コントロール (System.Windows.Forms 名前空間)を利用すると良い。此れは IE の描画エンジンをコントロール化 した物で、対象と成る Web ページを此のコントロールに表示させた時点で IE の描画エンジンが其の HTML ドキュメントを解析して居る為、其れに含まれる各 HTML 要素には、後述する.NET Framework のクラスを使って簡単にアクセス出来る。
本来、WebBrowser コントロールは Windows アプリケーション上に Web ページや HTML で記述され たヘルプやドキュメントを表示させる為の物だが、GUI を持たないアプリケーションでも其の機能は利 用可能で有る。本稿ではコンソールアプリケーションからWebBrowser コントロールを使用し、指定さ れたWeb ページからリンク文字列を抜き出す方法を示す。
■ Web ページからリンク文字列を抜き出すサンプルプログラム
Windows アプリケーションで WebBrowser コントロールに依り単に Web ページを表示する場合には、 Visual Studio でフォームに WebBrowser コントロールを配置しておき、其の Navigate メソッドを呼 び出す丈で良い(「TIPS:Windows アプリケーションで Web ページを表示するには?」参照)。 今回のケースでは、以下の様な手順に依りWebBrowser コントロールを使用し、Web ページ内の HTML 要素にアクセスする。 1.WebBrowser コントロールをインスタンス化する 2.Navigate メソッドに依り Web ページに移動する 3.ページ取得が完了するのを待つ 4.Document プロパティから HtmlDocument オブジェクトを得る 5.HtmlDocument オブジェクトから各要素(HtmlElement オブジェクト)にアクセスする ポイントと成るのは、3 のページ取得完了を待つ処理が必要と成る点だ(WebBrowser コントロールで はページの取得は非同期に行われる為、Navigate メソッドの呼び出し自体はすぐに完了する)。 ここではまず、上記の手順を実装したサンプルプログラムを示す。此のプログラムはInsider.NET のト ップ・ページに含まれるすべてのリンク文字列と其のURL を表示する。 Visual Basic Imports System Imports System.ComponentModel Imports System.Windows.Forms Public Class NonDispBrowser Inherits WebBrowser
Dim done As Boolean
' タイムアウト時間(10 秒)
Dim timeout As New TimeSpan( 0, 0, 10 )
Protected Overrides Sub OnDocumentCompleted( _
ByVal e As WebBrowserDocumentCompletedEventArgs ) ' ページにフレームが含まれる場合にはフレーム毎に
' 此のメソッドが実行される為、実際の URL を確認する If e.Url = Me.Url Then
done = True End If End Sub
Protected Overrides Sub OnNewWindow( ByVal e As CancelEventArgs ) ' ポップアップウィンドウをキャンセル
e.Cancel = True End Sub
Public Sub New( )
' スクリプトエラーを表示しない Me.ScriptErrorsSuppressed = True End Sub
Public Function NavigateAndWait( ByVal url As String ) As Boolean MyBase.Navigate( url ) ' ページの移動
done = False
Dim start As DateTime = DateTime.Now
While done = False
If DateTime.Now - start > timeout Then ' タイムアウト Return False End If Application.DoEvents( ) End While Return True End Function End Class Class GetLinks
Shared Sub main( )
Dim ndb As New NonDispBrowser
ndb.NavigateAndWait( "http://www.atmarkit.co.jp/fdotnet/" )
Dim doc As HtmlDocument = ndb.Document
' リンク文字列と其の URL の列挙
For Each e As HtmlElement In doc.GetElementsByTagName( "A" ) Dim href As String = e.GetAttribute( "HREF" ) ' HREF 属性の値 Dim text As String = e.InnerText ' リンク文字列
If ( Not String.IsNullOrEmpty( href )) _
And ( Not String.IsNullOrEmpty( text )) Then text = text.Replace( vbCrLf, "" ) ' 改行文字の削除 Console.WriteLine( href ) Console.WriteLine( text ) End If Next End Sub
C#
using System;
using System.ComponentModel; using System.Windows.Forms;
public class NonDispBrowser: WebBrowser { bool done;
// タイムアウト時間(10 秒)
TimeSpan timeout = new TimeSpan( 0, 0, 10 );
protected override void OnDocumentCompleted( WebBrowserDocumentCompletedEventArgs e) { // ページにフレームが含まれる場合にはフレーム毎に // 此のメソッドが実行される為実際の URL を確認する if ( e.Url == this.Url ) { done = true; } }
protected override void OnNewWindow( CancelEventArgs e ) { // ポップアップウィンドウをキャンセル e.Cancel = true; } public NonDispBrowser( ) { // スクリプトエラーを表示しない this.ScriptErrorsSuppressed = true; }
public bool NavigateAndWait( string url ) { base.Navigate( url ); // ページの移動
done = false;
DateTime start = DateTime.Now;
while ( done == false ) {
if ( DateTime.Now - start > timeout ) { // タイムアウト return false; } Application.DoEvents( ); } return true; } } class GetLinks { [ STAThread ]
static void Main( ) {
NonDispBrowser ndb = new NonDispBrowser( );
ndb.NavigateAndWait( "http://www.atmarkit.co.jp/fdotnet/" );
// リンク文字列と其の URL の列挙
foreach ( HtmlElement e in doc.GetElementsByTagName( "A" )) { string href = e.GetAttribute( "href" ); // HREF 属性の値
string text = e.InnerText; // リンク文字列
if ( !string.IsNullOrEmpty( href ) && !string.IsNullOrEmpty( text )) { text = text.Replace( "¥r¥n", "" ); // 改行文字の削除 Console.WriteLine( href ); Console.WriteLine( text ); } } } } プログラムの実行結果は次の様に成る。 http://www.atmarkit.co.jp/ @IT http://tech.atmarkit.co.jp/ @IT テクノロジー http://www.atmarkit.co.jp/im/ @IT 情報マネジメント http://monoist.atmarkit.co.jp/ @IT MONOist http://jibun.atmarkit.co.jp/ @IT 自分戦略研究所 http://www.atmarkit.co.jp/job/ ……以下省略…… 此のプログラムでは、WebBrowser コントロールをサブクラス化して NonDispBrowser クラスを作成 して居る。NonDispBrowser クラスの NavigateAndWait メソッドが、指定した Web ページの取得を 開始し、其れが完了する迄待つメソッドで有る。
■ ページ取得完了を待つ処理
NavigateAndWait メソッドでは、WebBrowser コントロールより継承した Navigate メソッドを呼び出 してページ取得を開始した後、done フラグが true に成る迄 Application.DoEvents メソッド呼び出し のループに依りページ取得が完了するのを待つ。
done フラグを true にセットして居るのは、ページ取得が完了した時にシステムに依り呼び出される OnDocumentCompleted メソッドで有る。
但し、対象と仕て居る Web ページにフレームが含まれて居る場合には、フレーム内容の取得が完了し た場合にも此の OnDocumentCompleted メソッドが呼び出される。此の為プログラムでは、其の時に 取得が完了したURL(コードでは e.Url)と最終的に取得し度い URL(WebBrowser コントロールの Url プロパティの値)が一致した場合に而巳 done フラグを true にして居る。
併し、此の処理丈では、他の URL にリダイレクトされる様なページの取得は正しく処理出来ない (WebBrowser コントロールの Url プロパティの値がリダイレクト後の URL と成る為)。此の為、一定 時間(上記のコードでは10 秒間)内に done フラグが true に成らない場合には強制的にループを抜け る様にして居る。
■ ポップアップウィンドウの抑制
今回はGUI を持たないアプリケーションでの使用を目的と仕て居るので、WebBrowser コントロール が別ウィンドウを開こうとするのを阻止しなければ成らない。此れは、新しいウィンドウが開く直前に システムに依り呼び出される OnNewWindow メソッドにおいて、メソッドのパラメータで渡される CancelEventArgs オブジェクト(System.ComponentModel 名前空間)の Cancel プロパティに true をセットする事で可能と成る。
亦、デフォルトでは、対象と成るWeb ページに実行エラーと成るスクリプト(JavaScript のコード等) が含まれて居る場合、スクリプトエラーを示すダイアログが表示されて了う。此れを抑制するには WebBrowse コントロールの ScriptErrorsSuppressed プロパティを true にして置けば良い。
■ HtmlDocument オブジェクトと HtmlElement オブジェクト Web ページの取得が完了すれば、其の HTML ドキュメントには Document プロパティからアクセス出 来る。 HTML ドキュメントは HtmlDocument オブジェクト(System.Windows.Forms 名前空間)で表され、 此 れ は HTML ド キ ュ メ ン ト に 含 ま れ る 各 HTML 要 素 を HtmlElement オ ブ ジ ェ ク ト (System.Windows.Forms 名前空間)のコレクションと仕て保持して居る(此のコレクションは HtmlElementCollection クラス(System.Windows.Forms 名前空間)に依り表される)。
HtmlElement クラスには親要素や子要素(のコレクション)を示す Parent プロパティや Children プ ロパティが有り、HTML ドキュメントは 1 つのツリー構造で表現されて居る。此の為ツリー構造を辿 り乍ら、任意の要素にアクセスする事も出来るが、特定のタグを持つ要素丈を列挙する場合には、 HtmlDocument オブジェクトの GetElementsByTagName メソッドを使うのが便利で有る。 GetElementsByTagName メソッドのパラメータには「A」や「IMG」と謂ったタグ名を文字列で指定 して呼び出す(大文字小文字は区別されない)。此れに依り、其のタグ名を持つHtmlElement オブジェ クトのコレクションが取得出来、其の各要素に付いて GetAttribute メソッドに依りタグの属性値を、 InnerText プロパティに依り其のタグ内に含まれるテキストを取得出来る。
■ WebBrowser コントロール内の HTML 要素から class 属性の値を取得 ■
前述の「WebBrowser コントロールに依り Web ページからリンクや画像を抽出」で示して居る様に、 WebBrowser コントロール(System.Windows.Forms 名前空間)を使えば、Web ページを取得して、 其処から特定のタグの要素を抜き出すと謂った事が可能で有る。 此 の 様 に し て 取 得 し た HTML 要素 は、上記 の項でも 示して居 る様 に、 HtmlElement クラ ス (System.Windows.Forms 名前空間)のオブジェクトと仕て表され、更には、其の GetAttribute メソ ッドに依り、任意の属性の値も取得出来る。 例えば、下記のコードは、変数e が HtmlElement オブジェクトを参照して居り、其の要素の href 属性 の値を取得して居る。 Visual Basic
Dim Href As String = E.GetAttribute( "href" ) ' href 属性の値の取得 C#
string href = e.GetAttribute( "href" ); // href 属性の値の取得
但し、GetAttribute メソッドの利用には 1 つ大きな注意点が有り、class 属性の値を取得する場合に限 り、其の属性名を「className」と記述しなければ成らない。
Visual Basic
Dim C As String = E.GetAttribute( "className" ) ' class 属性の値の取得 C#
string c = e.GetAttribute( "className" ); // class 属性の値の取得 class 属性の値の取得
メソッドの引数には「className」と指定する必要が有る。猶、GetAttribute メソッドでは属性名の 大文字小文字は区別されない。
引数に「"class"」と指定すると、仮令 class 属性が存在して居いても、GetAttribute メソッドの戻り値 は空文字と成る為、注意が必要で有る。
因みに、JavaScript の getAttribute 関数に於いても、IE7 迄は class 属性値を取得するには引数と仕て 「'className'」を指定する必要があったが、IE8 では、Firefox 等の他のブラウザと同様に、「'class'」 と指定出来る様に成って居る(猶、WebBrowser コントロールに於ける GetAttribute メソッドの挙動 は、インストールされて居るIE のバージョンとは関係ない)。
■ WebBrowser コントロールのコンテンツを文字列に依り設定 ■
Windows フォーム用の WebBrowser コントロール(.NET Framework 2.0 以降で利用可能)では、Uri プロパティにURL を設定するか、URL を引数にして Navigate メソッドを呼び出し、ページを表示す るのが一般的だが、HTML コードの文字列を Web ページと仕て表示する事も可能で有る。此処では其 の方法を2 つ紹介する。
■ DocumentText プロパティに依る表示
1 つ目の方法は非常にシンプルで、WebBrowser コントロールの DocumentText プロパティに、HTML の内容を含んだ文字列をセットする丈で有る。
次のサンプルコードでは、WebClient クラス(System.Net 名前空間)に依り Insider.NET のトップペ ージのHTML を取得し、其れを WebBrowser コントロールに表示して居る。
Visual Basic
' HTML データの取得
Dim Wc As New WebClient( ) Wc.Proxy = Nothing
Wc.Encoding = System.Text.Encoding.GetEncoding( "Shift_JIS" )
Dim Html As String = Wc.DownloadString( "http://www.atmarkit.co.jp/fdotnet" ) WebBrowser1.DocumentText = html
C#
// HTML データの取得
WebClient wc = new WebClient( ); wc.Proxy = null;
wc.Encoding = System.Text.Encoding.GetEncoding( "Shift_JIS" );
string html = wc.DownloadString( "http://www.atmarkit.co.jp/fdotnet" ); webBrowser1.DocumentText = html;
DocumentText プロパティに依り HTML を表示
変数webBrowser1 は WebBrowser コントロールを参照して居る物とする。亦、WebClient クラスを 使用して居る為、System.Net 名前空間のインポートが必要で有る。
WebClient クラスの使い方に付いては、オンラインヘルプを参照され度い。
猶、当然乍、相対 URL で記述されて居る要素(絶対 URL で記述されて居ない要素。例えば「<img src="images/fdotnet_m.gif">」)に付いては、正しく表示等が行えない。 ■ OpenNew/Write メソッドに依る表示 今1 つの方法は、WebBrowser コントロールに表示されて居るドキュメントを示す HtmlDocument オ ブジェクト(Document プロパティから取得出来る)に対して、Write メソッドに依り HTML を書き 込む方法で有る。メソッドの引数には HTML の内容を含んだ文字列を指定する。此の時、事前に OpenNew メソッドを呼び出す事に依り、現在表示中のドキュメントの内容をクリア出来る。 但し、アプリケーションの起動直後は、WebBrowser コントロールに HtmlDocument オブジェクトが 割り当てられて居ない。此の為、下記のサンプルコードの様に、Navigate メソッドに依り空白ページ に移動する等して、WebBrowser コントロールにページ表示をさせる処理が最初に必要と成る。
Visual Basic
' HTML データの取得
Dim Wc As New WebClient( ) Wc.Proxy = Nothing
Wc.Encoding = System.Text.Encoding.GetEncoding( "Shift_JIS" )
Dim Html As String = Wc.DownloadString( "http://www.atmarkit.co.jp/fdotnet" ) ' アプリケーション起動直後はドキュメントが存在しない
If WebBrowser1.Document = Nothing Then
WebBrowser1.Navigate( "about:blank" ) ' 空白ページを開く End If WebBrowser1.Document.OpenNew( True ) ' クリア WebBrowser1.Document.Write( Html ) ' 書き込み C# // HTML データの取得
WebClient wc = new WebClient( ); wc.Proxy = null;
wc.Encoding = System.Text.Encoding.GetEncoding( "Shift_JIS" );
string html = wc.DownloadString( "http://www.atmarkit.co.jp/fdotnet" ); // アプリケーション起動直後はドキュメントが存在しない if ( this.webBrowser1.Document == null ) { webBrowser1.Navigate( "about:blank" ); // 空白ページを開く } webBrowser1.Document.OpenNew( true ); // クリア webBrowser1.Document.Write( html ); // 書き込み Write メソッドに依り HTML を表示
変数webBrowser1 は WebBrowser コントロールを参照して居る物とする。亦、WebClient クラスを 使用して居る為、System.Net 名前空間のインポートが必要で有る。 猶、OpenNew メソッドの引数には、WebBrowser コントロールが保持する履歴の現在のエントリを新 しいドキュメントで置き換えるか何うかを指定する。 ■ 2 つの方法の違い 以上、2 つの方法を示したが、DocumentText プロパティに文字列をセットした場合には、Navigating、 Navigated、DocumentCompleted 等のイベントが発生するのに対して、Write メソッドで文字列を書 き込んだ場合には、此等のイベントは発生しない。此れが2 つの方法の大きな違いと謂える。
■ WebBrowser コントロール内のテキストボックスに文字列をセットする ■
Windows フォームには、Windows アプリケーション内に Web ページを表示する為の WebBrowser コ ントロールが用意されて居る。此のWebBrowser コントロールでは、指定したページへの移動や、戻る、 進む等のブラウザと同様の操作に加え、コントロールで表示されて居るドキュメント内の要素をプログ ラムから操作する事も可能で有る。 本稿では、WebBrowser コントロールに表示されて居る入力フォーム内のテキストボックスにプログラ ムから値を入力し、更に、其のフォームをサブミット(フォームの内容を送信)する、或いはフォーム に有るボタンをクリックする方法を紹介する。此の方法に依り、Web アプリケーションのテストや、 Web アプリケーションへの自動ログイン等が可能に成る。 ■ Google の検索ページを操作するサンプルプログラム 此処では最初に、本稿で作成するサンプルプログラムの動作を説明する。此れは3 つのボタンと 1 つの WebBrowser コントロールを配置した Windows アプリケーション(下図参照)で、此等 3 つのボタン でGoogle の検索ページを操作する。 具体的には、プログラム起動時にGoogle の検索ページが表示され、此処で[検索語の入力]ボタン(下 図の① )をクリックすると、ページに表示されて居るテキストボックスに「C#」と謂う文字列が自動 的に入力される。更に、② 或いは ③ のボタンをクリックすると、検索が実行されて検索結果ページ が表示される。
此の様にプログラムからWeb ページを操作する場合、事前に其の HTML のソースをチェックして、操 作対象と成るHTML 要素を明確にして置く必要が有る。Google の検索ページのソースを見ると、フォ ームの定義部分で次の様な記述を見付ける事が出来る。
<form action="/search" name=f >
<input name=q size=55 value="" …… >
<input name=btnG type=submit value="Google 検索" …… > ……
Google の検索ページ内のフォーム定義部分(抜粋)
此の記述から、フォーム(<form>要素)には「f」と謂う名前(name 属性)が付けられて居り、亦テ キストボックス(<input>要素)には「q」、[Google 検索]ボタン(サブミット・ボタン。「type=submit」 と謂う属性が付いて居る<input>要素)には「btnG」と謂う名前が付けられて居る事が分かる。 以上が確認出来れば、それぞれの名前で各 HTML 要素を検索し、其れを外部から操作する事が可能に 成る。 ■ 3 つのボタンのイベントハンドラの内容 Web ページの表示内容は HTML 要素(HTML タグ)の集まりで有るが、WebBrowser コントロールの ドキュメント上では、此等の要素はHtmlElement クラス(System.Windows.Forms 名前空間)のオブ ジェクトで表される。亦、HtmlElement オブジェクトのコレクションと仕て、HtmlElementCollection クラス(System.Windows.Forms 名前空間)が定義されて居る。
一方、WebBrowser コントロールのドキュメントは、HtmlDocument クラス(System.Windows.Forms 名前空間)のオブジェクトで表され、此れは WebBrowser コントロールの Document プロパティから 取 得 出 来 る 。 然 し て 、 其 の All プ ロ パ テ ィ か ら は 、 ド キ ュ メ ン ト 内 の 全 要 素 を 含 ん だ HtmlElementCollection オブジェクトを取得出来る。 以上を踏まえた上で、上記サンプルプログラムの3 つの操作の内容を次に示す。猶、上記サンプルプロ グ ラ ム で は 、WebBrowser コントロールをフォームに配置する際に、其の Url プロパティに 「http://www.google.co.jp」をセットして、起動時に Google の検索ページが開く様にして居る。 ■ テキストボックスに文字列をセット 特定のテキストボックスに文字列をセットするには、其のテキストボックスを表すHtmlElement オブ ジェクトを取得し、其れに含まれるテキストをInnerText プロパティに依り設定する事が出来る。 従って、上記サンプルプログラムの[検索語の入力]ボタンのイベントハンドラは次の様に成る。 Visual Basic
Private Sub Button1_Click( ByVal sender As System.Object, ByVal e As System.EventArgs ) _ Handles Button1.Click
Dim All As HtmlElementCollection = WebBrowser1.Document.All Dim Forms As HtmlElementCollection = All.GetElementsByName( "q" ) Forms( 0 ).InnerText = "c#" ' テキストボックスに「C#」を入力
End Sub C#
private void button1_Click( object sender, EventArgs e ) {
HtmlElementCollection all = webBrowser1.Document.All; HtmlElementCollection forms = all.GetElementsByName( "q" ); forms[ 0 ].InnerText = "c#"; // テキストボックスに「C#」を入力
GetElementsByName メソッドは、コレクションで有る HtmlElementCollection オブジェクトから、 特定の名前を持つ要素を取得する為の物で有る。複数の要素が同じ名前を持つ可能性が有る為、此のメ ソッドの戻り値もHtmlElementCollection オブジェクトと成る。 此のコードでは、「q」と謂う名前の要素は 1 つと謂う前提で記述して居るが、通常はプロパティにアク セスする前に、コレクションの要素数をチェックす可きで有る。 ■ フォームのサブミット フォームのサブミットでは、上記と同様に、先ず、要素名からフォームを表すHtmlElement オブジェ クトを取得する。然して、「"submit"」と謂う引数で InvokeMember メソッドを呼び出せば良い。コー ドは次の様に成る。 Visual Basic
Private Sub Button2_Click( ByVal sender As System.Object, ByVal e As System.EventArgs ) _ Handles Button2.Click
Dim All As HtmlElementCollection = WebBrowser1.Document.All Dim Forms As HtmlElementCollection = All.GetElementsByName( "f" ) Forms( 0 ).InvokeMember( "submit" ) ' フォームのサブミット
End Sub C#
private void button2_Click( object sender, EventArgs e ) {
HtmlElementCollection all = webBrowser1.Document.All; HtmlElementCollection forms = all.GetElementsByName( "f" ); forms[ 0 ].InvokeMember( "submit" ); // フォームのサブミット } [フォームのサブミット]ボタン(②)のイベントハンドラ ■ ボタンのクリック 上記の様にフォームを直接サブミットする代わりに、サブミットボタンをクリックしてもフォームをサ ブミット出来る。ボタンをクリックするには、其のボタンの HtmlElement オブジェクトを取得し、 「"submit"」と謂う引数で InvokeMember メソッドを呼び出す。 Visual Basic
Private Sub Button3_Click( ByVal sender As System.Object, ByVal e As System.EventArgs ) _ Handles Button3.Click
Dim All As HtmlElementCollection = WebBrowser1.Document.All
Dim Forms As HtmlElementCollection = All.GetElementsByName( "btnG" ) forms( 0 ).InvokeMember( "click" ) ' ボタンのクリック
End Sub C#
private void button3_Click( object sender, EventArgs e ) {
HtmlElementCollection all = webBrowser1.Document.All;
HtmlElementCollection forms = all.GetElementsByName( "btnG" ); forms[ 0 ].InvokeMember( "click" ); // ボタンのクリック
}
■ HTML 要素の其他の探し方
今回はname 属性の値が事前に解って居た為、GetElementsByName メソッドに依り HTML 要素のオ ブジェクトを特定した。name 属性ではなく、id 属性が付けられて居る場合には、id 属性の内容で HTML 要素を検索するGetElementById メソッドが使える(下記は、id="username" を取得する例)。
Visual Basic
Dim UsernameTextbox As HtmlElement = _
webBrowser1.Document.GetElementById( "username" ) C# HtmlElement usernameTextbox = webBrowser1.Document.GetElementById( "username" ); HTML 要素に name 属性や id 属性が付けられて居ない場合には、GetElementsByTagName メソッド を使って、HTML 要素のタグ名から検索する方法が有効で有る(<button>要素を取得する例)。 Visual Basic
Dim Buttons As HtmlElementCollection = _
webBrowser1.Document.GetElementsByTagName( "button" ) C# HtmlElementCollection buttons = webBrowser1.Document.GetElementsByTagName( "button" ); 此の場合には、通常複数のHTML 要素が見付かる為、HTML 上での並び順や、属性の値(GetAttribute メソッドに依り属性名から其の値を取得可能)を手掛かりにして、HTML 要素を絞り込む必要が有る。 ■ WebBrowser コントロールで選択されて居る文字列をコピーする ■ WebBrowser コントロールの HTML ドキュメントに対する操作は、前述の「WebBrowser コントロー ルに依り Web ページからリンクや画像を抽出」の最後で示して居る様に、ドキュメント内の特定の HTML 要素を取得してから行う事が多いが、此れとは別に、現在のドキュメントに対してコマンドを実 行すると謂う方法を採る場合が有る。
コマンドの実行には、WebBrowser コントロールの Document プロパティから HtmlDocument オブジ ェクト(System.Windows.Forms 名前空間)を取得し、其の ExecCommand メソッドを呼び出して行 う。 WebBrowser コントロールに表示されて居る HTML ドキュメントに於いて、現在選択されて居る文字 列のクリップボードへのコピーは、「Copy」コマンドで可能で有る。此れは次の様なコードに依り実行 する。 Visual Basic
webBrowser1.Document.ExecCommand( "Copy", False, Nothing ) C#
webBrowser1.Document.ExecCommand( "Copy", false, null );
ExecCommand メソッドの第 2 引数にはコマンド固有のダイアログを表示するか何うかを、第 3 引数に はコマンドに必要なパラメータを指定するが、此等が使用されるか何うかはコマンドの種類に依って異 なる。Copy コマンドの場合には、孰れも使用されない。
猶、ExecCommand メソッドで実行可能なコマンドの一覧は、MSDN の Command Identifiers に記載 されて居る。Copy コマンド以外では、Web ページを保存する「SaveAs」や、Web ページの印刷を行
■ Firefox の描画エンジン(Gecko エンジン)で Web ページを表示 ■
前述の「Windows アプリケーションで Web ページを表示する」では、Windows フォーム上に Web ブ ラウザコントロールを配置する方法を紹介して居る。Web ブラウザコントロールとは、Web ページを 表示する為のコントロールで、此の項では、WebBrowser コントロール(System.Windows.Forms 名 前空間)と謂う.NET Framework 2.0 に含まれる Windows フォームコントロールを利用して居る。 此のWebBrowser コントロールは、(其の内部で)Web ページの描画に IE(Internet Explorer)のレ ンダリングエンジンを利用する。併し、最近では世界全体でFirefox が約 15%迄ブラウザシェアを伸ば して来て居り(参考:Market Share : Browser Market Share for September, 2007)、レンダリングエ ンジンにもFirefox と同等の物(「Gecko エンジン」と呼ばれる)を使い度いと謂うニーズも少なくない だろう(例えば、国内で人気の高いカスタムブラウザ Sleipnir にも Gecko レンダリングのモードが有 る)。
其処で、此処ではFirefox で使われて居る Gecko エンジンに依るレンダリングが行える Web ブラウザ コントロールの利用方法を紹介する。
■ Gecko エンジンの Web ブラウザコントロールを利用
実はFirefox で使われて居る Gecko エンジンは、Firefox 本体と静的にコンパイルされて居る為、其の 儘外部から利用する事が出来ない。Firefox のソースコードから Gecko エンジンを抜き出す事も不可能 では無いと思うが、現実的に考えて其れでは余りにも手間が掛かり過ぎる。其れでは、もっと手軽に Gecko エンジンを利用する方法は無いのだろうか。
Gecko エンジンは、様々なプロジェクトで活用されて居る。例えば、Firefox 丈でなく、Netscape(Web ブラウザ)やThunderbird(メールクライアント)、SeaMonkey(インターネット統合アプリケーショ ン*1)、XULRunner(XUL アプリケーションのランタイムパッケージ*2)等で有る。此等の内、 SeaMonkey や XULRunner では Gecko エンジンの ActiveX コントロール版が同梱されて居るので、此 のActiveX コントロールを利用すると謂う方法が有る。
※1 此のインターネット統合アプリケーションには、タブ方式の Web ブラウザ、メールクライアント、 WYSIWYG 形式の HTML 編集ツール等が含まれて居る。
※2 XUL は「XML ユーザーインターフェイス言語」を意味し、Mozilla に依りデスクトップアプリケ ーション開発の為に提供されて居る。XULRunner は、Gecko エンジンを利用するランタイム環境 の為、「(新)GRE(Gecko Runtime Environment)」とも呼ばれる(因み、新 GRE に対して Mozilla Application Suite の一部が「旧 GRE」と呼ばれて居る)。
詰まり、例えばXULRunner をクライアント環境にインストールすれば、其の ActiveX コントロールを 利用してGecko エンジンに依る Web ページレンダリングが実現出来ると謂う訳で有る。以下では、此 の方法に付いて説明する。 ■ XULRunner のインストール 先ずは、最新のXULRunner をインストールする事にする。此れは、下記の FTP サイトで入手する事 が出来る。 XULRunner の Nightly ビルドの最新版 上 記 の サ イ ト で 、xulrunner-*.***.en-US.win32.zip ( 本 稿 執 筆 時 点 で の 最 新 バ ー ジ ョ ン は xulrunner-1.9a9pre.en-US.win32.zip)をダウンロードして、.zip ファイルに格納されて居る xulrunner フォルダを、任意の場所(本稿の例では「D:¥xulrunner」)に展開する。
此の中に含まれるmozctlx.dll が、Gecko エンジンの Web ブラウザコントロール(ActiveX 版)で有る。 拠って、此のActiveX コントロールを regsvr32.exe*3 を使って、レジストリに登録する。此れには、 コマンドプロンプトを立ち上げ(此れには、例えば[スタート]メニューから[ファイル名を指定して 実行]を表示して「cmd」を入力して実行する)、本稿の例では、次の様なコマンドを入力すれば良い。 regsvr32 D:¥xulrunner¥mozctlx.dll Gecko エンジンコントロール(ActiveX 版)をシステムに登録するコマンド
※3 regsvr32 は Windows に付属するコンソールプログラムで、ActiveX 等の COM コンポーネントを システムに登録する際に使う。コマンドライン引数に COM コンポーネント(.DLL ファイル)へ のパスを指定すれば登録される。猶、登録を解除するには、「/u」オプションを付加して呼び出せば 良い。
以上でXULRunner のインストールは完了で有る。 ■ Visual Studio での ActiveX コントロールの活用
ActiveX コントロールがインストール出来れば、後は通常の ActiveX コントロールを利用するのと同じ 手順で有る。一応、念の為、其の手順を画面で示して置く。
猶、以下ではVisual Studio 2005 を利用して居る。亦、以降では、ActiveX コントロールの「Gecko エ ンジンWeb ブラウザコントロール」は「AxMozillaBrowser」と表記。 先ずは、ツールボックスにAxMozillaBrowser のアイコンを追加する。此れには、ツールボックス上で 右クリックして、表示されるコンテキストメニューから[アイテムの選択]をクリックする。然うする と、次の様な[ツールボックスアイテムの選択]ダイアログが表示される。 [ツールボックスアイテムの選択]ダイアログの[COM コンポーネント]タブを開き、「MozillaBrowser Class」(パスは本稿の例では「D:¥xulrunner¥mozctlx.dll」と成って居る)を選択して[OK]ボタン をクリックする。此れに依り、[ツールボックス]に「MozillaBrowser Class」と謂うコントロールが 追加される。此処で、更に解り易い様に「MozillaBrowser Class」から「AxMozillaBrowser」等に[ア イ テ ム 名 の 変 更 ] を し て も 良 い 。 以 上 で Visual Studio の Windows フ ォ ー ム デ ザ イ ナ 上 に AxMozillaBrowser を配置可能に成る。次の画面は実際に、AxMozillaBrowser を Windows フォーム上 に配置して、其のDoc プロパティに Fill を指定した処で有る。
上記の画面の手順で Windows フォーム上に配置する処迄出来た。後は、AxMozillaBrowser コントロ ールのNavigate メソッドを呼び出せば、其のブラウザコントロール内に好きな URL の Web ページを 表示出来る。メソッドの第1 パラメータに URL を指定する。例えば、フォームの Load イベントハン ドラで@IT/Insider.NET のトップページを表示するには、次の様なコードに成る。
Visual Basic
Private Sub Form1_Load( ByVal sender As System.Object, ByVal e As System.EventArgs ) _ Handles MyBase.Load
AxMozillaBrowser1.Navigate( "http://www.atmarkit.co.jp/fdotnet/" ) End Sub
C#
private void Form1_Load( object sender, EventArgs e ) { axMozillaBrowser1.Navigate( "http://www.atmarkit.co.jp/fdotnet/" ); } 此れを実行すると、右の画面の様に成る。 此の例では、@IT/Insider.NET のトップページが Gecko レンダリングに依って表示されて居る。