MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Получить html со страницы которая генерируется скриптом c#"
Answer 824822
Все же объясните если кто знает почему body = null.
Вот поэтому:
Thread.Sleep(10000); //думал мб не хватает времени прогрузить
Использовать Thread.Sleep для ожидания загрузки документа нельзя. WebBrowser - обертка над ActiveX-элементом Internet Explorer, которому для корректной работы требуется обработка сообщений в GUI-потоке. Вызов Thread.Sleep блокирует ее, так что хоть и документ успевает загрузиться "транспортным уровнем" за 10 секунд, WebBrowser не может среагировать на это и установить значение свойства Document. Чтобы все сработало, нужно ждать без прерывания обработки сообщений.
К сожалению, WinForms очень старая библиотека и у WebBrowser я не смог найти асинхронного метода загрузки, который бы позволял использовать await. Так что единственный (стандартный) способ - подписка на событие:
private void button1_Click(object sender, EventArgs e) { System.Windows.Forms.WebBrowser browser = new System.Windows.Forms.WebBrowser(); browser.ScriptErrorsSuppressed = true; browser.DocumentCompleted += browser_DocumentCompleted; browser.Navigate("https://temp-mail.org/ru"); } void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { MessageBox.Show((sender as WebBrowser).Document.Body.InnerHtml); }
Чтобы реализовать ожидание более удобно, создадим вспомогательный метод для ожидания события с помощью TaskCompletionSource:
using System; using System.Reflection; using System.Threading.Tasks; namespace WinformsTest { public class AsyncTools { /// <summary> /// Получает объект Task, который может использоваться для ожидания срабатывания указанного события /// </summary> /// <param name="o">Объект-источник события</param> /// <param name="evt">Имя события</param> public static Task<object> GetTaskFromEvent(object o, string evt) { if (o == null || evt == null) throw new ArgumentNullException("Please pass non-null arguments"); EventInfo einfo = o.GetType().GetEvent(evt); if (einfo == null) { throw new ArgumentException(String.Format("*{0}* has no *{1}* event", o, evt)); } TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); MethodInfo mi = null; Delegate deleg = null; EventHandler handler = null; //код обработчика события handler = (s, e) => { mi = handler.Method; deleg = Delegate.CreateDelegate(einfo.EventHandlerType, handler.Target, mi); einfo.RemoveEventHandler(s, deleg); //отцепляем обработчик события tcs.TrySetResult(null); //сигнализируем о наступлении события }; mi = handler.Method; deleg = Delegate.CreateDelegate(einfo.EventHandlerType, handler.Target, mi); //получаем делегат нужного типа einfo.AddEventHandler(o, deleg); //присоединяем обработчик события return tcs.Task; } } }
Тогда ожидание загрузки документа можно осуществлять с помощью await (.NET 4.5+):
var task = AsyncTools.GetTaskFromEvent(webBrowser1,"DocumentCompleted"); webBrowser1.Navigate("http://example.com/"); await task;
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.