【问题标题】:C# WebBrowser control -- Get Document Elements After AJAX?C# WebBrowser 控件——在 AJAX 之后获取文档元素?
【发布时间】:2010-10-12 18:22:23
【问题描述】:

我正在编写一个应用程序,该应用程序使用 WebBrowser 控件来查看 Web 内容,这些内容可以通过添加新内容/元素的 AJAX 进行更改。 我似乎无法以任何我尝试过的方式了解新元素。 BrowserCtl.DocumentText 没有最新的页面,当然也不在“查看源代码”中。

有没有办法使用这个控件来获取这些新数据? :( 请帮忙。谢谢!

IE:

Browser.Navigate("www.somewebpagewithAJAX.com");
//Code that waits for browser to finish...
...
//WebBrowser control has loaded content and AJAX has loaded new content
// (is visible at runtime on form) but can't see them in Browser.Document.All
// or Browser.DocumentText :(

【问题讨论】:

    标签: c# javascript ajax browser


    【解决方案1】:

    你控制网页吗?

    如果是这样,这里有一篇博文解释了如何: http://www.palladiumconsulting.com/blog/sebastian/2007/04/ultimate-intranet-toy.html

    如果没有,可能有解决方案,但我帮不了你,对不起。

    【解决方案2】:

    您需要为此使用 DOM。将 WebBrowser.Document.DomDocument 转换为 IHTMLDocument?。您必须导入一些 COM 接口或 Microsoft.mshtml 程序集。

    查看http://msdn.microsoft.com/en-us/library/aa752641(VS.85).aspx了解更多详情。

    【讨论】:

    • 哎哟!我想,如果可能的话,我想避免这种情况。我可以很好地使用 HtmlElement.DomElement COM 类型,但是 IHTMLDocument 会在 javascript 后具有现在更改的元素吗?
    • 我也在尝试这样做,你找到解决方案了吗?
    【解决方案3】:

    我假设由于您正在读取从 Ajax 请求生成的内容,因此您需要用户将应用程序推进到加载相关数据的位置,此时您运行代码来读取数据。

    如果不是这样,您需要自动执行此过程,生成构建您有兴趣阅读的 DOM 节点的点击事件。我通常使用 WebBrowser 控件执行此操作,并且倾向于在 Javascript 中编写该层功能并使用 .InvokeScript() 调用它。另一种方法是找到从 C# 触发 Ajax 功能的节点并手动触发它们的点击事件:

    HtmlElement content = webMain.Document.GetElementById("content");
    content.RaiseEvent("onclick");
    

    在上面的脚本中要注意的一个重要方面是,如果您接受并解决 HtmlElement 对象类型的限制,您可以在 C# 中天真地与 DOM 节点交互。

    【讨论】:

    • 感谢您提供信息丰富的帖子,不幸的是,我的问题在于一旦 JavaScript 已经运行,页面上有新元素需要与之交互或检查来自...文档的值.x 似乎没有这些新元素 post-javascript :(
    • .Document 引用提供对 DOM 的实时访问,并且在初始加载后创建的元素与原始元素一样可访问。生成的元素是否有可能存在于框架中?你能分享出现问题的页面吗?
    【解决方案4】:

    如何运行 javascript 为元素添加标题并在新窗口中显示它?

    我还没有测试过,但它可能有效。

    (WebBrowser)w.Navigate("javascript:GetElementById('div').innerHtml;", true);
    

    在新窗口中打开返回的 true 属性。 (或者一个框架或者你可以找到更好的方法)

    要捕获 NewWindow 事件,您需要引用 Windows/System32 文件夹中的 SHDocVw.dll。然后你可以像这样投射你的 WebBrowser 控件:

    SHDocVw.WebBrowser_V1 browser = (SHDocVw.WebBrowser_V1)(WebBrowser)w.ActiveXInstance;
    

    您可以在存储响应后立即关闭它。祝你好运,让我知道进展如何。

    【讨论】:

      【解决方案5】:

      【讨论】:

        【解决方案6】:
        using System;
        using System.Windows.Forms;
        
        namespace WebBrowserDemo
        {
            class Program
            {
                public const string TestUrl = "http://www.w3schools.com/Ajax/tryit_view.asp?filename=tryajax_first";
        
                [STAThread]
                static void Main(string[] args)
                {
                    WebBrowser wb = new WebBrowser();
                    wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);
                    wb.Navigate(TestUrl);
        
                    while (wb.ReadyState != WebBrowserReadyState.Complete)
                    {
                        Application.DoEvents();
                    }
        
                    Console.WriteLine("\nPress any key to continue...");
                    Console.ReadKey(true);
                }
        
                static void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
                {
                    WebBrowser wb = (WebBrowser)sender;
        
                    HtmlElement document = wb.Document.GetElementsByTagName("html")[0];
                    HtmlElement button = wb.Document.GetElementsByTagName("button")[0];
        
                    Console.WriteLine(document.OuterHtml + "\n");
        
                    button.InvokeMember("Click");
        
                    Console.WriteLine(document.OuterHtml);           
                }
            }
        }
        

        【讨论】:

        • 不错的解决方案。我只是为了好玩而尝试简单的事情,这看起来很不错。
        • 这会继续渲染旧的 html。在 .Net 4.0 中尝试过
        【解决方案7】:

        我为我解决了这个问题。

        关键是,为通过 ajax 调用填充的 div 元素的onPropertyChanged 事件附加一个处理程序。

        HtmlElement target = webBrowser.Document.GetElementById("div_populated_by_ajax");
        
        if (target != null)
        {
              target.AttachEventHandler("onpropertychange", handler);
        }
        

        最后,

        private void handler(Object sender, EventArgs e)
        {
              HtmlElement div = webBrowser.Document.GetElementById("div_populated_by_ajax");
              if (div == null) return;
              String contentLoaded = div.InnerHtml; // get the content loaded via ajax
        }
        

        【讨论】:

        • 嗨,我一直在尝试用 youtube cmets 来做这件事,但我不知道这是如何工作的。
        猜你喜欢
        • 2011-01-11
        • 2012-08-29
        • 1970-01-01
        • 1970-01-01
        • 2011-08-22
        • 1970-01-01
        • 1970-01-01
        • 2012-05-07
        • 2011-09-30
        相关资源
        最近更新 更多