【发布时间】:2012-05-26 12:50:40
【问题描述】:
我正在尝试使用 Nokogiri 和 CSS 选择器在 Ruby 中编写一个脚本来解析 Wikipedia 文章。不过,我对脚本中的条件有点困惑。这是我目前所拥有的(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
谢谢!
【问题讨论】:
-
正如下面的 Mark 所指出的,您现在拥有的绝对没有问题,将它们分开总比组合好。
标签: ruby css-selectors nokogiri