HTML Agility Confezione
-
19-09-2019 - |
Domanda
Ho le tabelle HTML in una pagina web come
<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>
Ora da questa pagina web utilizzando html agilità pacchetto Voglio estrarre i dati dell'indirizzo di colonna e il telefono non solo. Vuol dire per quello che ho trovato prima in cui tavolo c'è indirizzo di colonna e phoneno.After trovare quel tavolo voglio estrarre i dati di tale indirizzo colonna e phoneno cosa devo fare?
posso ottenere il tavolo. Ma dopo che cosa devo fare non capisco.
E un'altra cosa:. È possibile che siamo in grado di estrarre i dati dalla tabella tramite nome della colonna
Soluzione
Ecco alcuni metodi di supporto per aiutare si analizza tabelle HTML per DataTable
istanze. Si può solo scorrere la matrice DataTable
risultante per trovare quello che contiene le colonne che si desidera. Il codice è accoppiato con il formato delle tabelle in HTML, in questo caso si ottiene informazioni di colonna della prima riga (<tr>
). Si noti inoltre che nessun controllo degli errori viene eseguito, quindi questo si romperà volontà tabelle che non seguono il formato specificato.
metodi di supporto:
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;
}
Esempio di utilizzo:
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;
}
}
}
Altri suggerimenti
Loop attraverso tablerows e ottenere i valori delle colonne per indice
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++;
}
Se è possibile modificare la pagina web, è possibile utilizzare thead per i testi di intestazione e tbody per i valori effettivi.
<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>
Allora non avrebbe dovuto saltare la prima fila.
foreach(HtmlNode tablerow in table.SelectNodes("/table[@id=\"mytable\"]/tbody/tr"))
{
// ...
}
Dai uno sguardo ad alcuni XPath tutorial, è molto utile con HtmlAgilityPack.