C# WebBrowser 控件——在 AJAX 之后获取文档元素?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/635948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# WebBrowser control -- Get Document Elements After AJAX?
提问by aikeru
I'm writing an application that uses the WebBrowser control to view web content that can change with AJAX that adds new content/elements. I can't seem to get at the new elements any way I've tried. BrowserCtl.DocumentText doesn't have the up-to-date page and of course it's not in "view source" either.
我正在编写一个应用程序,它使用 WebBrowser 控件来查看可以通过添加新内容/元素的 AJAX 更改的 Web 内容。我似乎无法以任何尝试过的方式获得新元素。BrowserCtl.DocumentText 没有最新的页面,当然它也不在“查看源代码”中。
Is there some way to get this new data using this control? :( Please help. Thanks!
有什么方法可以使用此控件获取这些新数据吗?:(请帮忙。谢谢!
IE:
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 :(
回答by Chloraphil
Do you control the web page?
你控制网页吗?
If so, here's a blog post that explains how: http://www.palladiumconsulting.com/blog/sebastian/2007/04/ultimate-intranet-toy.html
如果是这样,这里的博客文章解释了如何:http: //www.palladiumconsulting.com/blog/sebastian/2007/04/ultimate-intranet-toy.html
If not, there's probably a solution but I can't help you, sorry.
如果没有,可能有解决方案,但我帮不了你,抱歉。
回答by Eugene Petrenko
You will need to use DOM for it. Cast WebBrowser.Document.DomDocument to IHTMLDocument?. You will have to import some COM interfaces or Microsoft.mshtml assembly.
您将需要为此使用 DOM。将 WebBrowser.Document.DomDocument 转换为 IHTMLDocument?。您将不得不导入一些 COM 接口或 Microsoft.mshtml 程序集。
Have a look to http://msdn.microsoft.com/en-us/library/aa752641(VS.85).aspxfor more details.
查看http://msdn.microsoft.com/en-us/library/aa752641(VS.85).aspx了解更多详细信息。
回答by John Lewin
I assume that since you're reading content which is generated from Ajax requests that you require the user to progress the application to a point where the relevant data is loaded, at which point you run code to read the data.
我假设由于您正在阅读从 Ajax 请求生成的内容,因此您需要用户将应用程序推进到加载相关数据的位置,然后运行代码来读取数据。
If that's not the case, you'll need to automate this process, generating the click events which build out the DOM nodes you're interested in reading. I do this somewhat commonly with the WebBrowser control and tend to write that layer of functionality in Javascript and call it with .InvokeScript(). Another route would be to find the nodes which fire the Ajax functionality from C# and manually trigger their click events:
如果不是这种情况,您需要自动执行此过程,生成点击事件,从而构建您有兴趣阅读的 DOM 节点。我通常使用 WebBrowser 控件执行此操作,并且倾向于在 Javascript 中编写该功能层并使用 .InvokeScript() 调用它。另一种方法是找到从 C# 触发 Ajax 功能的节点并手动触发它们的点击事件:
HtmlElement content = webMain.Document.GetElementById("content");
content.RaiseEvent("onclick");
An important aspect to note in the script above is the fact that you can interact with DOM nodes naively in C# if you accept and work around the limitations of the HtmlElement object type.
在上面的脚本中需要注意的一个重要方面是,如果您接受并解决 HtmlElement 对象类型的限制,您可以在 C# 中天真地与 DOM 节点进行交互。
回答by Proximo
How about running javascript to caption the element and displaying it in a new window?
如何运行 javascript 来为元素添加标题并将其显示在新窗口中?
I haven't tested it out but it may work.
我还没有测试过,但它可能有效。
(WebBrowser)w.Navigate("javascript:GetElementById('div').innerHtml;", true);
The true attribute to open the return in a new windows. (Or a frame or maybe you can find a better way)
在新窗口中打开返回的 true 属性。(或者一个框架或者你可以找到更好的方法)
To capture the NewWindow event you'll need to reference the SHDocVw.dll which is in your Windows/System32 folder. Then you can cast your WebBrowser Control like this:
要捕获 NewWindow 事件,您需要引用 Windows/System32 文件夹中的 SHDocVw.dll。然后你可以像这样投射你的 WebBrowser 控件:
SHDocVw.WebBrowser_V1 browser = (SHDocVw.WebBrowser_V1)(WebBrowser)w.ActiveXInstance;
You can have it close right away after storing the response. Well good luck and let me know how it goes.
您可以在存储响应后立即关闭它。祝你好运,让我知道进展如何。
回答by Fraser
Is the information not in the WebBrowser.DocumentText? http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.documenttext.aspx
信息是否不在 WebBrowser.DocumentText 中?http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.documenttext.aspx
回答by xian
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);
}
}
}
回答by Evren Yortucboylu
I solved the problem for me.
我为我解决了这个问题。
the key is, attaching a handler for onPropertyChanged
event of the div element which is being populated via ajax call.
关键是,为onPropertyChanged
通过 ajax 调用填充的 div 元素的事件附加一个处理程序。
HtmlElement target = webBrowser.Document.GetElementById("div_populated_by_ajax");
if (target != null)
{
target.AttachEventHandler("onpropertychange", handler);
}
and finally,
最后,
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
}