d=<<"EOM"
<ul>
<li><a id=t href="t">a</a></li>
<li><a id=b href="b">b</a></li>
<li>
<ul>
<li><a href="inner">don't want inner</a></li>
<li><a href="inner">don't want inner</a></li>
</ul>
</li>
<li><a id=c href="c">c</a></li>
</ul>
<ul>
<li><a href="d">don't want</a></li>
</ul>
EOM
doc = Nokogiri.HTML(d)
t = doc.css("#t")[0]
我怎样才能获得所有具有相同 href 的 href外容器为"t",并且同时位于深度为"t"? 在这种情况下,我只想要Hrefs t,b,c.这些并不总是在 UL 中,只是使用举个例子。
要获得与 t 具有相同"祖父"的所有标签,您可以执行以下操作:
doc.css('a').select{|a| a.parent.parent == t.parent.parent}
要获取他们的 hrefs:
doc.css('a').select{|a| a.parent.parent == t.parent.parent}.map{|a| a[:href]}
如果您知道 ID 是一致的:
puts doc.search('#t, #b, #c').map{ |n| n['href'] }
如果你不知道它们会是什么,那么 XPath 可以带你去那里:
doc.search('//*[@id="t"]/../../*/*[@id]').to_html
=> "<a id="t" href="t">a</a><a id="b" href="b">b</a><a id="c" href="c">c</a>"
doc.search('//*[@id="t"]/../../*/*[@id]').map{ |n| n['href'] }
=> ["t", "b", "c"]
这意味着"查找 ID 为't'的节点,然后备份两个级别并向下查找具有填充 id 属性的节点"。
谢谢@pguardiario
父节点可以处于任何级别,所以我像这样修改了您的代码:
t = doc.css("#a")[0]
r = []
p = t.parent
x = 0
while true
break if p.node_name == "body" || p.node_name == "html"
x += 1
r = doc.css('a').select{|a|
m = a
x.times { m = m.parent }
m == p
}
break if r.length > 1
p = p.parent
end
pp r.length
我相信有比这种蛮力方法更好的方法。