通过机械化获取所有标签以下内容? (红宝石)

时间:2017-07-12 10:51:25

标签: ruby xpath css-selectors nokogiri mechanize-ruby

如何让所有元素跟随一次,例如:

<div id="exemple">
  <h2 class="target">foo</h2>
  <p>bla bla</p>
  <ul>
    <li>bar1</li>
    <li>bar2</li>
    <li>bar3</li>
  </ul>
  <h4>baz</h4> 
  <ul>
     <li>lot</li>
  </ul>
  <div>of</div>
  <p>possible</p>
  <p>tags</p>
  <a href="#">after</a>
</div>

我需要检测<h2 class="target">并将所有标记转到下一个<h4>并忽略<h4> AND 所有关注标记(如果<h4>没有存在,我必须将所有标签都放到父[[此处:<div>的结尾])

的末尾

内容是动态且不可预测的唯一的规则是:我们知道有一个目标,并且有一个(或元素的结尾)。我需要在两者之间获取所有标签并排除所有其他标签。

有了这个例子,我需要获得以下HTML:

<h2 class="target">foo</h2>
<p>bla bla</p>
<ul>
  <li>bar1</li>
  <li>bar2</li>
  <li>bar3</li>
</ul>

所以我可以得到:target = page.at('#exemple .target') 我知道next_sibling方法,但是如何测试当前节点的标签类型?

我认为这样的事情就是节点树:

html = ''
while not target.is_a? 'h4'
  html << target.inner_html
  target = target.next_sibling

我该怎么做?

2 个答案:

答案 0 :(得分:2)

您可以从节点集中减去不需要的那些:

h2 = page.at('h2')
(h2.search('~ *') - h2.search('~ h4','~ h4 ~ *')).each do |el|
    # el is not a h4 and does not follow a h4
end

使用xpath可能更有意义,但我可以在没有谷歌搜索的情况下这样做。

您对迭代下一个兄弟的想法也可以起作用:

el = page.at('h2 ~ *')
while el && el.name != 'h4'
    # do something with el
    el = el.at('+ *')
end

答案 1 :(得分:1)

看起来您想要返回h2元素及其后续兄弟元素。我不清楚你是想保留还是丢弃h4;如果你想保留XPath将是:

//h2[@class="target"] | //h2[@class="target"]/following-sibling::*

如果您需要排除h4

//h2[@class="target"] | //h2[@class="target"]/following-sibling::*[not(self::h4)]

修改:如果您需要排除h4以及其他内容:

//h2[@class="target"] | //h2[@class="target"]/following-sibling::*[not(self::h4) | not(preceding-sibling::h4)]