我使用Ruby写了一个网络爬虫,并且正在使用Nokogiri::HTML
解析页面。我需要打印出该页面,当我在IRB中试验时,我发现有一个pretty_print
方法,但是它需要一个参数,而我无法确定它想要什么。
我的爬虫正在缓存网页的HTML,并将其写入本地机器上的文件中。我希望能够"漂亮地打印"这些HTML,以便它们在打印时看起来美观并正确地格式化。
我使用Ruby写了一个网络爬虫,并且正在使用Nokogiri::HTML
解析页面。我需要打印出该页面,当我在IRB中试验时,我发现有一个pretty_print
方法,但是它需要一个参数,而我无法确定它想要什么。
我的爬虫正在缓存网页的HTML,并将其写入本地机器上的文件中。我希望能够"漂亮地打印"这些HTML,以便它们在打印时看起来美观并正确地格式化。
@mislav的回答有点错误。Nokogiri确实支持漂亮的打印,如果:
to_xhtml
或to_xml
来指定漂亮打印参数如下所示:
html = '<section>
<h1>Main Section 1</h1><p>Intro</p>
<section>
<h2>Subhead 1.1</h2><p>Meat</p><p>MOAR MEAT</p>
</section><section>
<h2>Subhead 1.2</h2><p>Meat</p>
</section></section>'
require 'nokogiri'
doc = Nokogiri::XML(html,&:noblanks)
puts doc
#=> <section>
#=> <h1>Main Section 1</h1>
#=> <p>Intro</p>
#=> <section>
#=> <h2>Subhead 1.1</h2>
#=> <p>Meat</p>
#=> <p>MOAR MEAT</p>
#=> </section>
#=> <section>
#=> <h2>Subhead 1.2</h2>
#=> <p>Meat</p>
#=> </section>
#=> </section>
puts doc.to_xhtml( indent:3, indent_text:"." )
#=> <section>
#=> ...<h1>Main Section 1</h1>
#=> ...<p>Intro</p>
#=> ...<section>
#=> ......<h2>Subhead 1.1</h2>
#=> ......<p>Meat</p>
#=> ......<p>MOAR MEAT</p>
#=> ...</section>
#=> ...<section>
#=> ......<h2>Subhead 1.2</h2>
#=> ......<p>Meat</p>
#=> ...</section>
#=> </section>
&:noblanks
的链接或来源? - Arup RakshitNokogiri.XML(…){|config| config.noblanks }
。Nokogiri.XML()
方法在文档中被说明为Nokogiri::XML::Document.parse
的一种快捷方式。传递给该方法的块是传递解析选项的简写形式。 - Phrogz我猜您所说的"漂亮打印"是指您想要使用正确的缩进重新格式化HTML结构。Nokogiri不支持此功能;pretty_print
方法是针对"pp"库的,其输出仅用于调试。
有几个项目能够充分理解HTML,并能够重新格式化它而不破坏实际上具有意义的空格(其中著名的一个是HTML Tidy),但通过谷歌搜索,我找到了这篇题为"Pretty printing XHTML with Nokogiri and XSLT"的帖子。
它归结为以下内容:
xsl = Nokogiri::XSLT(File.open("pretty_print.xsl"))
html = Nokogiri(File.open("source.html"))
puts xsl.apply_to(html).to_s
当然,这需要您将链接的XSL文件下载到您的文件系统中。我在我的机器上非常快速地尝试过它,它效果很棒。
<p><span>pre</span>fix</p>
变成了 "pre fix")。 - Kyle McClellan这对我有用:
pretty_html = Nokogiri::HTML(html).to_xhtml(indent: 3)
我试过上面的REXML版本,但它损坏了我的一些文件。而且我不想在新项目中使用XSLT,两者都感觉过时了。 :)
<body>
和<html>
标签,则会添加它们。在我的情况下,我根本不需要它们。 - kravcrequire "rexml/document"
doc = REXML::Document.new(xml)
doc.write($stdout, 2)
print
方法。在运行下面代码片段之后,您只需编写node.print
,它将漂亮地打印内容。无需xslt :-)Nokogiri::XML::Node.class_eval do
# Print every Node by default (will be overridden by CharacterData)
define_method :should_print? do
true
end
# Duplicate this node, replace the contents of the duplicated node with a
# newline. With this content substitution, the #to_s method conveniently
# returns a string with the opening tag (e.g. `<a href="foo">`) on the first
# line and the closing tag on the second (e.g. `</a>`, provided that the
# current node is not a self-closing tag).
#
# Now, print the open tag preceded by the correct amount of indentation, then
# recursively print this node's children (with extra indentation), and then
# print the close tag (if there is a closing tag)
define_method :print do |indent=0|
duplicate = self.dup
duplicate.content = "\n"
open_tag, close_tag = duplicate.to_s.split("\n")
puts (" " * indent) + open_tag
self.children.select(&:should_print?).each { |child| child.print(indent + 2) }
puts (" " * indent) + close_tag if close_tag
end
end
Nokogiri::XML::CharacterData.class_eval do
# Only print CharacterData if there's non-whitespace content
define_method :should_print? do
content =~ /\S+/
end
# Replace all consecutive whitespace characters by a single space; precede the
# outut by a certain amount of indentation; print this text.
define_method :print do |indent=0|
puts (" " * indent) + to_s.strip.sub(/\s+/, ' ')
end
end
doc = Nokogiri::HTML(html_source); doc.elements.each {|elem| elem.print }
。谢谢。 - ian更简单,而且运行良好
puts Nokogiri::HTML(File.read('terms.fr.html')).to_xhtml
我知道我回答这个问题已经非常晚了,但是我还是会留下答案。我尝试了上面的所有步骤,它确实在某种程度上起作用。
Nokogiri
确实可以格式化 HTML
,但不关心关闭或打开标签,因此漂亮的格式化就无从谈起了。
我发现了一个叫做 htmlbeautifier 的宝石,它的效果非常好。我希望其他仍在寻找答案的人也能从中受益。
你为什么不试试pp
方法呢?
require 'pp'
pp some_var