如何使用watir-webdriver遍历DOM(children/siblings)?

How to traverse DOM (children/siblings) using watir-webdriver?

我习惯使用 PHP 的 Simple HTML DOM Parser(SHDP) 来访问元素,但我现在使用 ruby 和 watir-webdriver,并且我我想知道就访问页面上的元素而言,这是否可以取代 SHDP 的功能。

所以在 SHDP 中我会这样做:

$ret = $html->find('div[id=foo]');

它是 divid=foo 的所有实例的数组。哦,而且 $html 是指定 URL 的 HTML 来源。无论如何,那么我会把它放在一个循环中:

foreach($ret as $element) 
       echo $element->first_child ()->first_child ()->first_child ()->first_child ()->first_child ()->first_child ()->first_child ()->plaintext . '<br>';

现在,这里每个 ->first_child() 都是 parent divid=foo 的 child(注意我有七个),然后我打印第 7 个 child 的明文。像这样

<div id="foo">
    <div ...>
        <div ...>
            <div ...>
                <div ...>
                    <div ...>
                        <div ...>
                            <div ...>HAPPINESS</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div
</div>

会打印 "HAPPINESS"。所以,我的问题是,如何使用 watir-webdriver(如果可能的话)来完成?

此外,更一般地说,我如何在 watir-webdriver 中获得 SHDP 的 DOM-traversing 能力:

enter image description here

我问是因为如果 watir-webdriver 不能做到这一点,我将不得不想办法将 watir-webdriver 中的浏览器实例源通过管道传输到 PHP 使用 SHDP 的脚本并以这种方式获取它,并以某种方式将其与相关信息返回 ruby...

我不相信有 .child 方法可以为您做这件事。如果你知道在那个结构中它总是有七个子 div,你可以做 inelegant

require 'watir-webdriver'
@browser = Watir::Browser.new
puts @browser.div(id: 'foo').div.div.div.div.div.div.div.text

你总是可以抓取它们的集合,然后处理最后一个,假设它是最后一个,堆栈中最深的。

puts @browser.div(id: 'foo').divs.last.text

这也可行,但假设页面结构是绝对的。它也不等同于您在上面获得的元素的迭代。由于我不清楚这样做的价值,所以我不愿意尝试使用等效代码。

也许我没有告诉你你在 PHP 中所做的事情。但是,如果您知道第 7 个 child 的文本将是 HAPPINESS,那么您可以简单地通过 XPath 定位一个元素:

步骤:

Given(/^I click the div "(.*?)" xpath$/) do |div_xpath|
  Watir::Wait.until { @browser.div(:xpath => div_xpath).exist? }
                      @browser.div(:xpath => div_xpath).click
end

特征:

Given I click the div "//div[@id='foo'][text()='HAPPINESS']" xpath

Watir 实现了 :index 功能(从零开始):

browser.div(id: 'foo').divs           # children
browser.div(id: 'foo').div(index: 6)  # nth-child
browser.div(id: 'foo').parent         # parent
browser.div(id: 'foo').div            # first-child
browser.div(id: 'foo').div(index: -1) # last-child

next_siblingprevious_sibling 目前没有实现,如果您认为您的代码有必要,请在这里发表评论:https://github.com/watir/watir/pull/270

请注意,通常您应该更喜欢使用索引而不是使用集合,但这些也有效:

browser.div(id: 'foo').divs.first
browser.div(id: 'foo').divs.last

平装代码示例(您是通过文本查找select还是获取文本?):

browser.li(text: /Paperback/)  
browser.td(class: "bucket").li
browser.table(id: 'productDetailsTable').li

我们过去也有请求支持直接子代而不是解析所有后代:https://github.com/watir/watir/issues/329

我们正在积极研究我们希望如何在即将推出的 Watir 版本中进行改进,因此如果此解决方案不适合您,请 post 建议您使用理想的语法来完成您的工作想要这里:https://github.com/watir/watir/issues 我们将看看如何支持它。