【问题标题】:Nokogiri grab text with formatting and link tags, <em>,<strong>, <a>, etcNokogiri 抓取带有格式和链接标签、<em>、<strong>、<a> 等的文本
【发布时间】:2017-01-02 22:40:17
【问题描述】:

如何使用 Nokogiri 递归捕获所有带有格式化标签的文本?

<div id="1">
  This is text in the TD with <strong> strong </strong> tags
  <p>This is a child node. with <b> bold </b> tags</p>
  <div id=2>
      "another line of text to a <a href="link.html"> link </a>"
      <p> This is text inside a div <em>inside<em> another div inside a paragraph tag</p>
  </div>
</div>

例如,我想捕获:

"This is text in the TD with <strong> strong </strong> tags" 

"This is a child node. with <b> bold </b> tags"

"another line of text to a <a href="link.html"> link </a>"

"This is text inside a div <em>inside<em> another div inside a paragraph tag"

我不能只使用 .text(),因为它会去除格式化标签,而且我不知道如何递归。

添加细节:消毒看起来像一个有趣的宝石,我现在正在阅读它。但是,请提供一些附加信息,以说明我需要做什么。

我需要遍历每个节点,获取文本,处理并放回去。因此我会从“这是 TD 中带有 strong 标签的文本”中获取文本,将其修改为“这是 TD 中带有 strong 的修改后的文本> 标签。然后从 div 1 转到下一个标签,获取

文本。 “这是一个子节点。带有 粗体 标记” 修改它 “这是一个修改后的子节点。带有 粗体 标记。”并放回去。转到下一个 div#2 并抓取文本,“another line text to a link”,修改它,“another line modified text to a link”,然后放回并转到下一个节点,Div#2 并抓取段落标签中的文本。 “这是在段落标签内的另一个 div 内的 div 内的修改文本”

所以在处理完所有内容后,新的 html 应该是这样的......

<div id="1">
  This is modified text in the TD with <strong> strong </strong> tags
  <p>This is a modified child node. with <b> bold </b> tags</p>
  <div id=2>
      "another line of modified text to a <a href="link.html"> link </a>"
      <p> This is modified text inside a div <em>inside<em> another div inside a paragraph tag</p>
  </div>
</div>

我的准代码,但我真的被困在两个部分上,只抓取带有格式的文本(清理有助于),但清理抓取所有标签。我需要保留带有格式的文本的格式,包括空格等。但是,不要抓住不相关的标签子项。第二,遍历所有与全文标签直接相关的children。

#Quasi-code
doc = Nokogiri.HTML(html)
kids=doc.at('div#1')
text_kids=kids.descendant_elements
text.kids.each do |i|
   #grab full text(full sentence and paragraphs) with formating tags
   #currently, I have not way to grab just the text with formatting and not the other tags
   modified_text=processing_code(i.full_text_w_formating())
   i.full_text_w_formating=modified_text
end

def processing_code(string)
#code to process string (not relevant for this example)
  return modified_string
end


# Recursive 1
class Nokogiri::XML::Node
  def descendant_elements
  #This is flawed because it grabs every child and even 
  #splits it based on any tag.
  # I need to traverse down only the text related children.
  element_children.map{ |kid|
     [kid, kid.descendant_elements]
  }.flatten
  end
 end

【问题讨论】:

  • 在尝试解决问题时包含您编写的代码很重要。这有助于我们通过将您的代码修复/包含到我们的答案中来帮助您,从而更容易对其进行改造。
  • 感谢您的意见。我更新了上面,对不起,我的代码没有更好,我真的迷失在上面提到的两个最重要的问题上。
  • 您需要花时间格式化问题以使其易于阅读,并将其简化为基础,因为人们不会花时间阅读长问题。查看编辑问题时可用的文本框标题和stackoverflow.com/editing-help
  • 更新节点很容易。我会在我的答案中添加一些内容。
  • 另外,您真的希望&lt;strong&gt; strong &lt;strong&gt; tags 出现在您想要的输出中吗?这是格式错误的 HTML。

标签: ruby recursion nokogiri


【解决方案1】:

我会使用两种策略,Nokogiri 提取您想要的内容,然后使用黑名单/白名单程序去除您不想要的标签或保留您想要的标签。

require 'nokogiri'
require 'sanitize'

html = '
<div id="1">
  This is text in the TD with <strong> strong <strong> tags
  <p>This is a child node. with <b> bold </b> tags</p>
  <div id=2>
      "another line of text to a <a href="link.html"> link </a>"
      <p> This is text inside a div <em>inside<em> another div inside a paragraph tag</p>
  </div>
</div>
'

doc = Nokogiri.HTML(html)
html_fragment = doc.at('div#1').to_html

&lt;div id="1"&gt; 的内容捕获为 HTML 字符串:

      This is text in the TD with <strong> strong <strong> tags
      <p>This is a child node. with <b> bold </b> tags</p>
      <div id="2">
          "another line of text to a <a href="link.html"> link </a>"
          <p> This is text inside a div <em>inside<em> another div inside a paragraph tag</em></em></p>
      </div>
    </strong></strong>

结尾的&lt;/strong&gt;&lt;/strong&gt; 是两个打开的&lt;strong&gt; 标记的结果。这可能是故意的,但没有结束标签 Nokogiri 会做一些修复以使 HTML 正确。

html_fragment 传递给Sanitize gem:

doc = Sanitize.clean(
  html_fragment,
  :elements   => %w[ a b em strong ],
  :attributes => {
    'a'    => %w[ href ],
  },
)

返回的文本如下:

 This is text in the TD with <strong> strong <strong> tags
  This is a child node. with <b> bold </b> tags 

      "another line of text to a <a href="link.html"> link </a>"
        This is text inside a div <em>inside<em> another div inside a paragraph tag</em></em> 

</strong></strong>

同样,由于 HTML 格式错误,没有结束 &lt;/strong&gt; 标记,因此存在两个尾随结束标记。

【讨论】:

  • 我接近使用正则表达式来尝试解决这个 html 解析问题。请不要让我做出如此绝望的举动!
猜你喜欢
  • 1970-01-01
  • 2010-12-28
  • 2016-02-01
  • 1970-01-01
  • 2015-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-01
相关资源
最近更新 更多