从线程返回时WebBrowser.Document为null,而不是在新线程中更新

时间:2015-04-14 09:07:45

标签: c# multithreading web-scraping

public static User registerUser()
{
    Uri test = new Uri("https://www.example.com/signup");
    HtmlDocument testdoc = runBrowserThread(test);

    string tosend = "test";

    User user = new User();

    user.apikey = tosend;

    return user;

}
public static HtmlDocument runBrowserThread(Uri url)
{
    HtmlDocument value = null;
    var th = new Thread(() =>
    {
        var br = new WebBrowser();
        br.DocumentCompleted += browser_DocumentCompleted;
        br.Navigate(url);
        value = br.Document;
        Application.Run();
    });
    th.SetApartmentState(ApartmentState.STA);
    th.Start();
    th.Join(8000); 
    return value;
}

static void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    var br = sender as WebBrowser;
    if (br.Url == e.Url)
    {
        Console.WriteLine("Natigated to {0}", e.Url);
        Console.WriteLine(br.Document.Body.InnerHtml);
        System.Console.ReadLine();
        Application.ExitThread();   // Stops the thread
    }
}

我正在尝试扫描此页面,虽然它确实获取了HTML但它没有将其传回函数调用,而是发送回null(我认为这是后期处理)。

如何使新线程传回其结果?

2 个答案:

答案 0 :(得分:1)

您的方法存在一些问题。

  • 你不等到网页导航,我的意思是直到Navigated事件。因此,在此之前,文件可能是空的。
  • 您在8秒后退出,如果页面加载时间超过8秒,您将无法获取该文档。
  • 如果文档没有正确加载,您就可以让线程保持活动状态。
  • 我猜WebBrowser控件无法按预期工作,除非您将其添加到表单中并显示它(它需要在屏幕中可见)。

等。

不要混淆东西。您的目标无法使用WebBrowser。如果您只需要从网页下载字符串,请使用HttpClient.GetStringAsync

将页面作为字符串格式后,如果要操作html,请使用HtmlAgilityPack

答案 1 :(得分:0)

转移到使用WaitN而不是默认浏览器模型。有点儿车,但现在应该这样做。

using (var browser = new FireFox("https://www.example.com/signup"))
        {
            browser.GoTo("https://example.com/signup");
            browser.WaitForComplete();


        }