C# WinForm WebBrowser控件:如何获取选中区域的HTML内容
WinForm WebBrowser控件获取选中区域HTML内容解决方案
我有一个WinForm项目,使用WebBrowser控件加载包含大量HTML表格的网站。用户会通过鼠标在WebBrowser中选中包含多个HTML表格的大段内容。目前已实现获取选中文本的功能,但需要编程获取选中区域的HTML内容,现有代码无法满足需求,请求正确实现方案。
已实现的选中文本获取代码
private string GetSelectedText() { dynamic document = webBrowser1.Document.DomDocument; dynamic selection = document.selection; dynamic text = selection.createRange().text; return (string)text; }
现有无效代码(仅能处理单个表格,无法获取多表格选中区域的HTML)
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; namespace HtmlTableParser { public partial class Form2 : Form { private WebBrowser webBrowser1; public Form2() { InitializeComponent(); Button btn = new Button(); btn.Text = "Test"; btn.Click += button1_Click; this.Controls.Add(btn); var panel = new Panel(); panel.Top = btn.Height + 2; panel.Height = this.ClientSize.Height - btn.Height + 2; panel.Width = this.ClientSize.Width; panel.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom; webBrowser1 = new WebBrowser(); webBrowser1.Dock = DockStyle.Fill; webBrowser1.Url = new Uri("https://www.sec.gov/Archives/edgar/data/1108134/000110813423000018/bhlb-20230630.htm"); panel.Controls.Add(webBrowser1); this.Controls.Add(panel); } private void button1_Click(object sender, EventArgs e) { TestSelection(); TestAllTable(); } private void TestSelection() { var domdoc = this.webBrowser1.Document.DomDocument as mshtml.IHTMLDocument2; var sel = domdoc.selection; var range = sel.createRange(); var trange = range as mshtml.IHTMLTxtRange; var table = GetParentTable(trange.parentElement()); if (table == null) { var startPointRange = trange.duplicate(); startPointRange.setEndPoint("EndToStart", trange); var startPointTable = GetParentTable(startPointRange.parentElement()); var endPointRange = trange.duplicate(); startPointRange.setEndPoint("StartToEnd", trange); var endPointTable = GetParentTable(endPointRange.parentElement()); if (startPointTable != null) { table = startPointTable; } else if (endPointTable != null) { table = endPointTable; } else { MessageBox.Show("Selection is not in Table"); return; } } var tableData = TableData.GetTableData(table); System.Diagnostics.Debug.WriteLine(tableData.ToString()); } private mshtml.IHTMLTable GetParentTable(mshtml.IHTMLElement element) { var parent = element; while (parent != null) { if (parent is mshtml.IHTMLTable table) { return table; } parent = parent.parentElement; } return null; } private void TestAllTable() { var domdoc = this.webBrowser1.Document.DomDocument as mshtml.HTMLDocument; foreach (var table in domdoc.getElementsByTagName("table").OfType<mshtml.IHTMLTable>()) { var tableData = TableData.GetTableData(table); System.Diagnostics.Debug.WriteLine(tableData.ToString()); System.Diagnostics.Debug.WriteLine(new string('=', 20)); } } } class TableData { public static TableData GetTableData(mshtml.IHTMLTable table) { TableData tableData = new TableData(); foreach (var tableRow in table.rows.OfType<mshtml.IHTMLTableRow>()) { RowData rowdata = new RowData(); foreach (var tablecell in tableRow.cells.OfType<mshtml.HTMLTableCell>()) { CellData cell = new CellData(); cell.Text = tablecell.innerText; cell.RowSpan = tablecell.rowSpan; cell.ColSpan = tablecell.colSpan; rowdata.Add(cell); } tableData.Rows.Add(rowdata); } return tableData; } public List<RowData> Rows { get; } = new List<RowData>(); public override string ToString() { System.Text.StringBuilder sb = new StringBuilder(); foreach (var row in this.Rows) { sb.AppendLine(row.ToString()); } return sb.ToString(); } } class RowData : List<CellData> { public override string ToString() { return string.Join("\t", this.Select(cell => cell.Text + new string('\t', cell.ColSpan))); } } class CellData { public string Text { get; set; } public int ColSpan { get; set; } public int RowSpan { get; set; } public override string ToString() => Text; } }
选中内容示例

正确实现方案
前置准备
确保项目已添加Microsoft HTML Object Library COM引用(右键项目→添加→引用→COM→找到并勾选)。
核心代码
private string GetSelectedHtml() { // 获取DOM文档对象 var domDoc = webBrowser1.Document.DomDocument as mshtml.IHTMLDocument2; if (domDoc == null || domDoc.selection == null) return string.Empty; var selection = domDoc.selection; var range = selection.createRange(); // 处理文本范围选中(用户拖动鼠标选中的多表格大段内容) var txtRange = range as mshtml.IHTMLTxtRange; if (txtRange != null) { // 返回选中范围的完整HTML内容 return txtRange.htmlText; } // 处理元素范围选中(比如右键选中的单个/多个元素) var ctrlRange = range as mshtml.IHTMLControlRange; if (ctrlRange != null && ctrlRange.length > 0) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < ctrlRange.length; i++) { var elem = ctrlRange.item(i) as mshtml.IHTMLElement; if (elem != null) sb.Append(elem.outerHTML); } return sb.ToString(); } return string.Empty; }
使用示例
在按钮点击事件中调用该方法,即可获取选中区域的HTML:
private void button1_Click(object sender, EventArgs e) { string selectedHtml = GetSelectedHtml(); // 输出或进一步解析HTML内容 System.Diagnostics.Debug.WriteLine(selectedHtml); }
关键说明
txtRange.htmlText会返回选中范围内的完整HTML,包括所有嵌套表格和元素,完美支持多表格选中场景。- 兼容两种选中模式:文本范围选中(用户拖动鼠标的任意选择)和元素范围选中(右键选择的元素)。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

