使用 WebBrowser 访问 DOM

Posted

技术标签:

【中文标题】使用 WebBrowser 访问 DOM【英文标题】:Access the DOM using WebBrowser 【发布时间】:2017-07-18 15:52:11 【问题描述】:

在页面上执行 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();
    



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

【问题讨论】:

请不要将代码发布为图片。将代码作为文本发布。此外,您应该使用事件来查找导航何时完成,而不是使用 while 循环 Application.DoEvents()Thread.Sleep() 我将代码添加为文本、图像以阐明浏览器中的 dom 与我得到的内容之间的区别 使用替代控件怎么样?例如。 ***.com/questions/790542/… 我用idealtackle.com作为url参数测试了你的代码,每次页面通过javascript加载时都会改变一个图像,在加载它两个不同的时间后,加载了两个不同的图像没问题,如果你想自己看看,在 browser.Dispose() 上放一个断点;然后在第 121 行的快速查看中查看 html,背景图像:每次加载时都会更改。所以我的猜测是这应该是因为您的浏览器版本或运行 javascript 的安全性或类似的东西。 能否请您给我们您的网址,我也核对一下? 【参考方案1】:

如果客户端脚本确实如您所说在 IE7 中执行,则问题可能纯粹是时间问题。即使在文档加载完成后,您也无法确切知道 何时 JS 脚本将被执行。在尝试到达documentElement 之前等待 5 秒在理论上听起来是个好主意;在实践中,该元素可能在此之前存在。或者,也许网络很慢,仅获取 jQuery 脚本本身需要 5 秒。

我建议测试您正在寻找的元素是否存在(img 标签,视情况而定)。类似于

while (browser.Document.GetElementsByTagName("img").Count == 0) 
    Application.DoEvents();

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

【讨论】:

该脚本将用于从任何给定的 URL 下载图像,而不是特定的,我认为这不适用于我的情况。 怎么回事?我的回答中没有考虑任何特定的 URL。 我正在寻找的是在执行任何 ajax 或客户端脚本之后获取整个文档 dom。我不是在这里寻找特定元素,我想下载任何给定 html 页面上的所有图像,包括任何标签的背景图像,我已经完成了,除了我无法下载由 ajax 请求或通过客户端脚本。【参考方案2】:

我看不到这里正在执行的 js,但我想你可以准确地找到正在更新的元素,并在 onprpertychange 事件时附加一个事件处理程序,就像这里给出的解决方案一样: C# WebBrowser control -- Get Document Elements After AJAX?

如果 js 是按类而不是按想法翻转元素,那么您可以从这里借用逻辑: How to select a class by GetElementByClass and click on it programmically

【讨论】:

【参考方案3】:

检查页面在 IE7 中的呈现方式。我猜你缺少的标签是用jQuery添加的,页面上的jQuery 2.2.4版本不支持IE7。我认为 WebBrowser 类确实围绕 IE7,即使您的 PC 上有更新版本的 IE。

如果您拥有该页面,请尝试添加 jQuery 迁移插件。

【讨论】:

不确定以下是否有帮助?:cyotek.com/blog/…、blogs.msdn.microsoft.com/patricka/2015/01/12/…、weblog.west-wind.com/posts/2011/may/21/… 和 ***.com/questions/17922308/… 页面在 IE7 中正确呈现,我将 jQuery 更改为 1.7.1 但没有任何改变。 我确实注意到上面黑色屏幕截图中的 div 类名不是双引号,如果这意味着什么,那么 images2.jpg URL 也不是。我读到 XHTML 需要引号。

以上是关于使用 WebBrowser 访问 DOM的主要内容,如果未能解决你的问题,请参考以下文章

从 WebBrowser 访问 DOM

从WebBrowser访问DOM

C# WebBrowser 控件:window.external 访问子对象

访问文件夹时,Webbrowser 控件身份验证不起作用

Frame和WebBrowser关系

如何使用webbrowser获取网页的源代码