在C#中解析HTML表格

16

我有一个包含表格的HTML页面,我想在C# Windows窗体中解析该表格。

http://www.mufap.com.pk/payout-report.php?tab=01

这是我想要解析的网页,我已经尝试过了。

> Foreach(Htmlnode a in document.getelementbyname("tr"))
{
    richtextbox1.text=a.innertext;
}

我尝试了类似于这样的东西,但是它不会以表格形式呈现给我,因为我只是简单地打印所有的 tr,所以请帮助我解决这个问题,谢谢。 对我的英语表示抱歉。

3个回答

60

使用 Html Agility Pack

WebClient webClient = new WebClient();
string page = webClient.DownloadString("http://www.mufap.com.pk/payout-report.php?tab=01");

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(page);

List<List<string>> table = doc.DocumentNode.SelectSingleNode("//table[@class='mydata']")
            .Descendants("tr")
            .Skip(1)
            .Where(tr=>tr.Elements("td").Count()>1)
            .Select(tr => tr.Elements("td").Select(td => td.InnerText.Trim()).ToList())
            .ToList();

3
谢谢L.B.。在删除[@class='mydata']后,它可以作为通用代码运行......完美.... - Dinand
如果表格进行了分页,那么如何通过抓取来进入下一页? - Dark_Knight
@Dark_Knight,你看到URL中的?tab=01了吗? - L.B
我只是使用这个字符串“Test Street\tTest Loc\tTest town\ttest\ttest\ttest\ttest\ttest\ttest\ttest\ttest\ttest”(因为只有一行)作为一个字符串,难道不应该在嵌套列表中吗? - ravenx30
1
对我有用。您可以使用“//table[2]”来获取<table>的第二个节点。 - Alex W.
对于Selenium爬虫,只需添加WebDriver.PageSource而不是变量page。 - ojonasplima

17

你是指像这样吗?

foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table")) {
    ///This is the table.    
    foreach (HtmlNode row in table.SelectNodes("tr")) {
    ///This is the row.
        foreach (HtmlNode cell in row.SelectNodes("th|td")) {
            ///This the cell.
        }
    }
}

是的,我想在网页中将列表视图控件中的每个单元格格式化为HTML表格进行显示。 - user1764351

3
稍有些晚了,但使用纯正的C#代码实现你所要求的功能,可以按照以下方式实现。
/// <summary>
/// parses a table and returns a list containing all the data with columns separated by tabs
/// e.g.: records = getTable(doc, 0);
/// </summary>
/// <param name="doc">HtmlDocument to work with</param>
/// <param name="number">table index (base 0)</param>
/// <returns>list containing the table data</returns>
public List<string> getTableData(HtmlDocument doc, int number)
{
  HtmlElementCollection tables = doc.GetElementsByTagName("table");
  int idx=0;
  List<string> data = new List<string>();

  foreach (HtmlElement tbl in tables)
  {
    if (idx++ == number)
    {
      data = getTableData(tbl);
      break;
    }
  }
  return data;
}

/// <summary>
/// parses a table and returns a list containing all the data with columns separated by tabs
/// e.g.: records = getTable(getElement(doc, "table", "id", "table1"));
/// </summary>
/// <param name="tbl">HtmlElement table to work with</param>
/// <returns>list containing the table data</returns>
public List<string> getTableData(HtmlElement tbl)
{
  int nrec = 0;
  List<string> data = new List<string>();
  string rowBuff;

  HtmlElementCollection rows = tbl.GetElementsByTagName("tr");
  HtmlElementCollection cols;
  foreach (HtmlElement tr in rows)
  {
    cols = tr.GetElementsByTagName("td");
    nrec++;
    rowBuff = nrec.ToString();
    foreach (HtmlElement td in cols)
    {
      rowBuff += "\t" + WebUtility.HtmlDecode(td.InnerText);
    }
    data.Add(rowBuff);
  }

  return data;
}

以上内容将使您能够从表格中提取数据,可以通过在页面内使用表格的“索引”(对于未命名的表格很有用),也可以通过将“table” HtmlElement传递给函数来完成(更快,但仅对命名表格有用);请注意,我选择返回“List”作为结果,并使用制表符分隔各列数据;您可以轻松更改代码以以任何其他格式返回数据


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接