C# 如何使用HtmlAgilityPack将注释之间的表刮到网格视图中?

C# 如何使用HtmlAgilityPack将注释之间的表刮到网格视图中?,c#,gridview,web-scraping,datatable,html-agility-pack,C#,Gridview,Web Scraping,Datatable,Html Agility Pack,当前正在尝试使用HtmlAlityPack将表从中刮取到gridview中。我相信我的代码成功地从注释之间提取了表,但是当它构建数据表时,它说它找不到第8列,这显然不应该存在于这个上下文中。我对这有点陌生,如果能解释一下我做错了什么,我会非常感激 private void GetTeamStats() { var webGet = new HtmlWeb(); var getPage = webGet.Load("https://www.teamrankings.com/nba/

当前正在尝试使用HtmlAlityPack将表从中刮取到gridview中。我相信我的代码成功地从注释之间提取了表,但是当它构建数据表时,它说它找不到第8列,这显然不应该存在于这个上下文中。我对这有点陌生,如果能解释一下我做错了什么,我会非常感激

private void GetTeamStats()
{
    var webGet = new HtmlWeb();
    var getPage = webGet.Load("https://www.teamrankings.com/nba/stat/effective-field-goal-pct");
    var commentNode = getPage.DocumentNode.SelectNodes("//comment()[contains(.,'table-filters')]/following::*[not(preceding::comment()[contains(.,'main-wrapper')])]");
    var commentHtml = commentNode.Select(c1 => c1.SelectSingleNode("//table"));

    DataTable dt = new DataTable();
    dt.Columns.Add("Rk", typeof(string));
    dt.Columns.Add("Team", typeof(string));
    dt.Columns.Add("2018", typeof(string));
    dt.Columns.Add("Last3", typeof(string));
    dt.Columns.Add("Last1", typeof(string));
    dt.Columns.Add("Home", typeof(string));
    dt.Columns.Add("Away", typeof(string));
    dt.Columns.Add("2017", typeof(string));

    foreach (var table in commentHtml)
    {
        foreach (var row in table.SelectNodes("//tr"))
        {
            var dr = dt.NewRow();
            dt.Rows.Add(dr);

            int i = 0;
            foreach (var cell in row.SelectNodes("//td"))
            {
                dr[i++] = cell.InnerText;
            }
        }

        gvTeamStats.DataSource = dt;
    }
}
异常显示为“System.IndexOutOfRangeException:'找不到第8列'”,并由这行代码引发

                    dr[i++] = cell.InnerText;
我做了一些改变:

页面源视图中的表结构为:

<table>
<thead>
 <tr>
    <th>Rank</th>
    <th>Team</th>
    <th>2018</th>
    <th>Last 3</th>
    <th>Last 1</th>
    <th>Home</th>
    <th>Away</th>
    <th>2017</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
</tr>
</table>

var webGet = new HtmlWeb();
var getPage = webGet.Load("https://www.teamrankings.com/nba/stat/effective-field-goal-pct");
var tableHeader = getPage.DocumentNode.SelectNodes("//table/thead/tr");
var tableData = getPage.DocumentNode.SelectNodes("//table/tbody/tr");

DataTable dataTable = new DataTable();

var headers = tableHeader
            .Elements("th")
            .Select(th => th.InnerText.Trim());

foreach (var header in headers)
{
    dataTable.Columns.Add(header);
}

var rows = tableData.Select(tr => tr
            .Elements("td")
            .Select(td => td.InnerText.Trim())
            .ToArray());

foreach (var row in rows)
{
    dataTable.Rows.Add(row);
}

// print our datatable
foreach (DataRow dataRow in dataTable.Rows)
{
     foreach (var item in dataRow.ItemArray)
     {
         Console.Write(item + " ");
     }
     Console.WriteLine();
 }

等级
团队
2018
最后3
最后1
家
远离
2017
var webGet=new HtmlWeb();
var getPage=webGet.Load(“https://www.teamrankings.com/nba/stat/effective-field-goal-pct");
var tableHeader=getPage.DocumentNode.SelectNodes(“//table/thead/tr”);
var tableData=getPage.DocumentNode.SelectNodes(“//table/tbody/tr”);
DataTable=新的DataTable();
var headers=tableHeader
.要素(“th”)
.Select(th=>th.InnerText.Trim());
foreach(标头中的var标头)
{
dataTable.Columns.Add(表头);
}
var rows=tableData.Select(tr=>tr
.要素(“td”)
.Select(td=>td.InnerText.Trim())
.ToArray());
foreach(行中的变量行)
{
dataTable.Rows.Add(行);
}
//打印我们的数据表
foreach(dataTable.Rows中的DataRow-DataRow)
{
foreach(dataRow.ItemArray中的变量项)
{
控制台。写入(项+“”);
}
Console.WriteLine();
}

如果您描述哪一行引发异常,并将实际的异常消息粘贴到此处,这会很有帮助。我看到创建了8列。数据表中的第一列将被读取为第0列,因此应该没有第8列,只有0-7列。我编辑了我的问题以包含异常并指定引发异常的行;正在尝试将第二行“2”添加到同一dr。您没有将该行添加到datatable并创建新的dr。现在,我得到异常“System.ArgumentException:'此行已属于此表”。“在else语句中的”datatable.Rows.add(dr)”行。当我将数据源分配到循环外部时,该异常会起作用,但它似乎切断了下一行的第一列数据。因此,第2行不是从排名开始,而是从团队名称开始,第3行从第一个fg%开始,等等。此外,我真的很感谢您的帮助,我一直坚持这一点。而且这似乎是在无限地构建表,因此30后,新的一行将从第1行开始,这就解释了为什么调试要花这么长时间。添加了一个if语句,当datatable有30行时会中断循环,所以我修复了这个问题,但仍然存在跳过代码的每8个数据节点的问题。将很快发布一个优雅的解决方案