web-dev-qa-db-ja.com

WebBrowserがVB.NETに完全にロードされるまで待つ方法

VB.NETアプリケーションでWebBrowserコントロールを使用して、いくつかのURL(約10〜15)をロードし、HTMLソースをテキストファイルに保存しています。ただし、ページが読み込まれる前でもトリガーされるため、私のコードは最初のページではなく現在のページのソースを記述しません。

ページが完全にロードされるまで待ってからイベントを呼び出すにはどうすればよいですか?

次のコードを試しましたが、機能しません。

Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete
   Application.DoEvents()
Loop
15
Shubham

Webブラウザーコントロールの DocumentCompleted イベントをキャッチしたいようです。

MSDNには、Webブラウザーコントロールに関するいくつかの優れた記事があります- WebBrowser Class には多くの例があり、 Webフォーム機能をWindowsフォームアプリケーションに追加する

7
Dan F

サルベテ! コードがページがロードされるのを待ってから続行するために呼び出すことができる関数答えを求めてウェブを探し、数時間いじり回した後、私はこれを思いついた自分で解決するために、あなたが提示する正確なジレンマ。私は答えが出てゲームに遅れていることを知っていますが、これを他の人に投稿したいと思います。

sage:ナビゲーションの呼び出しの直後にWaitForPageLoad()を呼び出す

whatbrowser.Navigate("http://www.google.com")
WaitForPageLoad()

別の例ナビゲート機能とページの読み込みを組み合わせません。たとえば、ナビゲートせずに読み込みを待つ必要がある場合があります。たとえば、ページが読み込まれるのを待つ必要がある場合があるためです。 invokememberイベントで開始

whatbrowser.Document.GetElementById("UserName").InnerText = whatusername
whatbrowser.Document.GetElementById("Password").InnerText = whatpassword
whatbrowser.Document.GetElementById("LoginButton").InvokeMember("click")
WaitForPageLoad()

コードは次のとおりです両方のサブルーチンとアクセス可能な変数pagereadyが必要です。最初に、whatbrowserという変数をWebブラウザコントロールに修正してください。

次に、モジュールまたはクラスのどこかに、これを配置します。

Private Property pageready As Boolean = False

#Region "Page Loading Functions"
    Private Sub WaitForPageLoad()
        AddHandler whatbrowser.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
        While Not pageready
            Application.DoEvents()
        End While
        pageready = False
    End Sub

    Private Sub PageWaiter(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)
        If whatbrowser.ReadyState = WebBrowserReadyState.Complete Then
            pageready = True
            RemoveHandler whatbrowser.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
        End If
    End Sub

#End Region
21
bgmCoder

JavaScriptを使用する場合、DocumentCompletイベントが正しい答えを返さないことがある場合、イベントProgressChangedを使用します

Private Sub WebBrowser1_ProgressChanged(sender As Object, e As WebBrowserProgressChangedEventArgs) _
 Handles WebBrowser1.ProgressChanged

    Console.WriteLine("CurrentProgress: " + e.CurrentProgress.ToString)
    If e.CurrentProgress = e.MaximumProgress Then
        'The maximun progres is reached
        load_stated = True
    End If
    'The page is confirmed downloaded after the pregres return to 0
    If e.CurrentProgress = 0 Then
        If load_stated Then
            'the page is ready to print or download...
            WebBrowser1.Print()
            load_stated = False
        End If
    End If
End Sub
3
Tronzeus

技術的には、BGMによって投稿されたコードには2つの問題があります。

  1. waitForPageLoadメソッドにハンドラーを追加するのは遅すぎる可能性があります。ハンドラーが追加される前にナビゲーションが開始されます。つまり、ブラウザーが既にページを持っている非常にまれなケースでは、ハンドラーが追加される前に完了する場合があります。

    解決策は、ナビゲーションを開始する前にハンドラーを追加し、ナビゲーションの完了後にハンドラーを削除することです

    これは、WaitForPageLoadメソッドを2つのメソッドに分割する必要があることを意味します。 1つは、ナビゲーションを開始する前に呼び出されます。ハンドラーを設定する必要があります。 2番目の部分は、ReadyStateの監視を行い、「準備完了」のときにクリーンアップします。

  2. 適切なプログラミング方法は、タイムアウトを追加して、ブラウザの紛失(またはクラッシュ、ループ)が原因でドキュメントが完了するまでコードが永遠に待機しないようにすることです。

3
david marcus

つかまっている...

私の経験から、DocumCompletedがフレームサブページ、スクリプト、画像、CSSなどではなく、あなたのURLに属していることを確認する必要があります。これは、IsBusyまたはReadyStateが終了しているかどうかに関わらずページがわずかに複雑な場合、しばしば不正確です。

まあ、それはVB.2013とIE11の作業プログラムでの私の個人的な経験です。また、webBrowser1でデフォルトでオンになっている互換モードIE7も考慮に入れる必要があることを述べておきます。

' Page, sub-frame or resource was totally loaded.
Private Sub webBrowser1_DocumentCompleted(sender As Object, _ 
    e As WebBrowserDocumentCompletedEventArgs) _ 
    Handles webBrowser1.DocumentCompleted

    ' Check if finally the full page was loaded (inc. sub-frames, javascripts, etc)
    If e.Url.ToString = webBrowser1.Url.ToString Then
        ' Only now you are sure!
        fullyLoaded = True
    End If

End Sub
1
JCM

ロードイベントでは、Me.Hideを使用します。

WebBrowser1.DocuementCompletedでは、Me.Showを使用します

1
Landon Tyner

私はしばらくの間、この「完全にロードされた」問題に苦労しましたが、次の解決策が私のために働いたことを発見しました。私はIE7を使用しているため、これが他のバージョンでも機能するかどうかはわかりませんが、一見の価値があります。

問題を2つの部分に分けました。最初にDocumentCompleteイベントからのメッセージが必要でした。

Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
   fullyLoaded = True
End Sub

次に、Webページが完全にロードされるまで待つ必要があるコードの部分で、これを行う別のサブルーチンを呼び出します。

Private Sub holdBrowserPage()
     fullyLoaded = False
     Do While fullyLoaded = False
         DoEvents
     Loop 
     fullyLoaded = False
End Sub

さらに、javascriptコードが完了するのを待っている間も同じことをする必要がありました。たとえば、1つのページでhtmlドロップダウンリストからアイテムを選択すると、次のドロップダウンリストが表示されますが、表示されるまでに時間がかかりました。その場合、私はこれを呼び出すことがわかりました。

Private Sub holdBrowser()
Do While WebBrowser1.Busy Or WebBrowser1.ReadyState <> READYSTATE_COMPLETE
   DoEvents
Loop
End Sub

ブラウザを保持するのに十分でした。 IE7、私がロードしていたWebサイト、およびページが単独で実行されていたjavascriptの組み合わせとして、これがすべての人に役立つかどうかはわかりませんが、このソリューションを許可したかもしれませんが、試してみる価値はあります。

0
Paul Blakeley