如何用Nokogiri解析连续标签?
我有这样的HTML代码:
Label1 Value1 Label2 Value2 ...
我的代码不起作用。
doc.css("first").each do |item| label = item.css("dt") value = item.css("dd") end
显示所有
标签,我需要“标签:值”
首先,您的HTML应该在
包含
和
元素:
- Label1
- Value1
- Label2
- Value2
...
但这不会改变你解析它的方式。 你想找到
并迭代它们,然后在每个
你可以使用next_element
来获得
; 像这样的东西:
doc = Nokogiri::HTML('...') doc.css('#first').search('dt').each do |node| puts "#{node.text}: #{node.next_element.text}" end
只要结构与您的示例匹配,这应该有效。
假设某些
可能有多个
,您希望找到所有
,然后(对于每个)在下一个
之前找到以下
。 这在纯Ruby中非常容易,但在XPath中更有趣。 ;)
鉴于此设置:
require 'nokogiri' html = ' - Label1
- Value1
- Label2
- Value2
- Label3
- Value3a
- Value3b
- Label4
- Value4
' doc = Nokogiri.HTML(html)
不使用XPath :
doc.css('dt').each do |dt| dds = [] n = dt.next_element begin dds << n n = n.next_element end while n && n.name=='dd' p [dt.text,dds.map(&:text)] end #=> ["Label1", ["Value1"]] #=> ["Label2", ["Value2"]] #=> ["Label3", ["Value3a", "Value3b"]] #=> ["Label4", ["Value4"]]
使用Little XPath :
doc.css('dt').each do |dt| dds = dt.xpath('following-sibling::*').chunk{ |n| n.name }.first.last p [dt.text,dds.map(&:text)] end #=> ["Label1", ["Value1"]] #=> ["Label2", ["Value2"]] #=> ["Label3", ["Value3a", "Value3b"]] #=> ["Label4", ["Value4"]]
使用Lotsa XPath :
doc.css('dt').each do |dt| ct = dt.xpath('count(following-sibling::dt)') dds = dt.xpath("following-sibling::dd[count(following-sibling::dt)=#{ct}]") p [dt.text,dds.map(&:text)] end #=> ["Label1", ["Value1"]] #=> ["Label2", ["Value2"]] #=> ["Label3", ["Value3a", "Value3b"]] #=> ["Label4", ["Value4"]]
看完其他答案后,这是一种做同样事情的低效方法。
require 'nokogiri' a = Nokogiri::HTML('Label1 Value1 Label2 Value2 ') dt = [] dd = [] a.css("#first").each do |item| item.css("dt").each {|t| dt << t.text} item.css("dd").each {|t| dd << t.text} end dt.each_index do |i| puts dt[i] + ': ' + dd[i] end
在css中引用ID需要先放入#符号。 对于一个类,它是。 符号。