用HtmlAgilityPack读出C#中的表

时间:2013-03-23 00:40:05

标签: c# html html-agility-pack

我已经尝试了很长一段时间,但这是我的情况;

我朋友的网络应用程序运行一个非常简单的HTML网站来生成图表数据。我希望从该页面上的表中获取某些值,因为他需要将此信息存储到数据库中。

所以这是HTML表格的一部分;

...
<tr>
    <td width=30 align=center bgcolor=#006699 class=W><font color=white>1</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>7387</td>

    <td width=30 height=25 align=center bgcolor=#006699 class=W><font color=white>2</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>2881</td>

    <td width=30 height=25 align=center bgcolor=#006699 class=W><font color=white>3</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>8782</td>

    <td width=30 height=25 align=center bgcolor=#006699 class=W><font color=white>4</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>5297</td>

    <td width=30 height=25 align=center bgcolor=#006699 class=W><font color=white>5</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>749</td>
</tr>
<tr>
    <td align=center bgcolor=#006699 class=W><font color=white>6</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>3136</td>

    <td height=25 align=center bgcolor=#006699 class=W><font color=white>7</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>8768</td>

    <td height=25 align=center bgcolor=#006699 class=W><font color=white>8</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>9548</td>

    <td height=25 align=center bgcolor=#006699 class=W><font color=white>9</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>6565</td>

    <td height=25 align=center bgcolor=#006699 class=W><font color=white>10</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>142</td>
</tr>
...

我想要实现的是;

  • 我得到两个数字 - 例如1和8。
  • 我的应用程序检查页面的HTML并选择包含数字的两个td(如上所示)。
  • 然后,我必须得到NEXT td的价值。

此输出为1=73878=9548。 在试图找到包含给定数字的两个td之后,我陷入了很快的困境。

到目前为止我的C#代码;

using (WebClient webClient = new WebClient())
{
    string completeHTMLCode = webClient.DownloadString("someUrl.php?getChartData=" + chartId);

    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(completeHTMLCode);

    foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//td[@...]"))
    {

    }
 }

我在这里尝试一些不可能的东西吗?

3 个答案:

答案 0 :(得分:3)

我做了一个快速的CsQuery示例如何实现这一目标。

string file = File.ReadAllText("a.html"); // gets the html

CQ dom = file; // initializes csquery
CQ td = dom["td"]; // get all td files

td.Each((i,e) => { // go through each
    if (e.FirstChild != null) // if element has child (font)
    {
        if (e.FirstChild.NodeType != NodeType.TEXT_NODE) // ignore text node
        {
            if (e.FirstChild.InnerText == "1") // if number is 1
            {
                Console.WriteLine(e.NextElementSibling.InnerText); // output the text
            }
            if (e.FirstChild.InnerText == "8") // etc etc
            {
                Console.WriteLine(e.NextElementSibling.InnerText);
            }
        }
    }

});

Console.ReadKey();

答案 1 :(得分:1)

您可以将其解析为字典并以此方式查找。我可能会想到一些更好的方法来解析它,但这可以做你想要的。

    void Main()
{
    string html = @"<tr>
    <td width=30 align=center bgcolor=#006699 class=W><font color=white>1</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>7387</td>

    <td width=30 height=25 align=center bgcolor=#006699 class=W><font color=white>2</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>2881</td>

    <td width=30 height=25 align=center bgcolor=#006699 class=W><font color=white>3</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>8782</td>

    <td width=30 height=25 align=center bgcolor=#006699 class=W><font color=white>4</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>5297</td>

    <td width=30 height=25 align=center bgcolor=#006699 class=W><font color=white>5</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>749</td>
</tr>
<tr>
    <td align=center bgcolor=#006699 class=W><font color=white>6</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>3136</td>

    <td height=25 align=center bgcolor=#006699 class=W><font color=white>7</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>8768</td>

    <td height=25 align=center bgcolor=#006699 class=W><font color=white>8</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>9548</td>

    <td height=25 align=center bgcolor=#006699 class=W><font color=white>9</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>6565</td>

    <td height=25 align=center bgcolor=#006699 class=W><font color=white>10</font></td>
    <td width=50 bgcolor=#FFFFFF align=center>142</td>
</tr>";

    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(html);

    int[] nodes = doc.DocumentNode.SelectNodes("//td").Select ( dn =>
        int.Parse(dn.InnerHtml.Contains("font") ? dn.FirstChild.InnerHtml : dn.InnerHtml)
        ).ToArray();

    Dictionary<int,int> d = new Dictionary<int,int>();
    for (int i = 0; i < nodes.Length; i+=2)
        d.Add(nodes[i],nodes[i+1]);

    d.Dump();
    d[1].Dump();
    d[8].Dump();
}

答案 2 :(得分:0)

好吧,如果您只使用此表数据,则可以使用HTMLAgilityPack解析它。

我要做的第一件事是废除foreach迭代tds,我使用一个计数器,然后使用计数器id作为索引器。代码看起来像这样

for(int i = 1;i <= selectednodes.Count();i++)
{
  if(selectednodes[i-1].InnerHtml.Contains("font")
  {
   if(selectednodes[i-1].FirstChild.Value == "1" || selectednodes[i-1].FirstChild.Value == "8")
   {
      myNodecollection.Add(selectednodes[i])
   }
  }
}