问题是 HTML 无效。我用它来测试它:
require 'nokogiri'
doc = Nokogiri::HTML::DocumentFragment.parse(<<EOT)
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
<html>
<p>
qwerty
</p>
</html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
EOT
puts doc.errors
解析文档后,Nokogiri 将errors
使用它在解析过程中发现的错误列表填充数组。对于您的 HTML,doc.errors
包含:
htmlParseStartTag: misplaced <html> tag
原因是,在<code>
块内,标签没有按照应有的方式进行 HTML 编码。
使用 HTML 实体将其转换为:
<html>
<p>
qwerty
</p>
</html>
它会起作用。
Nokogiri 是一个 XML/HTML 解析器,它尝试修复标记中的错误,让程序员有机会使用文档。在这种情况下,因为<html>
块在错误的位置,它会删除标签。Nokogiri 不会关心标签是否被编码,因为在那时,它们只是文本,而不是标签。
编辑:
我将尝试使用 gsub 进行预解析并在代码块中转换 html
require 'nokogiri'
html = <<EOT
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
<html>
<p>
qwerty
</p>
</html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
EOT
doc = Nokogiri::HTML::DocumentFragment.parse(html.gsub(%r[<(/?)html>], '<\1html>'))
puts doc.to_html
哪个输出:
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
<html>
<p>
qwerty
</p>
</html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
编辑:
这将<html>
在解析之前处理标签,因此 Nokogiri 可以<code>
毫发无损地加载块。然后它找到<code>
块,对编码的<html>
开始和结束标签进行转义,然后将生成的文本<code>
作为其内容插入到块中。因为它是作为内容插入的,所以当 Nokogiri 将 DOM 呈现为 HTML 时,文本会在必要时重新编码为实体:
require 'cgi'
require 'nokogiri'
html = <<EOT
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
<html>
<p>
qwerty
</p>
</html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
EOT
doc = Nokogiri::HTML::DocumentFragment.parse(html.gsub(%r[<(/?)html>], '<\1html>'))
code = doc.at('code')
code.content = CGI::unescapeHTML(code.inner_html)
puts doc.to_html
哪个输出:
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
<html>
<p>
qwerty
</p>
</html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>