HTML Agility-Pack
-
19-09-2019 - |
Frage
Ich habe HTML-Tabellen in einer Webseite wie
<table border=1>
<tr><td>sno</td><td>sname</td></tr>
<tr><td>111</td><td>abcde</td></tr>
<tr><td>213</td><td>ejkll</td></tr>
</table>
<table border=1>
<tr><td>adress</td><td>phoneno</td><td>note</td></tr>
<tr><td>asdlkj</td><td>121510</td><td>none</td></tr>
<tr><td>asdlkj</td><td>214545</td><td>none</td></tr>
</table>
Jetzt auf dieser Webseite mit HTML-Agilität packen ich die Daten der Spaltenadresse und Telefonnummer nur extrahieren möchten. Es bedeutet für dass ich zum ersten Mal dort, in der Tabelle finden haben Spaltenadresse und phoneno.After finden diese Tabelle ich die Daten dieser Spaltenadresse und PHONENO extrahieren möchten, was soll ich tun?
kann ich den Tisch bekommen. Aber danach, was soll ich nicht verstehen.
Und andere Sache. Ist möglich, dass wir Daten aus der Tabelle durch Spaltennamen extrahieren
Lösung
Hier sind einige Hilfsmethoden helfen Ihnen Parse-HTML-Tabellen zu DataTable
Instanzen. Sie können Iterierte nur durch den resultierenden DataTable
Array, das zu finden, die Spalten enthalten, die Sie wollen. Der Code mit dem Format der Tabellen in der HTML, in diesem Fall verbunden ist, erhält sie Spalteninformation von der ersten Reihe (<tr>
). Beachten Sie auch, dass keine Fehlerprüfung durchgeführt wird, so dass dies wird Tabellen brechen, die nicht das Format folgen Sie angegeben haben.
Helper-Methoden:
private static DataTable[] ParseAllTables(HtmlDocument doc)
{
var result = new List<DataTable>();
foreach (var table in doc.DocumentNode.Descendants("table"))
{
result.Add(ParseTable(table));
}
return result.ToArray();
}
private static DataTable ParseTable(HtmlNode table)
{
var result = new DataTable();
var rows = table.Descendants("tr");
var header = rows.Take(1).First();
foreach (var column in header.Descendants("td"))
{
result.Columns.Add(new DataColumn(column.InnerText, typeof(string)));
}
foreach (var row in rows.Skip(1))
{
var data = new List<string>();
foreach (var column in row.Descendants("td"))
{
data.Add(column.InnerText);
}
result.Rows.Add(data.ToArray());
}
return result;
}
Anwendungsbeispiel:
public static void Main(string[] args)
{
string html = @"
<html><head></head>
<body><div>
<table border=1>
<tr><td>sno</td><td>sname</td></tr>
<tr><td>111</td><td>abcde</td></tr>
<tr><td>213</td><td>ejkll</td></tr>
</table>
<table border=1>
<tr><td>adress</td><td>phoneno</td><td>note</td></tr>
<tr><td>asdlkj</td><td>121510</td><td>none</td></tr>
<tr><td>asdlkj</td><td>214545</td><td>none</td></tr>
</table>
</div></body>
</html>";
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html);
DataTable addressAndPhones;
foreach (var table in ParseAllTables(doc))
{
if (table.Columns.Contains("phoneno") && table.Columns.Contains("adress"))
{
// You found the address and phone number table
addressAndPhones = table;
}
}
}
Andere Tipps
Schleife durch TableRows und Spaltenwerte durch den Index erhalten
int index = 0;
foreach(HtmlNode tablerow in table.SelectNodes("tr"))
{
// skip the first row...
if(index > 0)
{
// select first td element
HtmlNode td1 = tablerow.SelectSingleNode("td[1]");
if(td1 != null)
{
string address = td1.InnerText;
}
}
index++;
}
Wenn Sie die Webseite ändern können, könnten Sie für Kopftexte und tbody für Istwerte verwenden thead.
<table id="mytable">
<thead><tr><td>Column1</td><td>Column2</td></tr></thead>
<tbody>
<tr><td>Value 1</td><td>Value 2</td></tr>
<tr><td>Value 1</td><td>Value 2</td></tr>
</tbody>
</table>
Dann würden Sie nicht die erste Zeile zu überspringen haben.
foreach(HtmlNode tablerow in table.SelectNodes("/table[@id=\"mytable\"]/tbody/tr"))
{
// ...
}
Haben Sie einen Blick auf einige XPath-Tutorial, es ist sehr nützlich, mit HtmlAgilityPack.