Question

Je souhaite utiliser le pack d'agilité HTML pour analyser des tables à partir de pages Web complexes, mais je suis en quelque sorte perdu dans le modèle d'objet.

J'ai consulté l'exemple de lien, mais je n'ai trouvé aucune donnée de table de cette façon. Puis-je utiliser XPath pour obtenir les tables? Je suis fondamentalement perdu après avoir chargé les données sur la façon d’obtenir les tables. J'ai déjà fait cela en Perl et c'était un peu maladroit, mais ça a fonctionné. ( HTML :: TableParser ).

Je suis également heureux si l'on peut simplement éclaircir le bon ordre des objets pour l'analyse.

Était-ce utile?

La solution

Que diriez-vous de quelque chose comme: Utilisation du Pack d'agilité HTML

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(@"<html><body><p><table id=""foo""><tr><th>hello</th></tr><tr><td>world</td></tr></table></body></html>");
foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table")) {
    Console.WriteLine("Found: " + table.Id);
    foreach (HtmlNode row in table.SelectNodes("tr")) {
        Console.WriteLine("row");
        foreach (HtmlNode cell in row.SelectNodes("th|td")) {
            Console.WriteLine("cell: " + cell.InnerText);
        }
    }
}

Notez que vous pouvez le rendre plus joli avec LINQ-to-Objects si vous le souhaitez:

var query = from table in doc.DocumentNode.SelectNodes("//table").Cast<HtmlNode>()
            from row in table.SelectNodes("tr").Cast<HtmlNode>()
            from cell in row.SelectNodes("th|td").Cast<HtmlNode>()
            select new {Table = table.Id, CellText = cell.InnerText};

foreach(var cell in query) {
    Console.WriteLine("{0}: {1}", cell.Table, cell.CellText);
}

Autres conseils

Le plus simple que j’ai trouvé pour obtenir le XPath pour un élément particulier est d’installer l’extension FireBug pour Firefox. Allez sur le site / la page Web. Appuyez sur F12 pour afficher firebug; sélectionnez et faites un clic droit sur l'élément de la page que vous souhaitez interroger, puis sélectionnez " Inspecter l'élément " Firebug sélectionnera l'élément dans son environnement de développement intégré, puis cliquera sur l'élément dans Firebug avec le bouton droit de la souris et choisir "Copier XPath". cette fonction vous donnera la requête XPath exacte dont vous avez besoin pour obtenir l’élément souhaité à l’aide de HTML Agility Library.

Je sais que c’est une question assez ancienne, mais c’était ma solution qui permettait de visualiser le tableau afin que vous puissiez créer une structure de classe. Ceci utilise également le pack d'agilité HTML

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(@"<html><body><p><table id=""foo""><tr><th>hello</th></tr><tr><td>world</td></tr></table></body></html>");
var table = doc.DocumentNode.SelectSingleNode("//table");
var tableRows = table.SelectNodes("tr");
var columns = tableRows[0].SelectNodes("th/text()");
for (int i = 1; i < tableRows.Count; i++)
{
    for (int e = 0; e < columns.Count; e++)
    {
        var value = tableRows[i].SelectSingleNode(<*>quot;td[{e + 1}]");
        Console.Write(columns[e].InnerText + ":" + value.InnerText);
    }
Console.WriteLine();
}

Dans mon cas, il existe une seule table qui se trouve être une liste de périphériques d’un routeur. Si vous souhaitez lire la table en utilisant TR / TH / TD (ligne, en-tête, données) au lieu d’une matrice comme indiqué ci-dessus, vous pouvez procéder de la manière suivante:

    List<TableRow> deviceTable = (from table in document.DocumentNode.SelectNodes(XPathQueries.SELECT_TABLE)
                                       from row in table?.SelectNodes(HtmlBody.TR)
                                       let rows = row.SelectSingleNode(HtmlBody.TR)
                                       where row.FirstChild.OriginalName != null && row.FirstChild.OriginalName.Equals(HtmlBody.T_HEADER)
                                       select new TableRow
                                       {
                                           Header = row.SelectSingleNode(HtmlBody.T_HEADER)?.InnerText,
                                           Data = row.SelectSingleNode(HtmlBody.T_DATA)?.InnerText}).ToList();
                                       }  

TableRow est juste un objet simple avec en-tête et données en tant que propriétés. L’approche prend en charge la nullité et ce cas:

<tr>
    <td width="28%">&nbsp;</td>
</tr>

qui est une ligne sans en-tête. On en déduit probablement les objets HtmlBody avec les constantes pendantes, mais je m'en excuse quand même. Je viens du monde où vous avez " dans votre code, il devrait être soit constant, soit localisable.

Ligne de la réponse ci-dessus:

HtmlDocument doc = new HtmlDocument();

Cela ne fonctionne pas dans VS 2015 C #. Vous ne pouvez plus construire un HtmlDocument .

Une autre fonction MS """ cela rend les choses plus difficiles à utiliser. Essayez HtmlAgilityPack.HtmlWeb et vérifiez ce lien pour un exemple de code.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top