質問者
WebBrowserでHTML要素のclick処理について

質問
-
WebBrowserで画面の自動遷移制御をしたいですが、うまくいかないです。
なぜかHTML要素のbuttonにInvokeMember("click")を呼び出す後の画面更新待ちができないようです。
ソースコードをご覧ください。
WebBrowser wb = new WebBrowser();
wb.Navigate("http://www.google.co.jp");
Application.DoEvents();
while (wb.ReadyState != WebBrowserReadyState.Complete || wb.IsBusy)
{
Console.WriteLine("waiting...");
System.Threading.Thread.Sleep(10);
Application.DoEvents();
}
Console.WriteLine(wb.DocumentTitle); <----ここでGoogleが出力される
//キーワードより検索する
HtmlElement input = wb.Document.All.GetElementsByName("q")[0];
HtmlElement button = wb.Document.All.GetElementsByName("btnG")[0];
input.InnerText = "test";
button.InvokeMember("click");
Application.DoEvents();
while (wb.ReadyState != WebBrowserReadyState.Complete || wb.IsBusy)
{
Console.WriteLine("waiting...");
System.Threading.Thread.Sleep(10);
Application.DoEvents();
}
Console.WriteLine(wb.DocumentTitle); <----ここでもGoogleが出力される
2回目のタイトルは「test - Google 検索」がでるはずですが、
なぜか前のページのままです。
Documentの中身も前のページのままです。
解決方法お願いします。
すべての返信
-
> なぜかHTML要素のbuttonにInvokeMember("click")を呼び出す後の画面更新
> 待ちができないようです。click で WebBrowswer が目的のページにナビゲートされるのでしょうか?
そこをまずチェックしてください。
今回の問題と関係あるのかどうか分かりませんが、DocumentCompleted イベン
トを利用しましょう。WebBrowserのウエイト
http://social.msdn.microsoft.com/Forums/ja-JP/vbexpressja/thread/fa0e8e02-316d-4176-99f9-4b8adc981904WebBrowserのNavigate処理中、発生するAccessViolationExceptionについて
http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/71ee4e18-527f-4250-a20c-08d096980a35/
よく Application.DoEvents メソッドを使っている例を見ますが、正しい
使い方ではないと思います。Application.DoEventsによるプロパティ値の影響について
http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/3f09d0ac-d6ad-4865-8daa-4a2e89c386e4- 編集済み SurferOnWww 2011年9月28日 13:03 リンク修正
-
2回目のタイトルは「test - Google 検索」がでるはずですが、
なぜか前のページのままです。試してみました。確かに一度目は「test - Google 検索」と表示されましたが、次からはいくらやっても「Google」としか出ませんでした。IEで表示させてそのページのTitleタグを見ても「Google」となっています。プログラムというより、Googleの仕様っぽい気がします。
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/ -
長い返事でありがとうございます。
clickでWebBrowserが目的ページにナビゲートします。
FormにWebBrowserを入れたら見えますが、WebBrowserはちゃんと目的ページにナビゲートしました。
InvokeMember("click")の後、5~10秒ぐらい待ったら、正しい結果も出ます。
いろんな手段を組み合わせて確認しましたが、どうやらWebBrowserはInvokeMember("click")の対応が不十分らしいです。
WebBrowserのReadyStateが変わらないみたいです。(つまり、前回のReadyStateのままです)
*DocumentCompletedも使ってみました、結果同じです。
ひとまずは、documentTitleが変わるまで待つことにしました。
-
IE9 とその開発者ツールで見てみましたが、タブに表示されているタイトルが
test - Google となっていても、html ソースを見ると <title>Google</title>
となっていることがありました。JavaScript で書き換えているのかもしれません。
12章 JavaScriptのドキュメント操作Ⅱ
http://www.site-cooler.com/kwl/jslibrary/12.htmWebBrowser.DocumentTitle プロパティで取得できる文字列は title タグのもの
でしょうから(検証してませんが)、表示と違うのは止むを得ないように思いま
す。 -
> Javascriptの処理終了を判断する方法がありますか?
読み込み時のスクリプトの完了は判断できても、JavaScript で実装されたロジックの終端は判断できません。
前者(読み込み時のスクリプトの完了)は、ページのロード完了時に一番最後によばれるのは document.onload イベントであるため、Document の Load イベントの末尾にイベントハンドラを追加するとよいでしょう。(JavaScript のイベントと .NET 側のイベントの連携は、うまいことやってくれるので簡単だった記憶)
後者(ロジックの終端)は、onload イベントを抜けるまでに通過したすべての JavaScript を動的に解析し、なんらかの基準を設けて JavaScript で書かれた処理の終端を分析・検出しなければなりません。(簡単には、待ち時間 0 で登録されるタイマイベントが尽きるまですべての制御フローをトレースしていけばよいかもしれませんが、eval とか無視になります)