ruby - Nokogiri 抓取带有格式和链接标签的文本,<em>、<strong>、<a> 等

标签 ruby recursion nokogiri

如何使用 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(),因为它会删除格式标记,而且我不知道如何递归地执行它。

添加细节:Sanitize 看起来像是一个有趣的 gem ,我现在正在阅读它。但是,添加一些可能会澄清我需要做什么的信息。

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

文本。“这是一个子节点。用粗体标签“修改它”这是修改后的子节点。带有 粗体 标签。”并将其放回去。转到下一个 div#2 并抓取文本,“链接的另一行文本”,修改它,“链接的另一行修改文本”,然后将其放回去并转到下一个节点 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>

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

#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

最佳答案

我会使用两种策略,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

将捕获 <div id="1"> 的内容作为 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>

尾随</strong></strong>是两次打开的结果<strong>标签。这可能是故意的,但由于没有结束标签,Nokogiri 会进行一些修复以使 HTML 正确。

通过html_fragmentSanitize 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 格式错误且没有关闭 </strong>标签,存在两个尾随结束标签。

关于ruby - Nokogiri 抓取带有格式和链接标签的文本,<em>、<strong>、<a> 等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14224594/

相关文章:

ruby-on-rails - 用于俄罗斯符号的 Rails gsub

ruby - 是否可以使用 %w[] 速记在数组中创建一个 nil 值?

Ruby Mechanize 单击不起作用

php - 返回随机数但不是 2

python - Python 中树的中序遍历返回列表

ruby-on-rails - Nokogiri 使用 Ruby On Rails 进行抓取未按预期工作

c - 为什么我从 ruby​​ 数组提取到 c 扩展的值是错误的?

java - 数独求解器的算法复杂度 (Big-O)

ruby - 使用 Nokogiri 的例子有哪些?

ruby - 使用 XPath 获取属性的 XML 属性值