2012-05-09 14 views
5

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

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

miradas La tabla HTML en la página web que estoy consultando como este:

<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 use 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 interactúo con un sitio web de alguna manera, así que estoy muy inseguro en este momento. Gracias por cualquier ayuda de antemano :)

+0

hace esto ayuda? http://weblogs.asp.net/grantbarrington/archive/2009/10/15/screen-scraping-in-c.aspx – iwayneo

Respuesta

4

No existe tal método de la caja del HTML Agility Pack, pero no debería ser demasiado difícil crear uno. Hay samples out there que hacen XML a Datatable desde Linq a XML. Estos pueden volver a trabajar en lo que necesita.

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

Consulte también:

+0

Gracias después de echar un vistazo a estos recursos y un par de otros que he logrado llegar con una forma de hacerlo: D –

+0

¿Estaría dispuesto a compartir su solución por el bien de los demás? – jessehouwing

+0

¡Gracias por la solución agregada de consejos a continuación! –

3

Ésta es mi solución. Puede ser un poco desordenado pero está funcionando perfectamente en el momento: D

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

doc.LoadHtml(htmlCode); 

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

int count = 0; 
decimal rowValue = 0; 
bool isDecimal = false; 
foreach (var row in doc.DocumentNode.SelectNodes("//table[@summary='Table Name']/tbody/tr")) 
{ 
DataRow dr = dt.NewRow(); 
foreach (var cell in row.SelectNodes("td")) 
{ 
if ((count % 2 == 0)) 
{ 
dr["Name"] = cell.InnerText.Replace("&nbsp;", " "); 
} 
else 
{ 
isDecimal = decimal.TryParse((cell.InnerText.Replace(".", "")).Replace(",", "."), out rowValue); 
if (isDecimal) 
{ 
dr["Value"] = rowValue; 
} 
dt.Rows.Add(dr); 
} 
count++; 
} 
} 
8

El uso de algunos de código de Jack Eker arriba y algo de código de Mark Gravell (see post here), me las arreglé para llegar a una solución. Este fragmento de código se utiliza para obtener los días festivos para el año de 2012 en Sudáfrica como de escribir 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; 

      } 
     } 

    } 
} 
1

lógica simple para convertir un HTMLTable a tabla de datos:

//Define your webtable 
public static HtmlTable table 
      { 
       get 
       { 
        HtmlTable var = new HtmlTable(parent); 
        var.SearchProperties.Add("id", "searchId"); 
        return var; 
       } 
      } 

//Convert a webtable to datatable 
public static DataTable getTable 
      { 
       get 
       { 
        DataTable dtTable= new DataTable("TableName"); 
        UITestControlCollection rows = table.Rows; 
        UITestControlCollection headers = rows[0].GetChildren(); 
        foreach (HtmlHeaderCell header in headers) 
        { 
         if (header.InnerText != null) 
          dtTable.Columns.Add(header.InnerText); 
        } 
        for (int i = 1; i < rows.Count; i++) 
        { 
         UITestControlCollection cells = rows[i].GetChildren(); 
         string[] data = new string[cells.Count]; 
         int counter = 0; 
         foreach (HtmlCell cell in cells) 
         { 
          if (cell.InnerText != null) 
           data[counter] = cell.InnerText; 
          counter++; 
         } 
         dtTable.Rows.Add(data); 
        } 
        return dtTable; 
       } 
      } 
0

Usted puede tratar

DataTable.Rows[i].Cells[j].InnerText; 

Donde DataTable es la identificación de su tabla, soy la fila y j son las celdas.

Cuestiones relacionadas