xec*_*ner 2 ruby ruby-on-rails web-crawler nokogiri web-scraping
我有一些HTML页面,其中要提取的内容标有HTML注释,如下所示.
<html>
.....
<!-- begin content -->
<div>some text</div>
<div><p>Some more elements</p></div>
<!-- end content -->
...
</html>
Run Code Online (Sandbox Code Playgroud)
我正在使用Nokogiri并试图在<!-- begin content -->和 <!-- end content -->评论之间提取HTML .
我想提取这两个HTML注释之间的完整元素:
<div>some text</div>
<div><p>Some more elements</p></div>
Run Code Online (Sandbox Code Playgroud)
我可以使用这个字符回调获得纯文本版本:
class TextExtractor < Nokogiri::XML::SAX::Document
def initialize
@interesting = false
@text = ""
@html = ""
end
def comment(string)
case string.strip # strip leading and trailing whitespaces
when /^begin content/ # match starting comment
@interesting = true
when /^end content/
@interesting = false # match closing comment
end
def characters(string)
@text << string if @interesting
end
end
Run Code Online (Sandbox Code Playgroud)
我得到了纯文本版本,@text但我需要存储完整的HTML @html.
在两个节点之间提取内容不是我们常做的事情; 通常我们想要特定节点内的内容.注释是节点,它们只是特殊类型的节点.
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<body>
<!-- begin content -->
<div>some text</div>
<div><p>Some more elements</p></div>
<!-- end content -->
</body>
EOT
Run Code Online (Sandbox Code Playgroud)
通过查找包含指定文本的注释,可以找到起始节点:
start_comment = doc.at("//comment()[contains(.,'begin content')]") # => #<Nokogiri::XML::Comment:0x3fe94994268c " begin content ">
Run Code Online (Sandbox Code Playgroud)
一旦找到,那么需要一个存储当前节点的循环,然后查找下一个兄弟,直到找到另一个注释:
content = Nokogiri::XML::NodeSet.new(doc)
contained_node = start_comment.next_sibling
loop do
break if contained_node.comment?
content << contained_node
contained_node = contained_node.next_sibling
end
content.to_html # => "\n <div>some text</div>\n <div><p>Some more elements</p></div>\n"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1567 次 |
| 最近记录: |