Ottenere dati dalla tabella HTML in un datatable

c# html html-agility-pack linq xpath

Domanda

Ok, quindi ho bisogno di interrogare un sito web in tempo reale per ottenere dati da una tabella, inserire questa tabella HTML in un DataTable e quindi utilizzare questi dati. Finora sono riuscito a utilizzare Html Agility Pack e XPath per ottenere ogni riga del tavolo di cui ho bisogno, ma so che ci deve essere un modo per analizzarlo in un DataTable. (C #) Il codice che sto usando attualmente è:

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 tabella HTML sul sito Web che sto interrogando assomiglia a questo:

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

Non sono sicuro che sia meglio / più facile usare LINQ + HAP o XPath + HAP per ottenere il risultato desiderato, ho provato entrambi con un successo limitato come probabilmente puoi vedere. Questa è la prima volta che faccio un programma per interrogare un sito Web o addirittura interagire con un sito Web in qualsiasi modo, quindi sono molto sicuro al momento! Grazie per qualsiasi aiuto in anticipo :)

Risposta accettata

Non esiste un tale metodo pronto per l'HTML Agility Pack, ma non dovrebbe essere troppo difficile crearne uno. Ci sono esempi che forniscono XML a Datatable da Linq a XML. Questi possono essere rielaborati in ciò che ti serve.

Se necessario posso dare una mano a creare l'intero metodo, ma non oggi :).

Guarda anche:


Risposta popolare

Usando un po 'del codice di Jack Eker sopra e del codice di Mark Gravell ( vedi post qui ), sono riuscito a venire con una soluzione. Questo frammento di codice viene utilizzato per ottenere le festività per l'anno 2012 in Sud Africa al momento della stesura di questo articolo

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(" ", " ");
                            }
                            else
                            {

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

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

                        }


                    }

                }


                dataGridView1.DataSource = dt;

            }
        }

    }
}



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché