如何使用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]');
它是 div
和 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>';
现在,这里每个 ->first_child()
都是 parent div
和 id=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 能力:
我问是因为如果 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_sibling
和 previous_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 我们将看看如何支持它。
我习惯使用 PHP 的 Simple HTML DOM Parser(SHDP) 来访问元素,但我现在使用 ruby 和 watir-webdriver,并且我我想知道就访问页面上的元素而言,这是否可以取代 SHDP 的功能。
所以在 SHDP 中我会这样做:
$ret = $html->find('div[id=foo]');
它是 div
和 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>';
现在,这里每个 ->first_child()
都是 parent div
和 id=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 能力:
我问是因为如果 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_sibling
和 previous_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 我们将看看如何支持它。