【问题标题】:How to traverse DOM (children/siblings) using watir-webdriver?如何使用 watir-webdriver 遍历 DOM(孩子/兄弟姐妹)?
【发布时间】:2016-12-20 17:15:24
【问题描述】:

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

所以在 SHDP 中我会这样做:

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

这是divs 和id=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>';

现在,在这里,每个 -&gt;first_child() 都是父 divid=foo 的孩子(注意我有七个),然后我打印第 7 个孩子的明文。像这样的

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

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

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

enter image description here

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

【问题讨论】:

  • 文档/参考会很棒。

标签: php ruby dom html-parsing watir-webdriver


【解决方案1】:

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

平装代码示例(您是要按文本选择还是获取文本?):

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

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

我们正在积极研究我们希望如何改进即将发布的 Watir 版本中的内容,因此如果此解决方案不适合您,请在此处发布您的理想语法建议:https://github.com/watir/watir/issues我们会看看如何支持它。

【讨论】:

  • 查看 titusfortner 对 David Shute 回答的评论。
【解决方案2】:

我不相信有 .child 方法可以为您执行此操作。如果你知道在那个结构中它总是有七个子 div,你可以做不优雅的

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

这也可以,但假定页面结构具有绝对性。它也不等同于您在上面得到的元素的迭代。因为我不清楚这样做的价值,所以我不太愿意尝试等效的代码。

【讨论】:

  • this 这样的访问文本“Paperback:”怎么样?
  • 你能做到@browser.table(id: 'productDetailsTable').tr.td.??? ??? 是我不知道如何处理兄弟姐妹。
  • @Forwarding - 如果您需要直接的兄弟姐妹支持,请在此处留言:github.com/watir/watir/pull/270
  • @titusfortner,那么,您将如何在 XPath 中执行此操作?
【解决方案3】:

也许我没有准确地告诉你你在 PHP 中所做的事情。但是,如果您知道第 7 个孩子的文本将是 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

【讨论】:

  • 请尽量避免将 XPath 选择器与 Watir 一起使用。 Watir API 使它几乎完全没有必要,而且读起来很糟糕。 :) 如果要根据文本匹配元素,请使用:@browser.div(text: "HAPPINESS")
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-21
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
  • 1970-01-01
相关资源
最近更新 更多