Nokogiri 正在修复格式错误的 HTML 以使其可解析。完成后,DOM 处于合理状态,但 Nokogiri 不再提供原始文档。
如果您希望原件不受影响,则必须在将其传递给 Nokogiri 之前使其有效,然后您可以使用 Nokogiri 的方法对其进行操作。通常我会使用一些正则表达式来查找问题点并添加/调整标签或其相关的结束标签,以允许 Nokogiri 解析而无需修复问题。
这不是 HTML 比 XML 更智能的情况,而是 Nokogiri 尊重严格的 XML 规范的精神,并errors
在文件无效时通过使用错误填充数组来引发标志。HTML 的规范不那么严格,而且,因为浏览器在解析和显示 HTML 时(也)很宽容,所以 Nokogiri 会在一定程度上遵循,进行修复,然后填充errors
数组。(无论哪种情况,您都可以检查该数组以查看问题所在。)
require 'nokogiri'
orig_html = '
<html>
<meta name="Generator" content="Microsoft Word 97 O.o">
<body>
1
<b><p>2</p></b>
3
</body>
</html>'
doc = Nokogiri::HTML(orig_html)
doc.errors
doc.errors
包含:
[
[0] #<Nokogiri::XML::SyntaxError: Unexpected end tag : b>
]
以下是我使用 Nokogiri 修复示例 HTML 的方法:
doc = Nokogiri::HTML(orig_html)
p = doc.at('b+p')
p.previous_sibling.remove
这是此时的 HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="Generator" content="Microsoft Word 97 O.o">
</head>
<body>
1
<p>2</p>
3
</body>
</html>
继续:
p.inner_html = "<b>#{p.content}</b>"
puts doc.to_html
这是生成的 HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="Generator" content="Microsoft Word 97 O.o">
</head>
<body>
1
<p><b>2</b></p>
3
</body>
</html>
很明显,示例 HTML 并不是您真正使用的内容,因此您必须更改访问器以定位需要更改的标签,但这应该可以帮助您。