c# - 使用 HTML AgilityPack 按断线解析 HTML

标签 c# parsing html-agility-pack

我正在尝试解析一个特定的 HTML 字符串,以便我可以提取一组由 <br/> 分隔的行断线。输入的 HTML 如下所示:

<div class="PlainText">
  DATE: 2013-10-28 20:00:43 -0500 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  <br/> //Notice this has two break lines, i would like to stop after seeing two consecutive break lines.
</div>

在较大的 html 文档中使用此 div,我能够获得 HTML ChildNodes

List<HtmlNode> nodes = htmlDoc.DocumentNode
                                    .Descendants("div")
                                    .Where(x => x.Attributes.Contains("class") &&
                                            x.Attributes["class"].Value.Contains("PlainText")).ToList();

我不完全确定从这里到哪里去,我想阅读所有文本,直到看到两条分界线并停下来?

编辑

我查看了子节点 nodes在 Visual Studio 运行时检查器中,注意到实际上没有两个连续的 <br/>行,但有一条断线和一个 #text标记其 innerHTMl 为 \n换行符。

enter image description here

最佳答案

您可以使用 XPath //div[@class='PlainText'] 获取所需的 div 节点。您还可以在从 div 获取子节点时检查下一个兄弟节点:

HtmlDocument doc = new HtmlDocument();
doc.Load("index.html");
Func<HtmlNode, bool> notTwoBrakes = 
    n => (n.Name != "br" || n.NextSibling != null && n.NextSibling.Name != "br");
var nodes = doc.DocumentNode.SelectNodes("//div[@class='PlainText']")
               .Select(div => div.ChildNodes.TakeWhile(notTwoBrakes));

我使用内联 lambda 并不是为了提高可读性。条件是这样的:

  • 检查下一个节点是否为null,如果为null,则取当前节点
  • 检查下一个节点是否是br节点,如果不是-取当前节点
  • 检查当前节点是否为br节点,如果不是-获取当前节点
  • 否则停止取子节点

结果:

enter image description here

关于c# - 使用 HTML AgilityPack 按断线解析 HTML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19710644/

相关文章:

c# - 什么是单声道项目

java - "OutOfMemoryError: GC overhead limit exceeded": parse large json file with java

java - Gson - 检查节点/元素是否存在的正确方法

c# - 如何从 Selenium Driver.PageSource 获取 HtmlAgilityPack.HtmlDocument?

c# - 掩盖您的网络抓取事件,使其看起来像正常的浏览器冲浪事件?

c# - 空间域卷积代码的性能

c# - 基于两个属性从列表中选择不同值的最快方法

html - XPATH 如何使用 HTML 敏捷包从 HTML 中的 tbody 一次提取一个 td

c# - @Html.DisplayFor() 不适用于自定义模型子类

php - 如果还没有空格,如何在子字符串周围添加空格?