使用WebBrowser访问DOM

9

我需要在执行页面上的JavaScript后访问HTML文档的DOM。我有以下连接到URL并获取文档的代码。 问题是它从未获得经过JavaScript修改后的DOM

public class CustomBrowser
{
    public CustomBrowser()
    {
        //
        // TODO: Add constructor logic here
        //
    }

    protected string _url;
    string html = "";
    WebBrowser browser;

    public string GetWebpage(string url)
    {
        _url = url;
        // WebBrowser is an ActiveX control that must be run in a
        // single-threaded apartment so create a thread to create the
        // control and generate the thumbnail
        Thread thread = new Thread(new ThreadStart(GetWebPageWorker));
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
        thread.Join();
        string s = html;
        return s;
    }

    protected void GetWebPageWorker()
    {
        browser = new WebBrowser();
        //  browser.ClientSize = new Size(_width, _height);
        browser.ScrollBarsEnabled = false;
        browser.ScriptErrorsSuppressed = true;
        //browser.DocumentCompleted += browser_DocumentCompleted;
        browser.Navigate(_url);

        // Wait for control to load page
        while (browser.ReadyState != WebBrowserReadyState.Complete)
            Application.DoEvents();

        Thread.Sleep(5000);


        var documentAsIHtmlDocument3 = (mshtml.IHTMLDocument3)browser.Document.DomDocument;

        html = documentAsIHtmlDocument3.documentElement.outerHTML; 


        browser.Dispose();
    }


}

Google Chrome开发者工具中的DOM结构

我在代码中获取到的DOM结构

我希望有人能够帮助我解决这个问题。


请勿将代码发布为图像。请将代码发布为文本。此外,您应该使用事件来查找导航何时完成,而不是使用 while 循环和 Application.DoEvents()Thread.Sleep() - Heretic Monkey
我将代码添加为文本,图像用于澄清浏览器中的DOM和我得到的DOM之间的差异。 - Abubakr A.Hafiz
使用另一种控件怎么样?例如:https://dev59.com/K3RA5IYBdhLWcg3w4iJ_ - user1946932
我使用http://idealtackle.com作为URL参数测试了您的代码,页面中有一个通过JavaScript每次加载时都会更改的图像。在加载它两次后,加载了两个不同的图像,并且没有任何问题。如果您想亲自查看,请在browser.Dispose()上设置断点,然后在快速查看中的第121行查看HTML,BACKGROUND-IMAGE:每次加载时都会更改。因此,我的猜测是这应该是由于您的浏览器版本或运行JavaScript的安全性等原因。 - Saman
请提供您的网址,这样我也可以检查吗? - Saman
这是链接 http://autoindex-eg.com/test/ - Abubakr A.Hafiz
3个回答

3
如果客户端脚本确实在IE7中执行,那么问题可能纯粹是时间问题。即使文档的加载完成后,您也无法确切知道JS脚本将何时执行。在尝试获取documentElement之前等待5秒钟在理论上听起来不错;但在实践中,元素可能在此之前存在。或者,网络速度很慢,仅获取jQuery脚本就需要5秒钟。
我建议测试您正在查找的元素(例如img标签)是否存在。类似以下内容:
while (browser.Document.GetElementsByTagName("img").Count == 0) {
    Application.DoEvents();
}

这样,您就不需要Thread.Sleep这行代码了。


该脚本将用于从任何给定的URL下载图像,而不是特定的URL,我认为这在我的情况下不起作用。 - Abubakr A.Hafiz
怎么回事?我在回答中没有涉及任何特定的URL。 - MrMister
我需要的是在任何ajax或客户端脚本执行后获取整个文档dom。我不是在寻找特定元素,我想下载任何给定html页面上的所有图像,包括任何标签的背景图像,我已经完成了这个过程,除了我无法下载由ajax请求或客户端脚本加载的图像。 - Abubakr A.Hafiz

2

1

请检查页面在IE7中的呈现效果。我猜你缺少的标签是通过jQuery添加的,而页面上的jQuery版本2.2.4不支持IE7。我认为WebBrowser类即使在PC上安装了更新的IE版本,也会包装IE7。

如果你拥有该页面,请尝试添加jQuery migrate插件。


不确定以下内容是否有帮助?:https://www.cyotek.com/blog/configuring-the-emulation-mode-of-an-internet-explorer-webbrowser-control, https://blogs.msdn.microsoft.com/patricka/2015/01/12/controlling-webbrowser-control-compatibility/,https://weblog.west-wind.com/posts/2011/may/21/web-browser-control-specifying-the-ie-version 和https://dev59.com/jGMm5IYBdhLWcg3wDbin - user1946932
页面在IE7中正确呈现,我将jQuery更改为1.7.1,但没有任何变化。 - Abubakr A.Hafiz
我注意到上面黑色截图中的div类名没有用双引号括起来,images2.jpg的URL也没有。如果这有什么意义的话,我读过XHTML需要使用引号。 - user1946932

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接