• 締切済み

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の中身も前のページのままです。 解決方法お願いします。

みんなの回答

  • DOUGLAS_
  • ベストアンサー率74% (397/534)
回答No.4

 そもそものご質問の意図を理解できていなかったようです。 button.InvokeMember("click"); の後の Console.WriteLine("waiting..."); が出てこない、つまり while (wb.ReadyState != WebBrowserReadyState.Complete || wb.IsBusy) が スルー されてしまう、ということが問題だったようですね。  Excel で確認したところ、Google の場合は、最初の「検索開始」の画面を呼び出した後は、「検索結果」の画面に遷移する間、「wb.ReadyState」・「wb.IsBusy」が変わっていないので、2番目の while ループ が スルー されてしまうようです(Google の仕様ですかね)。 >ひとまずはdocumentTitleが変わるまで待ちます。 とお書きだったのは、 button.InvokeMember("click"); Application.DoEvents(); while (wb.ReadyState != WebBrowserReadyState.Complete || wb.IsBusy) を hoge = wb.DocumentTitle; button.InvokeMember("click"); Application.DoEvents(); while (wb.DocumentTitle != hoge) みたいにするということでしたか。  こうすれば、2番目の while ループ の中に入って、 waiting... Google waiting... test コマンド - Google 検索 の順に吐き出されますね。  何故か分かりませんが、「コマンド」という言葉が入ってはいますが。。。  何度もスレッド を汚してしまって申し訳ございませんでした。  私の愚答をご覧になって、有識者の方から有効な回答が付くことを祈って、敢えて書かせていただきましたので、#3・4 にはお返事は結構です。  大変、失礼いたしました。  <(_ _)>

  • DOUGLAS_
  • ベストアンサー率74% (397/534)
回答No.3

>長い返事で大変ありがとうございます。  ぃぇぃぇ、無駄に長いだけでした。  昨夜、回答を書いてからいろいろと考えておりまして、 >「wb.Document」は「<変数なし>」ですねぇ。 について、よく考えてみたら、これって、何かの タイミング でよくあることで、Document 配下の プロパティ を付けて、「Document.All」などに変えたらちゃんと要素が入ってました。  大変、失礼いたしました。 >ひとまずはdocumentTitleが変わるまで待ちます。 >正しい結果も出ます。  Excel では、 While .Busy Or .ReadyState <> 4: DoEvents: Wend Application.Wait (Now + TimeValue("0:00:10")) ← 10秒待ってみました とすれば、 wb.Document.Title : "test コマンド - Google 検索" となりました。  が、相変わらず、表示されている IE の [表示(V)] - [ソース(C)] は <title>Google</title> のままでした。何なんでしょうねぇ。。  以上、お詫び旁々、追加の情報でした。

  • DOUGLAS_
  • ベストアンサー率74% (397/534)
回答No.2

#1 追加情報 です。 >1回目と2回目の ソース を見比べて見ましたが >ソース が全く変わっていない ということで、それなら、 wb.Navigate "http://www.google.co.jp/?q=#sclient&q=test" や wb.Navigate "http://www.google.co.jp/?q=#sclient=psy-ab&hl=ja&source=hp&q=test&pbx=1&oq=test&aq=f&aqi=&aql=&gs_sm=e&gs_upl=0l0l0l16431l0l0l0l0l0l0l0l0ll0l0&bav=on.2,or.r_gc.r_pw.&fp=b8a4c9b777f5c6bf&biw=1264&bih=875" ならイケるかな? と思いましたが、どうも、URL から 当該ページを開いた場合は、常に <title>Google</title> となってますねぇ。  アドレスバー から「? test」で開いた http://www.google.co.jp/search?sourceid=ie7&q=test&rls=com.microsoft:ja:IE-Address&ie=UTF-8&oe=UTF-8&rlz=1I7MOCJ&redir_esc=&ei=BReDTq2eOPHzmAWazdQ_ の場合は、 <title>test - Google 検索</title> になりました。  でも、「wb.Document」は「<変数なし>」ですねぇ。  しかたないので、WebBrowser ではなくて、HttpRequest で アクセス してみると、ちゃんと、document を取得できました。  Excel VBA の コード ですが、ご参考までに。。。 Sub with_HttpRequest() '// [Microsoft Forms 2.0 Object Library] を参照設定  Dim strHTTP As Variant  Dim i As Integer  Dim objHTTP As Object  Dim strURI As String  Dim myDocument As String  strHTTP = Array("MSXML2.XMLHTTP.6.0", "MSXML2.XMLHTTP.5.0", _   "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", _   "MSXML.XMLHTTPRequest", "WinHttp.WinHttpRequest.5.1")  On Error Resume Next  Do   Set objHTTP = CreateObject(strHTTP(i))   i = i + 1  Loop Until IsObject(objHTTP)  On Error GoTo 0  strURI = "http://www.google.co.jp/search?sourceid=ie7&q=test&rls=com.microsoft:ja:IE-Address&ie=UTF-8&oe=UTF-8&rlz=1I7MOCJ&redir_esc=&ei=BReDTq2eOPHzmAWazdQ_"  With objHTTP   .Open "GET", strURI, False   .Send   If .Status <> 200 Then GoTo 100   myDocument = .responseText   Debug.Print myDocument  End With 100:  Set objHTTP = Nothing End Sub

get_star
質問者

補足

長い返事で大変ありがとうございます。 HttpRequestについて、正しいページソースを取得できますが、画面の遷移制御ができないです。 人の操作と同様にWebページの遷移を制御したいので、WebBrowserでやるしかないです。 WebBrowserのバグかな? Navigateでの遷移じゃない場合、待ってくれないみたいです。 ひとまずはdocumentTitleが変わるまで待ちます。 正しい結果も出ます。

  • DOUGLAS_
  • ベストアンサー率74% (397/534)
回答No.1

>2回目のタイトルは「test - Google 検索」がでるはず  お示しの コード を Excel VBA に翻訳して実行してみたところ妙なことに気が付きました。  実は、最近(ここ2~3日)、Google 検索の URL パラメータ の書式が変わったみたいなんですよねぇ~。  以前は、 http://www.google.co.jp/?q=test でイケてたように思うのですが、最近、 http://www.google.co.jp/?q=#sclient&q=test でないと、検索結果が現われないんです。  で、本題に戻りますが、 >Documentの中身も前のページのままです。 とのことですが、Excel VBA では While .Busy Or .ReadyState <> 4: DoEvents: Wend の後には、「wb.Document」は「<変数なし>」になってしまってるんですねぇ。  ぉゃ~ん? と思って、表示された「2回目」の ページ の ソース を覗いてみると、 <title>Google</title> となってますねぇ。  だから >2回目のタイトルは「test - Google 検索」がでるはず なのに、2回目も ><----ここでもGoogleが出力される になっているんでしょうねぇ。  私も興味がありますので、1回目と2回目の ソース を見比べて見ましたが、な、な、なんと、ソース が全く変わっていないではあ~りませんか?  当然、 >Documentの中身も前のページのままです。 でしょうなぁ。。。  これって、どぅぃぅコトッ!?  つまり、コード の問題ではなくて、Google サイト の大幅な仕様変更ってトコなんでしょうが、なんか釈然としません。 ●Google Japan Blog http://googlejapan.blogspot.com/2011/09/igoogle.html によると >Google 検索ページや Gmail、Google カレンダーなど Google のサービスのデザインが変更されていることにお気づきの方は多いかと思います。今回のリニューアルは先日行ったこちらの発表 (英語) に基づく変更です。 とのコトですゎ。  まぁ、「Google 検索ページ・・・のサービスのデザインが変更され」た(勝手に検索が始ったりするなど。。)のは、何ヶ月も前のコトですが、今回、第2弾を発動したんとちゃぅヵ? ってトコでしょうかぁ?  以上、見当違いな回答でしたら スル~~なさってください。

関連するQ&A

  • vb2005 webbrowserでリンクをクリックした後の表示待ちの方法

    VB2005を勉強中の者です。 WebBrowser1.Navigateを使ってwebページを開いた際は下記while文での表示待ちが機能するのですが、ページ表示後、さらにInvokeMemberを使って先のページにクリックで進んだ後では同一の表示待ち部分がうまく機能せずにそのまま次の処理へと進んでしまいいます。 どこに問題があるのか分からず困っております。どなたか助けていただけませんでしょうか? WebBrowser1.Navigate("https://yahoo.co.jp") '↓ここは機能します While WebBrowser1.IsBusy Or WebBrowser1.ReadyState <> WebBrowserReadyState.Complete Application.DoEvents() End While WebBrowser1.Document.GetElementsByTagName("a").Item(15).InvokeMember("click") '↓これが機能しなくて困っています! While WebBrowser1.IsBusy Or WebBrowser1.ReadyState <> WebBrowserReadyState.Complete Application.DoEvents() End While '↓目的 TextBox1.Text = WebBrowser1.Document.Body.InnerText

  • WebBrowserについて

    Visual Studio 2008を使っています 途中で処理が停止しまい困っています デバックで一時停止をすると Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete System.Windows.Forms.Application.DoEvents() Loop この部分で作業が止まっています 何かいい方法はないでしょうか? ソースは下記の通りです WebBrowser1.Navigate(New Uri("http://※※※※※※※※※※※※)) Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete System.Windows.Forms.Application.DoEvents() Loop ______________________________ Threading.Thread.Sleep(1000)とか入れても止まってしまいます 秒数はいろいろ試しましたが駄目でした WebBrowser1.Navigate(New Uri("※※※※※※※※※※※※)) Threading.Thread.Sleep(1000) Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete System.Windows.Forms.Application.DoEvents() Loop

  • vb2005にてhtmlソースの中のある値を取得したい。

    WebBrowser1.Navigate("http://www.yahoo.co.jp/") Do While (WebBrowser1.IsBusy Or WebBrowser1.ReadyState <> WebBrowserReadyState.Complete) My.Application.DoEvents() System.Threading.Thread.Sleep(50) Loop にてホームページを表示させたとき タグの中の値を取得したいんですが、 xmlみたいにピンポイントで取得するにはどのようにすればよろしいでしょうか?教えてください。

  • webbrowserの読込完了が反応しない

    何度も質問してすみません。 どうしても自力では解決できないことがありましたので質問させていただきます。 webbrowserでの読み込み後の処理についてなのですが、現在表示されているページ内のリンクを自動でクリックし、次のページにあるテキストボックス内にテキストを打ち込みたいのです。 While WebBrowser1.IsBusy Or WebBrowser1.ReadyState <> WebBrowserReadyState.Complete  Application.DoEvents() End While を置いているのですが、どうやらこれが機能せずにテキストボックスへの書き込みがうまくいきません。 試しに、上記の記載の後ろに msgbox("待ってみる") と記載してみると、前ページのリンクをクリックした瞬間、メッセージボックスが表示されます。 メッセージボックスのOKボタンをしばらく待って手動でOKをクリックするとテキストボックスへのテキストの書き込みも正常に行われます。 ほかには Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete System.Windows.Forms.Application.DoEvents() Loop や System.Threading.Thread.Sleep(1000) も試してみたのですが、sleepに関してはwebbrowserの読込自体が止まってしまいます。 何か良い方法はないのでしょうか? よろしくお願いいたします。

  • WebBrowserにてsubmitの前にnavigateしてしまう

    いつもお世話になっております。 VB2005ユーザーです。 WebBrowser内の"submit"を押したあと、違うページに行きたいのですが、 "submit"を押す前に"Navigate"で指定しているページに行ってしまいます。 このようなコードを書いています。 With WebBrowser1 .Navigate("最初のURL") Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete System.Windows.Forms.Application.DoEvents() Loop .Document.Forms(0).InvokeMember("submit") Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete System.Windows.Forms.Application.DoEvents() Loop .Navigate("次の指定URL") Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete System.Windows.Forms.Application.DoEvents() Loop 「指定URL」は"submit"により新しいHTMLが生まれるので、その後の作業のためにどうしても"submit"を押したいのですが、上のようなコードですと先に「指定URL」に行ってしまいます。 "submit"をクリックせず、無視してしまうのです。 Navigate("次の指定URL")を外せばクリックしてくれるのですが・・・。 WebBrowserを完全に待機させる方法などが必要なのでしょうか? 宜しくご教授のほどお願い致します。

  • 正しいWebBrowserの使い方(ループ判定)

    VB2008を使っています。WebBrowserのコンポーネントを使って ホームページにGET形式でパラメータを渡して画面のBODY部分を読み取る ものを作っているのですが、サーバーのレスポンスにもよりますが 1分間に20回で5分(100回程度)連続アクセスをするのですが、 以下のルーチンの場合何か不安を感じまして、 ネットでこれを使えばOKというものが無くて 確実に読み取る方法が知りたくて質問いたしました。 やはり、2つ目のイベントを用いる方が安心でしょうか? 正しいWebBrowserの使い方(ループ判定)をご存知の方教えてください。 '***** WebBrowser1.ReadyState ***** WebBrowser1.Navigate(URL) Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete Or WebBrowser1.IsBusy = True Application.DoEvents() Loop data = WebBrowser1.DocumentText '***** DocumentCompletedイベントまでループ ***** public wait_flag as Boolean wait_flag = True WebBrowser1.Navigate(URL) Do While (WebBrowser1.IsBusy = True) Or (wait_flag = True) Application.DoEvents() Loop data = WebBrowser1.DocumentText '---- イベント ----- Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted wait_flag = False End Sub

  • vb2005のWebbrowserコントロールでSubmitすると動作

    vb2005のWebbrowserコントロールでSubmitすると動作がおかしいのですが Browser.Navigate("http://hyperlink.xrea.jp/regist.php") Do While Not Browser.ReadyState = WebBrowserReadyState.Complete Application.DoEvents() Loop Browser.Document.All.GetElementsByName("site_name")(0).InnerText = "test"           ・           ・ Browser.Document.Forms(0).InvokeMember("submit") このようなソースなのですが、submit後のページが <div id="copyright"> Copyright By ***</div></body></html> のように、最後の方しか返してこないのです。 手動でsubmitボタンをクリックすると大丈夫なのですが、なぜだかわかるでしょうか?

  • WebBrowserでHtmlを取得

    WebBrowserでHtmlを取得する方法をおしえてください フォーム上に、WebBrowser1、TextBox1、Button1を配置しています。 TextBox1にHtmlを表示し、Button1は、WebBrowser1に表示している WEBページを更新します。 やりたい事  (1)フォームを開いた時に、URLで指定したWEBページを表示させ   TextBox1にHtmlを表示させる。  (2)Button1をクリックした時、表示しているWEBページを更新する。   更新後のHtmlをTextBox1に表示させる。  (3)TextBox1の表示が完了したらHtmlを処理する。(未着手) 現在、(1)は動作するのですが、(2)が動作しません(TextBox1のHtmlが更新されない) Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load WebBrowser1.Navigate(オッズURL):webcompflag = False Do While (webcompflag = False) System.Windows.Forms.Application.DoEvents() System.Threading.Thread.Sleep(10) Loop TextBox1.Text = WebBrowser1.Document.Body.InnerHtml End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click TextBox1.Text = "" If Not WebBrowser1.Url.Equals("about:blank") Then WebBrowser1.Refresh() : webcompflag = False Do While (webcompflag = False) System.Windows.Forms.Application.DoEvents() System.Threading.Thread.Sleep(10) Loop TextBox1.Text = WebBrowser1.Document.Body.InnerHtml End Sub 何がいけないのか分かりません よろしくお願いします。

  • WebBrowser 内のボタンをクリックし、引数を渡したい。

    WebBrowser 内のボタンをクリックし、引数を渡したい。 WebBrowser コントロールを使用していて Windows アプリからページ内のボタンをクリックする方法について質問です。 以下のボタンが html で定義されているとして、 <input type = "button" id = "button1" onclick="javascript:foo();" /> HtmlElement element = null; element = webBrowser1.Document.GetElementById("button1"); element.InvokeMember("click"); こうすると、javascript の foo() が実行されます。 本題はここからなんですが、 この関数fooに引数を渡したいのです! 例えばfooの定義を var foo=function(arg) { alert(arg); } として、アプリ側から、 element.InvokeMember("click","this is test"); のようにすれば動くかと思ったのですが、だめでした。 方法をご存知のかた、ご教授願います!

    • ベストアンサー
    • HTML
  • VB2005、WebBrowserにてログインが成功したか失敗したかを判断

    お世話になっております。 VB2005ユーザーです。 WebBrowserを使用し、windowsフォームに入力した内容を元にログインし、ログインが成功したか失敗したかを判断したいのです。 With WebBrowser1 .Navigate("ログインしたいURL") Do While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete '読み込み終わるまで待つ System.Windows.Forms.Application.DoEvents() Loop .Document.All.GetElementsByName("ID")(0).InnerText = ID.Text .Document.All.GetElementsByName("パスワード")(0).InnerText = パスワード.Text .Document.Forms(0).InvokeMember("submit") という物を使い、その後にログイン成功か失敗かを判断するために、 If .Document.Body.Innertext = "ログイン失敗" Then MsgBox("だめ") Exit Sub Else MsgBox("OK") Exit Sub End If というコードを使ってみたのですが、Innertextの情報を読み取っていないのか、Else MsgBox("OK")に飛んでしまいます。 Navigateにて進んだ先のHTML情報(Innertext)と、コチラが指定したい情報が一致しているかの判断はどのようなコードを記述すればいいのでしょうか?

専門家に質問してみよう