以 HTML 格式获取当前的 WebBrowser DOM

Posted

技术标签:

【中文标题】以 HTML 格式获取当前的 WebBrowser DOM【英文标题】:Get current WebBrowser DOM as HTML 【发布时间】:2013-09-19 11:30:57 【问题描述】:

我想在加载了我需要的所有内容的 WebBrowser 上使用 html 功能包(它单击带有代码的按钮以加载频道上的每个视频) (它加载一个 YouTube 频道,然后加载该频道上的所有视频。) 现在,如果我尝试获取所有视频详细信息(我有一个将频道的前 30 个视频放入列表视图的工作代码),它仍将仅显示前 30 个,但我已在 WebBrowser 页面上加载了所有视频(它显示所有视频) 我正在使用它来获取当前从 WebBrowser 加载的内容

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

【问题讨论】:

您是否受制于您当前使用的技术? PhantomJS 真的很擅长处理这样的事情。 将返回页面初始加载时的 Html,而不是使用 ajax 动态添加的任何内容 我如何获得动态加载的内容? 【参考方案1】:

如果目标网站大量使用 AJAX(如 Youtube 那样),则很难(如果不是不可能)确定页面何时完成加载和执行所有动态脚本。但是您可以通过处理window.onload 事件并为非确定性 AJAX 调用留出一两秒钟的时间来接近。然后通过dynamic调用webBrowser.Document.DomDocument.documentElement.outerHTML获取当前渲染的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;

[EDITED]这是帮助解决 OP 问题的最后一段代码:

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

【讨论】:

呜呜。我有一个按钮,在页面加载并通过点击进行 AJAX 调用后,它会使用该页面。这个答案让我很困惑。 糟糕,我误读了有关您如何加载页面的部分,抱歉。只需使用最后一部分获取当前页面 HTML 快照:((dynamic)this.webBrowser.Document.DomDocument).documentElement.outerHTML 而不是 webBrowser.DocumentText 在清除非法字符的代码后,我得到了这个i.imgur.com/58cGnZB.png outerHTML 返回一个字符串,将其与HtmlAgilityPack 一起使用,如下所示:doc.LoadHtml(((dynamic)this.webBrowser.Document.DomDocument).documentElement.outerHTML) 得到它的工作我使用了你的第一个代码,然后用 htmlabilitypack Ty 加载HTML! HtmlAgilityPack.HtmlDocument 文档 = 新 HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(((动态)this.webBrowser1.Document.DomDocument).documentElement.outerHTML);

以上是关于以 HTML 格式获取当前的 WebBrowser DOM的主要内容,如果未能解决你的问题,请参考以下文章

C#webbrowser如何获取网页的html文件

Webbrowser控件execcommand参数详解

VB6.0 获取WebBrowser当前打开页面的网址

vb6 webbrowser 如何判断当前网页中获取焦点的是否一个文本框?

获得WebBrowser控件中的HTML源码

怎样用delphi 获取网页html源代码(网页需登录)