使用 mechanize 获取特定的所有标签? (ruby)

Get all tags followings a certain with 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

我该怎么做?

您似乎想要 return 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)]

你可以从你的节点集中减去你不想要的:

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