将当前的WebBrowser DOM作为HTML获取

时间:2013-09-15 04:44:18

标签: c# html video xpath

我想在WebBrowser上使用HTML能力包,它已经加载了我需要的所有东西(它点击一个带代码的按钮来加载频道上的每个视频) (它加载YouTube频道,然后加载所述频道上的所有视频。) 现在,如果我尝试获取所有视频详细信息(我有一个工作代码将频道的前30个视频导入列表视图),它仍然只显示前30个,但我在WebBrowser页面上加载了所有视频(它显示所有视频) 我正在使用它来获取当前从WebBrowser

加载的内容

enter image description here

但它仍然只加载前30个视频而不是从WebBrowser加载的所有视频。

1 个答案:

答案 0 :(得分:5)

如果目标网站大量使用AJAX(如Youtube所做的那样),那么很难(如果不是不可能的话)确定页面何时完成加载并执行所有动态脚本。但是你可以通过处理window.onload事件来接近,并允许额外的一两秒用于非确定性的AJAX调用。然后通过webBrowser.Document.DomDocument.documentElement.outerHTML致电dynamic以获取当前呈现的HTML。

示例:

private void Form1_Load(object sender, EventArgs e)
{
    DownloadAsync("http://www.example.com").ContinueWith(
        (task) => MessageBox.Show(task.Result),
        TaskScheduler.FromCurrentSynchronizationContext());
}

async Task<string> DownloadAsync(string url)
{
    TaskCompletionSource<bool> onloadTcs = new TaskCompletionSource<bool>();
    WebBrowserDocumentCompletedEventHandler handler = null;

    handler = delegate
    {
        this.webBrowser.DocumentCompleted -= handler;

        // attach to subscribe to DOM onload event
        this.webBrowser.Document.Window.AttachEventHandler("onload", delegate
        {
            // each navigation has its own TaskCompletionSource
            if (onloadTcs.Task.IsCompleted)
                return; // this should not be happening
            // signal the completion of the page loading
            onloadTcs.SetResult(true);
        });
    };

    // register DocumentCompleted handler
    this.webBrowser.DocumentCompleted += handler;

    // Navigate to url
    this.webBrowser.Navigate(url);

    // continue upon onload
    await onloadTcs.Task;

    // artificial delay for AJAX
    await Task.Delay(1000);

    // the document has been fully loaded, can access DOM here
    return ((dynamic)this.webBrowser.Document.DomDocument).documentElement.outerHTML;
}

[编辑] 以下是帮助解决OP问题的最后一段代码:

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(((dynamic)this.webBrowser1.Document.DomDocument).documentElement.ou‌​terHTML);