2012-05-09 2 views
5

Итак, мне нужно запросить веб-сайт в реальном времени, чтобы получить данные из таблицы, поместите эту таблицу HTML в DataTable и затем используйте эти данные. До сих пор мне удалось использовать Html Agility Pack и XPath для доступа к каждой строке в таблице, в которой я нуждаюсь, но я знаю, что должен быть способ проанализировать ее в DataTable. (C#) Код Сейчас я использую это:Получение данных из таблицы HTML в datatable

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

HTML-таблицы на сайте я запрашивающие выглядит следующим образом:

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

Я не уверен, будет ли лучше/легче используйте LINQ + HAP или XPath + HAP, чтобы получить желаемый результат, я пробовал работать с ограниченным успехом, как вы, вероятно, видите. Это первый раз, когда я когда-либо делал программу для запроса веб-сайта или даже взаимодействовал с веб-сайтом каким-либо образом, поэтому я очень не уверен в данный момент! Спасибо за любую помощь заранее :)

+0

это помогает? http://weblogs.asp.net/grantbarrington/archive/2009/10/15/screen-scraping-in-c.aspx – iwayneo

ответ

4

Этот метод не существует из пакета HTML Agility Pack, но его не должно быть слишком сложно создать. Есть samples out there, которые делают XML для Datatable из Linq-to-XML. Они могут быть переработаны в то, что вам нужно.

При необходимости я могу помочь создать весь метод, но не сегодня :).

Смотрите также:

+0

Спасибо, посмотрев эти ресурсы и пару других, мне удалось подняться с возможностью сделать это: D –

+0

Вы согласны поделиться своим решением ради других? – jessehouwing

+0

Спасибо за подсказку, добавленное ниже! –

3

Это мое решение. Может быть немного грязный, но он отлично работает в данный момент: 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

Используя некоторые из кода Джека Экер в выше и некоторый код от Марка Gravell (see post here), мне удалось прийти к решению. Этот фрагмент кода используется для получения государственных праздников на 2012 год в Южной Африке написания этой статьи

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

Простая логика для преобразования HTMLTable в DataTable:

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

Вы можете попробовать

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

Где DataTable является идентификатором вашей таблицы, i - это строка, а j - ячейки.

Смежные вопросы