从 HTML 表中获取数据到数据表中

Posted

技术标签:

【中文标题】从 HTML 表中获取数据到数据表中【英文标题】:Getting data from HTML table into a datatable 【发布时间】:2012-05-17 19:36:46 【问题描述】:

好的,所以我需要查询一个实时网站以从表中获取数据,将此 html 表放入 DataTable 中,然后使用此数据。到目前为止,我已经设法使用 Html Agility Pack 和 XPath 来访问我需要的表中的每一行,但我知道必须有一种方法可以将其解析为 DataTable。 (C#) 我目前使用的代码是:

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 是否更好/更容易获得所需的结果,正如您可能看到的那样,我尝试了这两种方法都取得了有限的成功。这是我第一次编写程序来查询网站甚至以任何方式与网站交互,所以我现在非常不确定!提前感谢您的帮助:)

【问题讨论】:

这有帮助吗? weblogs.asp.net/grantbarrington/archive/2009/10/15/… 【参考方案1】:

使用上面 Jack Eker 的一些代码和 Mark Gravell (see post here) 的一些代码,我设法找到了一个解决方案。 此代码 sn-p 用于获取撰写本文时南非 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;

            
        

    

【讨论】:

【参考方案2】:

HTML 敏捷包中没有开箱即用的这种方法,但创建一个应该不会太难。 samples out there 从 Linq-to-XML 执行 XML 到 Datatable。这些可以重新加工成您需要的东西。

如果需要,我可以帮助创建整个方法,但不是今天 :)。

另见:

HTML Agility pack - parsing tables parsing html with HTMLAGILITYPACK and loading into datatable C#

【讨论】:

感谢您在查看了这些资源和其他一些资源后,我设法想出了一种方法:D 您愿意为他人分享您的解决方案吗? 感谢下方提示添加的解决方案!【参考方案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++;


【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

你可以试试

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

DataTable 是表格的 id,i 是行,j 是单元格。

【讨论】:

以上是关于从 HTML 表中获取数据到数据表中的主要内容,如果未能解决你的问题,请参考以下文章

当 html 中没有类名时,从 html 表中获取数据

如何从 mongodb 获取数据并使用节点 js 将其显示在表中?

使用 Jquery 使用正则表达式从 HTML 表中获取所有数据

从 2 个表中获取数据到 excel 表中

添加一些 html 元素后,typeahead 不会从表中获取数据

我应该如何使用 html 代码从谷歌表中获取数据