使用htmlagilitypack解析抓取到的html如何解决table嵌套导致重复的问题

hk207 2017-06-02 04:59:01
例如抓取到的html如下:

<table>
<tr>
<td>姓名</td>
<td>学号</td>
<td>学分</td>
</tr>
<tr>
<td>张三</td>
<td>
<table>
<tr>
<td>201505047</td>
</tr>
</table>
</td>
<td>52</td>
</tr>
<tr>
<td>李四</td>
<td>
<table>
<tr>
<td>201502072</td>
</tr>
</table>
</td>
<td>65</td>
</tr>
</table>


通过for循环tr获取行记录,再for循环td获取列记录,但是因为里面有嵌套,因此获取到的记录就重复了(学号重复了),请教大神,如何避免这个问题?
...全文
483 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
闭包客 2017-06-19
  • 打赏
  • 举报
回复
原来的回答并没有处理重复的学号,更正一下: http://blog.csdn.net/closurer/article/details/73466718
hk207 2017-06-09
  • 打赏
  • 举报
回复
引用 9 楼 closurer 的回复:
我给你一个开源模块解决这个问题,你有兴趣吗?
有兴趣啊,有吗?
闭包客 2017-06-09
  • 打赏
  • 举报
回复
我给你一个开源模块解决这个问题,你有兴趣吗?
hk207 2017-06-09
  • 打赏
  • 举报
回复
大神都跑哪去了啊?
闭包客 2017-06-09
  • 打赏
  • 举报
回复
引用 10 楼 hk207 的回复:
[quote=引用 9 楼 closurer 的回复:] 我给你一个开源模块解决这个问题,你有兴趣吗?
有兴趣啊,有吗?[/quote] https://code.csdn.net/closurer/less-html/tree/master 代码在这里。
闭包客 2017-06-09
  • 打赏
  • 举报
回复




using Less.Html;
using System;

namespace Test
{
class Program
{
static void Main(string[] args)
{
string testHtml =
@"<table>
<tr>
<td>姓名</td>
<td>学号</td>
<td>学分</td>
</tr>
<tr>
<td>张三</td>
<td>
<table>
<tr>
<td>201505047</td>
</tr>
</table>
</td>
<td>52</td>
</tr>
<tr>
<td>李四</td>
<td>
<table>
<tr>
<td>201502072</td>
</tr>
</table>
</td>
<td>65</td>
</tr>
</table>";

var q = HtmlParser.Query(testHtml);

for (int i = 0; i < q("td").length; i++)
Console.WriteLine(q("td")[i].textContent);

Console.ReadLine();
}
}
}




测试通过了。
hk207 2017-06-02
  • 打赏
  • 举报
回复
以上运行的结果如下:

{
  "1": {
    "1": "姓名",
    "2": "学号",
    "3": "学分"
  },
  "2": {
    "1": "张三",
    "2": "201505047",
    "3": "52"
  },
  "3": {
    "1": "201505047"
  },
  "4": {
    "1": "李四",
    "2": "201502072",
    "3": "65"
  },
  "5": {
    "1": "201502072"
  },
  "6": {
    "1": "201505047"
  },
  "7": {
    "1": "201502072"
  }
}
而我想要的结果如下:

{
  "1": {
    "1": "姓名",
    "2": "学号",
    "3": "学分"
  },
  "2": {
    "1": "张三",
    "2": "201505047",
    "3": "52"
  },
  "3": {
    "1": "李四",
    "2": "201502072",
    "3": "65"
  }
}
这个该如何处理??
hk207 2017-06-02
  • 打赏
  • 举报
回复
因为获取到的html不确定(不一定是table,只是用table举个例子),因此不能穷举吧?我想到的只能循环。 但是这样循环的话,像这种嵌套的table,我只要一个InnerText就可以了(比如学号值201505047,我只想要一个),嵌套重复的数据如何去掉或者避免呢?
  • 打赏
  • 举报
回复
另外,尽量使用简洁的选择器表示法——用一个表达式就找到 <table><tr><td><table><tr><td> 这里边的 InnerText。用一个表达式直接找到! 实在不行才这样写一层层的 for 循环代码,这需要写4、5层 for 循环,这种少一些“高度”的查询代码自然麻烦。
  • 打赏
  • 举报
回复
引用 2 楼 hk207 的回复:
主要代码如下:

//行结果集
                IEnumerable<HtmlNode> getCont = htmls.CssSelect("tr");
                
                var i = 1;
                //取行结果集的列数据
                foreach (var htmlNode in getCont)
                {
                    JObject jobj = new JObject();
                    //取列数据 
                    IEnumerable<HtmlNode> getContList = htmlNode.CssSelect("td");                  
                    var j = 1;
                    foreach (var htmlNodes in getContList)
                    {
                        jobj.Add(j.ToString(), htmlNodes.InnerText.Trim());
                        j++;
                    }
                    i_obj.Add(i.ToString(), jobj);
                    i++;
                }
其中htmls即为取到的html,如上面举例的table.
td 里边查找 table 啊!你到了 td 就停止深入3层(table、tr、td)挖掘数据结构了?这就跟 html 模型脱节了。
  • 打赏
  • 举报
回复
你也说“for循环td获取列记录”,那么你获取的 td 结果,对其里边内容是怎么处理的?难道你不认为 td 里边包含一个 table ?
hk207 2017-06-02
  • 打赏
  • 举报
回复
主要代码如下:

//行结果集
                IEnumerable<HtmlNode> getCont = htmls.CssSelect("tr");
                
                var i = 1;
                //取行结果集的列数据
                foreach (var htmlNode in getCont)
                {
                    JObject jobj = new JObject();
                    //取列数据 
                    IEnumerable<HtmlNode> getContList = htmlNode.CssSelect("td");                  
                    var j = 1;
                    foreach (var htmlNodes in getContList)
                    {
                        jobj.Add(j.ToString(), htmlNodes.InnerText.Trim());
                        j++;
                    }
                    i_obj.Add(i.ToString(), jobj);
                    i++;
                }
其中htmls即为取到的html,如上面举例的table.
  • 打赏
  • 举报
回复
什么重复了?怎么就重复了?<td>中有<table>哪里有什么错误? 贴你的实际的代码吧。htmlagilitypack根本不骗人,不会不认识 table 的。

62,041

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧