我正在尝试用 Ruby 编写一个脚本来使用 Nokogiri 和 CSS 选择器来解析维基百科的文章。不过,我对脚本中的条件有点困惑。这是我到目前为止所拥有的(page
是使用 Nokogiri 下载的 html):
page.css('h3').each do |node|
puts node.text
end
page.css('li').each do |node|
if /\d|\D/.match(node)
puts node.text.scan(/[\d]+\D*/).first
end
end
page.css('td b').each do |node|
puts node.text
end
这一切都很好。但是,我真正想要的是这样的:
page.css('h3, li, td b').each do |node|
# if it's an h3 node, do one thing
# if it's a li node, do another thing
# else if it's a 'td b' node, do another thing
end
这将允许按顺序解析页面,而不是分别通过正文三次。但是,我不确定如何在我的脚本中编写这些条件。
编辑:所以现在我的脚本是
page.css('h3, li, td b').each do |node|
case node.name
when 'h3', 'b'
puts node.text
when 'li'
if /\d|\D/.match(node)
puts node.text.scan(/[\d]+\D*/).first
end
else
next
end
end
但是,它并没有改变行为。它以与之前相同的顺序处理它们(所有'h3'元素,然后是所有'li'元素,然后是所有'b'元素)。
编辑2:
好吧,我终于让它工作了。这是我的最后一组条件:
page.traverse do |node|
case
when 'h3' == node.name
puts node.text
when 'li' == node.name
puts node.text.scan(/[\d]+\D*/).first if /\d|\D/.match(node)
when 'b' == node.name
puts node.text if (node.parent.name == 'p' or node.parent.name == 'td')
end
end
谢谢!