Paquete de agilidad HTML

c# html-agility-pack html-parsing winforms

Pregunta

Tengo tablas html en una página web como

<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>

Ahora, desde esta página web que utiliza el paquete de agilidad html, deseo extraer los datos de la dirección de la columna y no solo del teléfono. Significa que primero he encontrado en qué tabla hay dirección de columna y phoneno. Después de encontrar esa tabla, deseo extraer los datos de esa dirección de columna y phoneno, ¿qué debo hacer?

Puedo conseguir la mesa. Pero después de eso, ¿qué debo hacer? No entiendo.

Y otra cosa: es factible que podamos extraer datos de la tabla a través del nombre de la columna.

Respuesta aceptada

Aquí hay algunos métodos de ayuda para ayudarlo a analizar tablas HTML a instancias de DataTable . Puede simplemente recorrer la matriz DataTable resultante para encontrar la que contiene las columnas que desea. El código se combina con el formato de las tablas en el HTML, en este caso, obtiene información de columna de la primera fila ( <tr> ). También tenga en cuenta que no se realiza ninguna comprobación de errores, por lo que se romperán las tablas que no siguen el formato que especificó.

Métodos de ayuda:

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

Ejemplo de uso:

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

Respuesta popular

Recorrer tableros y obtener valores de columna por índice

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

Si puede modificar la página web, puede usar thead para los textos de encabezado y tbody para los valores reales.

<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>

Entonces no tendrías que saltarte la primera fila.

foreach(HtmlNode tablerow in table.SelectNodes("/table[@id=\"mytable\"]/tbody/tr"))
{
    // ...
}

Echa un vistazo a algunos tutoriales de xpath, es muy útil con HtmlAgilityPack.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué