Как заставить WebBrowser дождаться полной загрузки?

У меня есть форма C # с элементом управления веб-браузером.

Я пытаюсь последовательно посещать разные веб-сайты.

Однако я не могу контролировать URL-адрес для загрузки в элемент веб-браузера моей формы.

Это функция, которую я использую для навигации по URL-адресам:

public String WebNavigateBrowser(String urlString, WebBrowser wb)
{
    string data = "";
    wb.Navigate(urlString);
    while (wb.ReadyState != WebBrowserReadyState.Complete)
    {
        Application.DoEvents();
    }
    data = wb.DocumentText;
    return data;
}

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

Мой цикл выглядит примерно так:

foreach (string urlAddresses in urls)
{
    WebNavigateBrowser(urlAddresses, webBrowser1);
    // I need to add a code to make webbrowser in Form to wait till it loads
}

person Val Nolav    schedule 19.03.2012    source источник
comment
Пожалуйста, не ставьте перед заголовками префикс C # и тому подобное. Вот для чего нужны теги.   -  person John Saunders    schedule 19.03.2012
comment
Прикрепите метод к событию DocumentCompleted.   -  person Brian Graham    schedule 19.03.2012
comment
В ПОРЯДКЕ! Я сделал это так, потому что это помогает мне, когда я пытаюсь найти что-то в stackoverflow.   -  person Val Nolav    schedule 19.03.2012
comment
Брайан, как я могу это сделать? Вы можете дать мне образец кода?   -  person Val Nolav    schedule 19.03.2012


Ответы (4)


Добавьте это в свой код:

webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);

Заполните эту функцию

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
     //This line is so you only do the event once   
     if (e.Url != webBrowser1.Url) 
        return;


        //do you actual code        



    }
person SamFisher83    schedule 19.03.2012
comment
Сэм, я не могу запустить свой код по вашему предложению. Это не работает - person Val Nolav; 19.03.2012
comment
Обратите внимание на проверку if, которая очень важна. DocumentedCompleted будет срабатывать, например, для каждого iframe. - person ; 19.03.2012
comment
Вы обязательно изменили webBrowser1 на wb? - person SamFisher83; 20.03.2012
comment
Можете объяснить, что не работает? Я знаю, что то, что я опубликовал, работает с моим кодом. - person SamFisher83; 20.03.2012
comment
Мне нужно запустить этот код в цикле, потому что есть номера URL. Код действительно работает для первого цикла, но после первого цикла он не запускается. У меня есть коллекция HtmlElementCollection, в которой я собираю некоторые данные с посещенного веб-сайта. В первом цикле я могу получить данные для коллекции, однако во втором цикле это не заставляет мой код ждать, пока загрузится веб-страница, и, таким образом, моя коллекция имеет значение null, и из-за этого моя функция события щелчка не работает должным образом, поэтому петля разрывается. Это моя проблема. мои обработчики событий щелчка, если доступен СЛЕДУЮЩИЙ щелчок. - person Val Nolav; 20.03.2012
comment
Большое спасибо за эту проверку URL! У меня были проблемы с ранними пожарами DocumentCompleted в течение нескольких месяцев, и я не мог понять, почему. - person Dan Bechard; 25.10.2012
comment
Наконец-то способ, который действительно работает. Мой последний (циклы while и задержки) был чертовски хреновым. Большое спасибо за это! - person C4d; 01.06.2015
comment
Это не будет работать полностью, если есть сложный javascript, который правильно создает контент после загрузки страницы? - person firebellys; 23.10.2015

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

Никогда не используйте событие WebBrowserDocumentCompletedEventHandler, используйте WebBrowserProgressChangedEventHandler с некоторыми модификациями, показанными ниже.

// "ie" - это объект нашего веб-браузера

ie.ProgressChanged += new WebBrowserProgressChangedEventHandler(_ie);
private void _ie(object sender, WebBrowserProgressChangedEventArgs e)
{
  int max = (int)Math.Max(e.MaximumProgress, e.CurrentProgress);
  int min = (int)Math.Min(e.MaximumProgress, e.CurrentProgress);
  if (min.Equals(max))
  {
   //Run your code here when page is actually 100% complete
  }
}

Простой гениальный метод решения этой проблемы, я нашел этот вопрос в Google: "Как перевести браузер в спящий режим или поставить его на паузу".

person user2887749    schedule 22.10.2013
comment
Что ж ... Это не помогло мне с моей полной проблемой javascript. :( - person Omzig; 30.04.2014
comment
Подтверждаю: это решение не абсолютное. Например, у меня это срабатывает 5 раз, а DocumentCompleted только 2 раза ... Итак, этот извечный вопрос "how to know when WB really finished loading document" все еще открыт. - person Kosmo零; 30.11.2017

Согласно MSDN (содержит образец source) вы можете использовать для этого событие DocumentCompleted. Дополнительную очень полезную информацию и источник, показывающий, как различать вызовы событий, можно найти здесь.

person Yahia    schedule 19.03.2012
comment
На практике это не работает. Когда я это делал сам, он срабатывает примерно 4-5 раз для каждого документа. - person Haedrian; 19.03.2012
comment
@Haedrian он действительно работает ... он вызывается для каждого завершенного документа, что означает, что его можно вызывать несколько раз для одного URL-адреса (например, когда он содержит IFRAME, использует AJAX или работает с перенаправлениями и т. Д.). Перейдите по второй ссылке, чтобы увидеть предложение о том, как различать эти случаи ... - person Yahia; 19.03.2012

то, что вы пережили, и случилось со мной. readyStete.complete в некоторых случаях не работает. здесь я использовал bool в document_completed, чтобы проверить состояние

 button1_click(){
    //go site1 
    wb.Navigate("site1.com");
    //wait for documentCompleted before  continue to  execute  any further 
    waitWebBrowserToComplete(wb); 

    // set some values in html page
    wb.Document.GetElementById("input1").SetAttribute("Value", "hello");
    //  then click submit. (submit does navigation)
    wb.Document.GetElementById("formid").InvokeMember("submit");
    // then wait for doc complete        
    waitWebBrowserToComplete(wb);


    var processedHtml = wb.Document.GetElementsByTagName("HTML")[0].OuterHtml;
    var rawHtml = wb.DocumentText;
}

// helpers
//instead of checking  readState . we get state from DocumentCompleted Event via bool value
bool webbrowserDocumentCompleted = false;
public static void waitWebBrowserToComplete(WebBrowser wb)
{
  while (!webbrowserDocumentCompleted )
      Application.DoEvents();
  webbrowserDocumentCompleted = false;
}

form_load(){
  wb.DocumentCompleted += (o, e) => {
     webbrowserDocumentCompleted = true;
  };
}
person bh_earth0    schedule 05.01.2017