如何使用 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_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 格式错误且没有关闭 </strong>
标签,存在两个尾随结束标签。
关于ruby - Nokogiri 抓取带有格式和链接标签的文本,<em>、<strong>、<a> 等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14224594/