none
WebBrowserでHTML要素のclick処理について RRS feed

  • 質問

  • 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の中身も前のページのままです。

    解決方法お願いします。
    2011年9月28日 8:51

すべての返信

  • > なぜかHTML要素のbuttonにInvokeMember("click")を呼び出す後の画面更新
    > 待ちができないようです。

    click で WebBrowswer が目的のページにナビゲートされるのでしょうか?
    そこをまずチェックしてください。


    今回の問題と関係あるのかどうか分かりませんが、DocumentCompleted イベン
    トを利用しましょう。

    WebBrowserのウエイト
    http://social.msdn.microsoft.com/Forums/ja-JP/vbexpressja/thread/fa0e8e02-316d-4176-99f9-4b8adc981904

    WebBrowserの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 リンク修正
    2011年9月28日 12:56
  • 2回目のタイトルは「test - Google 検索」がでるはずですが、
    なぜか前のページのままです。

    試してみました。確かに一度目は「test - Google 検索」と表示されましたが、次からはいくらやっても「Google」としか出ませんでした。IEで表示させてそのページのTitleタグを見ても「Google」となっています。プログラムというより、Googleの仕様っぽい気がします。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2011年9月28日 13:15
    モデレータ
  • Googleのページで「検索オプション」をクリックして検索オプションのページを開き、testと入力して「詳細検索」ボタンを押して検索するとtitleタグが「test - Google 検索」となりますね。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2011年9月28日 13:25
    モデレータ
  • 長い返事でありがとうございます。

     

    clickでWebBrowserが目的ページにナビゲートします。

    FormにWebBrowserを入れたら見えますが、WebBrowserはちゃんと目的ページにナビゲートしました。

     

    InvokeMember("click")の後、5~10秒ぐらい待ったら、正しい結果も出ます。

     

    いろんな手段を組み合わせて確認しましたが、どうやらWebBrowserはInvokeMember("click")の対応が不十分らしいです。

    WebBrowserのReadyStateが変わらないみたいです。(つまり、前回のReadyStateのままです)

    *DocumentCompletedも使ってみました、結果同じです。

     

    ひとまずは、documentTitleが変わるまで待つことにしました。

     

    2011年9月29日 2:00
  • IE9 とその開発者ツールで見てみましたが、タブに表示されているタイトルが
    test - Google となっていても、html ソースを見ると <title>Google</title>
    となっていることがありました。

    JavaScript で書き換えているのかもしれません。

    12章 JavaScriptのドキュメント操作Ⅱ
    http://www.site-cooler.com/kwl/jslibrary/12.htm

    WebBrowser.DocumentTitle プロパティで取得できる文字列は title タグのもの
    でしょうから(検証してませんが)、表示と違うのは止むを得ないように思いま
    す。

     

    2011年9月29日 12:58
  • Javascriptの処理終了を判断する方法がありますか?

    Webページの遷移を制御したいので、ページの表示が終わるまで待つしかないです。

    * 画面のタイトルが必ずしも変わるわけがないです。

     

    それとも、固定秒数で待つかな?

    タイムアウトの秒数で待てば、、、

    けれど、途中のページの情報を取ってしまうのも大変なことです、、、

    2011年9月30日 3:03
  • > Javascriptの処理終了を判断する方法がありますか?

    読み込み時のスクリプトの完了は判断できても、JavaScript で実装されたロジックの終端は判断できません。

     前者(読み込み時のスクリプトの完了)は、ページのロード完了時に一番最後によばれるのは document.onload イベントであるため、Document の Load イベントの末尾にイベントハンドラを追加するとよいでしょう。(JavaScript のイベントと .NET 側のイベントの連携は、うまいことやってくれるので簡単だった記憶)

     後者(ロジックの終端)は、onload イベントを抜けるまでに通過したすべての JavaScript を動的に解析し、なんらかの基準を設けて JavaScript で書かれた処理の終端を分析・検出しなければなりません。(簡単には、待ち時間 0 で登録されるタイマイベントが尽きるまですべての制御フローをトレースしていけばよいかもしれませんが、eval とか無視になります)

     

     

     

    2011年9月30日 3:43