使用Html Agility Pack

时间:2015-05-11 14:28:12

标签: c# .net html-agility-pack

我一直试图从网站上删除一些数据。源通过不同的类名将所有表的标题区分为实际内容的标题。因为我想要抓取所有表信息,所以我将所有头文件放入一个数组,将内容放入另一个数组中。但问题是,当我尝试将数组内容写入文件时,我可以编写一个标题但第二个数组包含来自所有表的内容,我无法标记第一个表的内容结束的位置。 因为htmlagilitypack会抓取指定节点的所有标签,所以我得到了所有内容。首先让我展示一下代码来说清楚:

<tr class=tableHeader>
<th width=16%>Caught</th>
<th width=16%><p><a href="/url">Normal Range</a></p></th>
</tr>
<TR class=content><TD><a href="/url"><i>Bluegill</i></a></TD>
<TD>trap net</TD>
<TD align=CENTER>4.05</TD>
<TD align=CENTER>    7.9 -    37.7</TD>
<TD align=CENTER>0.26</TD>
<TD align=CENTER>    0.1 -     0.2</TD>
</TR>
<TR class=content><TD><i></i></TD>
<TD>Gill net</TD>
<TD align=CENTER>1.50</TD>
<TD align=CENTER>N/A</TD>
<TD align=CENTER>0.07</TD>
<TD align=CENTER>N/A</TD>
</TR>
<tr class=tableHeader>
<th>0-5</th>
<th>6-8</th>
<th>9-11</th>
<th>12-14</th>
<th>15-19</th>
<th>20-24</th>
<th>25-29</th>
<th>30+</th>
<th>Total</th>
</tr>
<TR class=content><TD><i>bluegill</i></TD>
<TD align=CENTER>19</TD>
<TD align=CENTER>65</TD>
<TD align=CENTER>0</TD>
<TD align=CENTER>0</TD>
<TD align=CENTER>0</TD>
<TD align=CENTER>0</TD>
<TD align=CENTER>0</TD>
<TD align=CENTER>0</TD>
<TD align=CENTER>84</TD>
</TR>

下面是我将代码和内容保存到数组中的代码,并尝试将其显示在网站中。

int count =0;
foreach (var trTag4Pale in trTags4Pale)
{
    string trText4Pale = trTag4Pale.InnerText;
    paleLake[count] = trText4Pale;
    if (trTags4Small != null)
    {
        int counter = 0;
        foreach (var trTag4Small in trTags4Small)
        {
            string trText4Small = trTag4Small.InnerText;
            smallText[counter] = trText4Small;
            counter++;
        }
     }
     File.AppendAllText(path,paleLake[count]+Environment.Newline+smallText[count]+Environment.Newline);
}

如您所见,当我尝试将数组的内容附加到文件时,它会在第一个标题中排成行,并在所有表中显示内容。但我只想要第一个表的内容,并重复该过程以获取第二个表的内容,依此类推。 如果我可以在tr标签tableHeader之间获取内容,则内容的数组将包含不同数组中所有表的每个内容。我不知道该怎么做。

1 个答案:

答案 0 :(得分:0)

这可能不是最好的方法,但我让它以某种方式工作。它有朝一日可能对某人有用。以下是适合我的代码。我将存储在列表中的数据附加到Excel工作表中。因为我拥有每个类的每个tr标签所需的所有数据,所以我可以操作我想要的数据:

var trTags4Header = document.DocumentNode.SelectNodes("//tr[@class='tableheader']");
if (trTags4Header != null)
{
    //Create a list to store td values 
    List<string> tableList1 = new List<string>();
    int row = 2;
    foreach (var item in trTags4Header)
    {
        //Get only next siblings which matches the calss name as "content" 
        var found = item.SelectNodes("followin-sibling::*").TakeWhile(tag => tag.Name == "tr" && tag.Attributes["class"].Value == "content");
        //store the nodes selected in an array (this is the selection of nodes I wanted which has td information I want. 
        HtmlNode[] nextItem = found.ToArray();
        foreach (var node in nextItem)
        {
            //Gets individual td values within tr class='content' Notice .//td- this starts looking from the present node instead of the root nodes.
            var tdValues = node.SelectNodes(".//td").TakeWhile(tdTag => tdTag.Name == "td");
            int column = 1;
            //Stores each td values into the list which is why I have control over the data to where I want to store, I am storing them in one excel worksheet.
            foreach (var tdText in tdValues)
            {
                tableList1.Add(tdText.InnerText);
                ws1.Cells[row, column] = tdText.InnerText;
                column++;
            }
            row++;
         }
     }
     //Display the content in a listbox 
     listBox1.DataSource = tableList1;
}

如果您遇到此问题或留下您的反馈意见,请建议更好的解决方案。感谢