WebBrowser控件是.NET框架中提供的一个ActiveX控件封装,允许在Windows Forms或WPF应用程序中嵌入网页浏览器功能。当需要从iframe中提取HTML内容时,需要理解DOM(文档对象模型)结构以及如何与嵌入的网页交互。
using System;
using System.Windows.Forms;
public class IframeHtmlReader
{
private WebBrowser webBrowser;
public IframeHtmlReader(WebBrowser browser)
{
this.webBrowser = browser;
webBrowser.DocumentCompleted += WebBrowser_DocumentCompleted;
}
private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// 确保主文档加载完成
if (webBrowser.ReadyState != WebBrowserReadyState.Complete) return;
// 获取所有iframe元素
HtmlElementCollection iframes = webBrowser.Document.GetElementsByTagName("iframe");
foreach (HtmlElement iframe in iframes)
{
try
{
// 获取iframe的文档对象
HtmlDocument iframeDoc = iframe.Document.Window.Document;
// 获取iframe的HTML内容
string iframeHtml = iframeDoc.Body.Parent.OuterHtml;
Console.WriteLine("IFrame HTML: " + iframeHtml);
}
catch (Exception ex)
{
Console.WriteLine("Error accessing iframe: " + ex.Message);
}
}
}
}
如果iframe来自不同域,由于同源策略限制,直接访问其内容会抛出安全异常。解决方法:
// 在应用程序启动时设置WebBrowser特性以允许跨域访问
// 注意:这会降低安全性
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
private const int GWL_EXSTYLE = -20;
private const int WS_EX_NOACTIVATE = 0x08000000;
private void Form1_Load(object sender, EventArgs e)
{
// 获取WebBrowser控件的窗口句柄
IntPtr handle = webBrowser.Handle;
// 设置窗口特性
SetWindowLong(handle, GWL_EXSTYLE, WS_EX_NOACTIVATE);
// 设置WebBrowser特性以允许跨域访问
webBrowser.ObjectForScripting = this;
webBrowser.AllowWebBrowserDrop = false;
webBrowser.IsWebBrowserContextMenuEnabled = false;
webBrowser.WebBrowserShortcutsEnabled = false;
webBrowser.ScriptErrorsSuppressed = true;
}
另一种方法是注入JavaScript来获取iframe内容:
private void GetIframeContentWithJS()
{
if (webBrowser.ReadyState == WebBrowserReadyState.Complete)
{
HtmlElement head = webBrowser.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = webBrowser.Document.CreateElement("script");
// 定义获取iframe内容的JavaScript函数
string scriptText = @"
function getAllIframesContent() {
var iframes = document.getElementsByTagName('iframe');
var contents = [];
for (var i = 0; i < iframes.length; i++) {
try {
if (iframes[i].contentDocument) {
contents.push(iframes[i].contentDocument.documentElement.outerHTML);
}
} catch (e) {
contents.push('Cross-domain iframe - access denied');
}
}
return contents;
}";
scriptEl.SetAttribute("text", scriptText);
head.AppendChild(scriptEl);
// 调用JavaScript函数并获取结果
object[] contents = webBrowser.Document.InvokeScript("getAllIframesContent") as object[];
foreach (object content in contents)
{
Console.WriteLine("IFrame Content: " + content.ToString());
}
}
}
没有搜到相关的文章