基于Html Agility Pack提取无标识表格数据的技术咨询
Got it, let's solve this problem using Html Agility Pack—since your tables don't have fixed IDs or XPaths, we'll anchor everything to that reliable CONSTANT_TEXT marker. Here's how to hit both your requirements:
1. Get the CHANGING_VALUE from the same row as CONSTANT_TEXT
Instead of targeting the anchor tag first, start by finding the <td> that contains your fixed CONSTANT_TEXT. Once you have that node, you can easily grab the second <td> in its parent row, no matter where the table sits in the HTML structure.
// Locate the <td> holding the fixed CONSTANT_TEXT var constantTd = document.DocumentNode.SelectSingleNode("//td[contains(text(), 'CONSTANT_TEXT')]"); if (constantTd != null) { // Navigate up to the parent <tr> (the row containing our target td) var parentRow = constantTd.ParentNode; if (parentRow != null && parentRow.Name.Equals("tr", StringComparison.OrdinalIgnoreCase)) { // Grab the second <td> in this row to get CHANGING_VALUE var valueTd = parentRow.SelectSingleNode("./td[2]"); if (valueTd != null) { string changingValue = valueTd.InnerText.Trim(); // Use your extracted value here Console.WriteLine($"Extracted value: {changingValue}"); } } }
2. Get the parent table containing CONSTANT_TEXT
To find the closest (lowest-level) parent table, you can either traverse up the node tree manually or use an XPath ancestor axis for a cleaner approach:
Option 1: Manual traversal
if (constantTd != null) { HtmlNode parentTable = null; var currentNode = constantTd.ParentNode; // Move up through parent nodes until we hit a <table> while (currentNode != null && !currentNode.Name.Equals("table", StringComparison.OrdinalIgnoreCase)) { currentNode = currentNode.ParentNode; } if (currentNode != null) { parentTable = currentNode; // Access the table's content, e.g., get its full HTML string tableHtml = parentTable.OuterHtml; Console.WriteLine($"Parent table HTML: {tableHtml}"); } }
Option 2: XPath ancestor axis (more concise)
This XPath query directly finds the nearest parent <table> to your target <td>:
if (constantTd != null) { var parentTable = constantTd.SelectSingleNode("./ancestor::table[1]"); if (parentTable != null) { // Work with the parent table here Console.WriteLine($"Found parent table with {parentTable.SelectNodes(".//tr").Count} rows"); } }
Why this works better than your original approach
Your initial code targeted the anchor tag with CONSTANT_ID, but since your core marker is CONSTANT_TEXT, starting there ensures you're always aligned with the right row and table—even if the anchor tag's ID or position shifts slightly across files.
内容的提问来源于stack exchange,提问作者michal

