【问题标题】:How to get text that has no tag with htmlAgilityPack如何使用 htmlAgilityPack 获取没有标签的文本
【发布时间】:2013-05-10 05:13:59
【问题描述】:

我有一个如下所示的 html 文件

  <div>

  <div style="margin-left:0.5em;">
  <div class="tiny" style="margin-bottom:0.5em;">
  <b><span class="h3color tiny">This review is from: </span>You Meet</b>
  </div>
  If you know Ron Kaufman as I do ...
  <br /><br />Whether you're the CEO....
  <br /><br />Written in a distinctive, ...
  <br /><br />My advice? Don't just get one copy
  <div style="padding-top: 10px; clear: both; width: 100%;"></div>
  </div>

  <div style="margin-left:0.5em;">
  <div class="tiny" style="margin-bottom:0.5em;">
  <b><span class="h3color tiny">This review is from: </span>My Review</b>
  </div>
  I became a fan of Ron Kaufman after reading an earlier book of his years ago...
  <div style="padding-top: 10px; clear: both; width: 100%;"></div>
  </div>

  </div>

我想获得没有任何 html 标记的评论文本。 我现在使用下面的代码

  foreach (HtmlNode divReview in doc.DocumentNode.SelectNodes(@"//div[@style='margin-left:0.5em;']"))   
   {
      if (divReview != null)
          {

 review.Add(divReview.Descendants("div").Where(d => d.Attributes.Contains("style") && 
 d.Attributes["style"].Value.Contains("padding-top: 10px; clear: both; width: 100%;")).
                                          Select(d =>
 d.PreviousSibling.InnerText.Trim()).SingleOrDefault());  
          }
       }

只返回“我的建议?不要只得到一份”,我怎样才能得到整个文本?

更新:即使我删除所有

"br"

来自 htmlnode 的标签,仍然在使用上述代码时,我只得到“我的建议?不要只得到一份”部分!!!有什么意见吗?

【问题讨论】:

  • 我不能使用 TakeWhile 或类似的东西来获取所有文本吗??
  • 定义一个“没有任何html标签的文本”?
  • 我的示例中的文本“如果你像我一样认识 Ron Kaufman...”只属于 htmlpage 顶部的一个 div,所以在我的 htmlnode 中它实际上没有任何标签
  • 这不是 HTML 术语中的定义。所有文本节点都是父节点的子节点。
  • 是的,这很奇怪,但无论如何我都需要这样做。

标签: c# html xpath html-agility-pack


【解决方案1】:

我已将代码更新为:

var allText = (reviewDiv.Descendants("div")
  .First(div => div.Attributes["style"].Value == "padding-top: 10px; clear: both; width: 100%;")
  .SelectNodes("./preceding-sibling::text()") ?? new HtmlNodeCollection(null)) 
  .Select(text => text.InnerText);

这应该返回一个 IEnumerable 字符串,其中包含具有复杂样式的 div 前面的文本。

如果没有更多周围的 HTML,很难判断这是否正是您所追求的。我目前猜测您选择了一个 div,并且该 div 是整个文本块的直接父级(鉴于您对 reviewDiv 的引用)。您的 HTML 示例似乎不包含这段 HTML,所以我在这里做一些假设。

使用以下输入:

<div><div class="tiny" style="margin-bottom:0.5em;">
<b><span class="h3color tiny">This review is from: </span>You Meet</b>
</div>
If you know Ron Kaufman as I do ...
<br /><br />Whether you're the CEO....
<br /><br />Written in a distinctive, ...
<br /><br />My advice? Don't just get one copy
<div style="padding-top: 10px; clear: both; width: 100%;"></div></div>

它提取了这个:

如果你和我一样认识罗恩考夫曼 ...
无论您是 CEO....
写在一个独特的,...
我的建议?不要只买一份

为了构建我使用的单个字符串:string extractedText = string.Join("", allText);

【讨论】:

  • 是否还包括“此评论来自:”和“您遇见”?
  • 它没有得到没有
    标签的文本......这很重要
  • 你测试了吗?输出正是我正在寻找的,但是当我测试您的代码时,我得到“对象引用未设置为对象的实例”
  • 是的,我测试过了。这可能取决于 reviewDiv 指的是什么,这就是为什么我发表评论需要了解一点周围的 HTML。此外,当没有找到节点时,SelectNodes 返回 null 而不是空集合,因此在每次调用 SelectNodes 之后添加 ?? new HtmlNodeCollection() 也可能会解决您的问题。
  • 我已经将它们分开并且它有效: HtmlNode afterReviewDiv = divReview.SelectSingleNode(@".//div[@style='padding-top: 10px; clear: both; width: 100%; ']"); var reviewNodes = afterReviewDiv.SelectNodes("./preceding-sibling::text()") ??新的 HtmlNodeCollection(null); var txtReviewNodes = reviewNodes.Select(text => text.InnerText.Trim());
猜你喜欢
相关资源
最近更新 更多
热门标签