Pregunta

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 de los objetos para el análisis.

¿Fue útil?

Solución

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

Tenga en cuenta que puede hacerlo más bonito con LINQ-to-Objects si lo desea:

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

Otros consejos

Lo más simple que he encontrado para obtener el XPath para un Elemento en particular es instalar la extensión FireBug para Firefox, ir al sitio / página web y presionar F12 para abrir firebug; seleccione y haga clic con el botón derecho en el elemento en la página que desea consultar y seleccione "Inspeccionar elemento" Firebug seleccionará el elemento en su IDE, luego haga clic con el botón 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 utilizando la Biblioteca de agilidad HTML.

Sé que esta es una pregunta bastante antigua, pero esta fue mi solución que ayudó a visualizar la tabla para que pueda crear una estructura de clase. Esto también está usando el paquete de agilidad 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();
}

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 ocupa de la nulidad y este caso:

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

que es una fila sin encabezado. El objeto HtmlBody con las constantes colgando de él probablemente se deduzca fácilmente, pero me disculpo por ello aún. Vine del mundo donde si tienes " en su código, debe ser constante o localizable.

Línea desde la respuesta anterior:

HtmlDocument doc = new HtmlDocument();

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

Otra MS '' característica '' eso hace que las cosas sean más difíciles de usar. Pruebe HtmlAgilityPack.HtmlWeb y consulte este enlace para algún código de muestra.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top