Как дождаться полной загрузки WebBrowser в VB.NET? - PullRequest
15 голосов
/ 18 июля 2010

Я использую элемент управления WebBrowser в своем приложении VB.NET для загрузки нескольких URL-адресов (~ 10-15) и сохранения их источника HTML в текстовом файле. Однако мой код не записывает источник текущей страницы, а не исходную, потому что он запускается еще до загрузки страницы.

Как мне дождаться полной загрузки страницы, прежде чем вызывать какое-либо событие?

Я попробовал следующий код, но он не работает.

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

Ответы [ 8 ]

20 голосов
/ 09 февраля 2012

Salvete!Мне просто нужна была функция, которую я мог бы вызвать, чтобы заставить код ждать загрузки страницы, прежде чем она продолжится. После поиска в Интернете ответов и возни в течение нескольких часов, я придумал это дляРешите для себя точную дилемму, которую вы представляете.Я знаю, что опаздываю в игре с ответом, но я хочу опубликовать его для всех, кто придет.

использование: просто вызовите 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, которая будет вашим браузером

Теперь, где-нибудь в вашем модуле или классе, поместите это:

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
7 голосов
/ 18 июля 2010

Звучит так, как будто вы хотите перехватить событие DocumentCompleted вашего веб-браузера.

В MSDN есть несколько хороших статей об элементе управления веб-браузером - Класс веб-браузера содержит множество примеров и Как: добавить возможности веб-браузера в приложение Windows Forms

3 голосов
/ 07 января 2016

Иногда, если вы используете 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 голосов
/ 28 февраля 2012

Технически, есть две проблемы с кодом, опубликованным BGM:

  1. добавление обработчиков в метод WaitForPageLoad потенциально слишком поздно.Навигация инициируется до добавления обработчиков, что означает, что в очень редких случаях, когда в браузере уже есть страница, которую он может завершить до добавления обработчиков, в этом случае вы пропустите событие и будете ждать вечно.

    Решение состоит в том, чтобы добавить обработчики до начала навигации и удалить их после завершения навигации

    Это означает, что метод WaitForPageLoad необходимо разделить на два метода.Один вызывается до начала навигации.Следует установить обработчики.Вторая часть выполняет мониторинг ReadyState и очищает его, когда «Готово».

  2. Хорошая практика программирования заключается в добавлении тайм-аута, чтобы потерянный (или аварийный, или зацикленный) браузер незаставьте ваш код ждать, пока документ завершится, даже

1 голос
/ 30 августа 2015

Держись ...

Из моего опыта вы ДОЛЖНЫ убедиться, что DocumCompleted относится к ВАШЕМ URL, а не к подстранице фрейма, сценарию, изображению, CSS и т. Д. И этонезависимо от того, IsBusy или ReadyState закончен или нет, оба часто бывают неточными, когда страница немного сложна.

Что ж, это мой личный опыт в рабочей программе VB.2013 и IE11.Позвольте мне также упомянуть, что вы должны учитывать также режим совместимости IE7, который включен по умолчанию на webBrowser1.

' 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 голос
/ 10 июля 2013

В событиях загрузки используйте Me.Hide.

В WebBrowser1.DocuementCompleted используйте Me.Show

0 голосов
/ 03 июня 2015

Я сделал похожую функцию (только то, что мне подходит) - извините, это на C #, но легко перевести ...

private void WaitForPageLoad ( ) {
 while (pageReady == false)
     Application.DoEvents();

  while (webBrowser1.IsBusy || webBrowser1.ReadyState !=   WebBrowserReadyState.Complete)
     Application.DoEvents();
}
0 голосов
/ 22 мая 2012

Я некоторое время боролся с этой «полностью загруженной» проблемой, но обнаружил, что следующее решение работает для меня. Я использую IE7, поэтому я не уверен, что это работает в других версиях, но стоит посмотреть.

Я разбил проблему на две части; сначала мне нужно было сообщение из события DocumentComplete;

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

Затем в той части кода, где мне нужно дождаться полной загрузки веб-страницы, я вызываю другую подпрограмму, которая делает это;

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

Кроме того, мне также нужно было сделать то же самое, ожидая завершения кода javascript. Например, на одной странице, когда вы выбираете элемент из раскрывающегося списка html, он заполняет следующий раскрывающийся список, но требует времени, чтобы раскрыть себя. В этом случае я нашел это так:

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

было достаточно для удержания браузера. Не уверен, что это поможет всем, как комбинация IE7, веб-сайта, который я загружал, и javascript, который работала одна страница, возможно, позволили это решение, но, безусловно, стоит попробовать.

...