HTML Agility pack-análisis de tablas


Quiero usar el paquete de agilidad HTML para analizar tablas de páginas web complejas, pero de alguna manera estoy perdido en el modelo de objetos.

Miré el ejemplo de enlace, pero no encontré ningún dato de tabla de esta manera. Puedo usar XPath para obtener las tablas? Básicamente estoy perdido después de haber cargado los datos sobre cómo obtener las tablas. He hecho esto en Perl antes y fue un poco torpe, pero funcionó. (HTML::TableParser).

También estoy feliz si uno puede arrojar una luz sobre el orden correcto del objeto para el analizar.

Author: Nathaniel Ford, 2009-03-17

4 answers

¿Qué tal algo como: Usando HTML Agility Pack

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);
        }
    }
}

Ten en cuenta que puedes hacerlo más bonito con LINQ-to-Objects si quieres:

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);
}
 104
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-28 17:52:37

Lo más simple que he encontrado para obtener el XPath de un elemento en particular es instalar la extensión FireBug para Firefox ir al sitio/página web pulse F12 para abrir firebug; seleccione derecho y haga clic derecho en el elemento de la página que desea consultar y seleccione "Inspeccionar elemento" Firebug seleccionará el elemento en su IDE, luego haga clic derecho en el elemento en Firebug y elija "Copiar XPath" esta función le dará la Consulta XPath exacta que necesita para obtener el elemento que desea usar Agilidad HTML Biblioteca.

 31
Author: Coda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-23 17:33:23

Línea de arriba respuesta:

HtmlDocument doc = new HtmlDocument();

Esto no funciona en C#VS 2015. Ya no se puede construir un HtmlDocument.

Otra "característica" de MS que hace que las cosas sean más difíciles de usar. Prueba HtmlAgilityPack.HtmlWeb y echa un vistazo a este enlace para ver un código de ejemplo.

 0
Author: rk42,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-13 02:37:14

En mi caso, hay una sola tabla que resulta ser una lista de dispositivos de un enrutador. Si desea leer la tabla usando TR/TH/TD (fila, encabezado, datos) en lugar de una matriz como se mencionó anteriormente, puede hacer algo como lo siguiente:

    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 es solo un objeto simple con Encabezado y Datos como propiedades. El enfoque se encarga de null-ness y este caso:

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

Que es fila sin cabecera. El objeto HTMLBody con las constantes colgando fuera de ella probablemente se deducen fácilmente, pero me disculpo por ello aún. Vine del mundo donde si tienes " en tu código, debe ser constante o localizable.

 0
Author: Shibumi Tait,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-05 03:51:22