我正在尝试解析维基词条以检索所有英文定义。我能够检索所有定义,问题是某些定义是在其他语言中。我想做的是以某种方式检索只有英文定义的HTML块。我发现,在有其他语言条目的情况下,英文定义之后的标题可以通过以下方式检索:
header = (doc/"h2")[3]
所以我想只搜索这个header元素之前的所有元素。我认为header.preceding_siblings()
可能有可能,但这似乎不起作用。有什么建议吗?
答案 0 :(得分:2)
您可以使用Nokogiri的访客模式。此代码将从其他语言定义的h2开始删除所有内容:
require 'nokogiri'
require 'open-uri'
class Visitor
def initialize(node)
@node = node
end
def visit(node)
if @remove || @node == node
node.remove
@remove = true
return
end
node.children.each do |child|
child.accept(self)
end
end
end
doc = Nokogiri::XML.parse(open('http://en.wiktionary.org/wiki/pony'))
node = doc.search("h2")[2] #In this case, the Italian h2 is at index 2. Your page may differ
doc.root.accept(Visitor.new(node)) #Removes all page contents starting from node
答案 1 :(得分:1)
以下代码使用 Hpricot 它从英语语言(h2)的标题中获取文本,直到下一个标题(h2),或者如果没有其他语言,则直到页脚:
require 'hpricot'
require 'open-uri'
def get_english_definition(url)
doc = Hpricot(open(url))
span = doc.at('h2/span[@class="mw-headline"][text()=English]')
english_header = span && span.parent
return nil unless english_header
next_header_or_footer =
Hpricot::Elements[*english_header.following_siblings].at('h2') ||
doc.at('[@class="printfooter"]')
Hpricot::Elements.expand(english_header.next_node,
next_header_or_footer.previous_node).to_s
end
示例:强>
get_english_definition "http://en.wiktionary.org/wiki/gift"
答案 2 :(得分:1)
对于Nokogiri:
doc = Nokogiri::HTML(code)
stop_node = doc.css('h2')[3]
doc.traverse do |node|
break if node == stop_node
# else, do whatever, e.g. `puts node.name`
end
这将迭代在第2行中指定为stop_node
的任何节点之前的所有节点。