Obtenir des données d'un tableau HTML dans un datatable

c# html html-agility-pack linq xpath

Question

Ok, je dois donc interroger un site Web actif pour obtenir les données d'une table, placer cette table HTML dans un DataTable, puis utiliser ces données. Jusqu'à présent, j'ai réussi à utiliser Html Agility Pack et XPath pour accéder à chaque ligne de la table dont j'ai besoin, mais je sais qu'il doit y avoir un moyen de l'analyser dans un DataTable. (C #) Le code que j'utilise actuellement est le suivant:

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

Le tableau HTML sur le site Web que j'interroge ressemble à ceci:

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

Je ne sais pas s'il est préférable / plus facile d'utiliser LINQ + HAP ou XPath + HAP pour obtenir le résultat souhaité. J'ai essayé les deux avec un succès limité, comme vous pouvez probablement le constater. C'est la première fois que je crée un programme permettant d'interroger un site Web ou même d'interagir avec un site Web de quelque manière que ce soit, alors je suis très incertain pour le moment! Merci d'avance pour toute aide :)

Réponse acceptée

Il n’existe aucune méthode de ce type dans le pack Agility HTML, mais vous ne devriez pas en créer trop. Il existe des exemples qui font XML to Datatable de Linq-to-XML. Ceux-ci peuvent être retravaillés dans ce dont vous avez besoin.

Si nécessaire, je peux aider à créer l'ensemble de la méthode, mais pas aujourd'hui :).

Voir également:


Réponse populaire

En utilisant une partie du code de Jack Eker ci-dessus et du code de Mark Gravell ( voir l'article ici ), j'ai réussi à trouver une solution. Cet extrait de code est utilisé pour obtenir les jours fériés de l'année 2012 en Afrique du Sud au moment de la rédaction de cet article.

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;

            }
        }

    }
}


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow