VB.NETアプリケーションでWebBrowserコントロールを使用して、いくつかのURL(約10〜15)をロードし、HTMLソースをテキストファイルに保存しています。ただし、ページが読み込まれる前でもトリガーされるため、私のコードは最初のページではなく現在のページのソースを記述しません。
ページが完全にロードされるまで待ってからイベントを呼び出すにはどうすればよいですか?
次のコードを試しましたが、機能しません。
Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
Loop
Webブラウザーコントロールの DocumentCompleted イベントをキャッチしたいようです。
MSDNには、Webブラウザーコントロールに関するいくつかの優れた記事があります- WebBrowser Class には多くの例があり、 Webフォーム機能をWindowsフォームアプリケーションに追加する
サルベテ! コードがページがロードされるのを待ってから続行するために呼び出すことができる関数答えを求めてウェブを探し、数時間いじり回した後、私はこれを思いついた自分で解決するために、あなたが提示する正確なジレンマ。私は答えが出てゲームに遅れていることを知っていますが、これを他の人に投稿したいと思います。
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
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
技術的には、BGMによって投稿されたコードには2つの問題があります。
waitForPageLoadメソッドにハンドラーを追加するのは遅すぎる可能性があります。ハンドラーが追加される前にナビゲーションが開始されます。つまり、ブラウザーが既にページを持っている非常にまれなケースでは、ハンドラーが追加される前に完了する場合があります。
解決策は、ナビゲーションを開始する前にハンドラーを追加し、ナビゲーションの完了後にハンドラーを削除することです
これは、WaitForPageLoadメソッドを2つのメソッドに分割する必要があることを意味します。 1つは、ナビゲーションを開始する前に呼び出されます。ハンドラーを設定する必要があります。 2番目の部分は、ReadyStateの監視を行い、「準備完了」のときにクリーンアップします。
適切なプログラミング方法は、タイムアウトを追加して、ブラウザの紛失(またはクラッシュ、ループ)が原因でドキュメントが完了するまでコードが永遠に待機しないようにすることです。
つかまっている...
私の経験から、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
ロードイベントでは、Me.Hide
を使用します。
WebBrowser1.DocuementCompletedでは、Me.Show
を使用します
私はしばらくの間、この「完全にロードされた」問題に苦労しましたが、次の解決策が私のために働いたことを発見しました。私は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の組み合わせとして、これがすべての人に役立つかどうかはわかりませんが、このソリューションを許可したかもしれませんが、試してみる価値はあります。