Obtención de datos de la tabla HTML en una tabla de datos

c# html html-agility-pack linq xpath

Pregunta

Ok, así que necesito consultar un sitio web en vivo para obtener datos de una tabla, poner esta tabla HTML en un DataTable y luego usar estos datos. Hasta ahora he logrado usar Html Agility Pack y XPath para llegar a cada fila de la tabla que necesito, pero sé que debe haber una forma de analizarlo en un DataTable. (C #) El código que estoy usando actualmente es:

string htmlCode = "";
using (WebClient client = new WebClient())
{
htmlCode = client.DownloadString("http://www.website.com");
}
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();

doc.LoadHtml(htmlCode);

//My attempt at LINQ to solve the issue (not sure where to go from here)
var myTable = doc.DocumentNode
.Descendants("table")
.Where(t =>t.Attributes["summary"].Value == "Table One")
.FirstOrDefault();

//Finds all the odd rows (which are the ones I actually need but would prefer a
//DataTable containing all the rows!
foreach (HtmlNode cell in doc.DocumentNode.SelectNodes("//tr[@class='odd']/td"))
{
string test = cell.InnerText;
//Have not gone further than this yet!
}

La tabla HTML en el sitio web que estoy consultando se ve así:

<table summary="Table One">
<tbody>
<tr class="odd">
<td>Some Text</td>
<td>Some Value</td>
</tr>
<tr class="even">
<td>Some Text1</td>
<td>Some Value1</td>
</tr>
<tr class="odd">
<td>Some Text2</td>
<td>Some Value2</td>
</tr>
<tr class="even">
<td>Some Text3</td>
<td>Some Value3</td>
</tr>
<tr class="odd">
<td>Some Text4</td>
<td>Some Value4</td>
</tr>
</tbody>
</table>

No estoy seguro de si es mejor / más fácil usar LINQ + HAP o XPath + HAP para obtener el resultado deseado, probé ambos con un éxito limitado como probablemente pueda ver. ¡Esta es la primera vez que hago un programa para consultar un sitio web o incluso interactuar con un sitio web de alguna manera, por lo que estoy muy inseguro en este momento! Gracias por cualquier ayuda por adelantado :)

Respuesta aceptada

No existe un método de este tipo fuera del paquete del paquete de agilidad de HTML, pero no debería ser demasiado difícil crear uno. Hay muestras por ahí que hacen de XML a Datatable desde Linq a XML. Estos pueden ser re-trabajados en lo que necesita.

Si es necesario, puedo ayudar a crear todo el método, pero no hoy :).

Ver también:


Respuesta popular

Usando algunos de los códigos de Jack Eker de arriba y algunos códigos de Mark Gravell ( vea la publicación aquí ), logré encontrar una solución. Este fragmento de código se utiliza para obtener los días festivos del año 2012 en Sudáfrica a partir de la redacción de este artículo.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Web;
using System.Net;
using HtmlAgilityPack;



namespace WindowsFormsApplication
{
    public partial class Form1 : Form
    {
        private DataTable dt;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            string htmlCode = "";
            using (WebClient client = new WebClient())
            {
                client.Headers.Add(HttpRequestHeader.UserAgent, "AvoidError");
                htmlCode = client.DownloadString("http://www.info.gov.za/aboutsa/holidays.htm");
            }
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();

            doc.LoadHtml(htmlCode);

            dt = new DataTable();
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Value", typeof(string));

            int count = 0;


            foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table"))
            {

                foreach (HtmlNode row in table.SelectNodes("tr"))
                {

                    if (table.Id == "table2")
                    {
                        DataRow dr = dt.NewRow();

                        foreach (var cell in row.SelectNodes("td"))
                        {
                            if ((count % 2 == 0))
                            {
                                dr["Name"] = cell.InnerText.Replace("&nbsp;", " ");
                            }
                            else
                            {

                                dr["Value"] = cell.InnerText.Replace("&nbsp;", " ");

                                dt.Rows.Add(dr);
                            }
                            count++;

                        }


                    }

                }


                dataGridView1.DataSource = dt;

            }
        }

    }
}


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é