VBA Selenium - 在具有多个非常相似的条目的容器中查找要单击的按钮
VBA Selenium - Find Button to Click in Container that has multiple very similar entries
抱歉新手所以希望以正确的格式发帖
我正在尝试查找并单击按钮。
这是针对发球台预订 sheet 的,每次可用时都有一个单独的按钮(文本 = 预订)。
我需要进入 Div Class 'controls' 部分并在一段时间内找到(比如 07:54),如果找到请点击。
我试过了
obj.FindElementByXPath("*//div[@class,'Controls' contains(text(),'07:54')]").Click
obj.FindElementByPartialLinkText("07:54").Click
和其他各种不起作用的和
obj.FindElementByXPath("//*//*[@id='booking-teesheet-container']/div/div[5]/div[2]/div[3]/div/a").Click
这有效但无法让我搜索特定时间
如您所见,我并不精通 VBA Selenium。
感谢任何帮助
<div class="tee available" data-hour-val="9" data-min-val="22" data-teetime="2021-03-30 09:22">
<div class="time theme_bg">
09:22
</div>
<div class="info">
<div class="col-xs-12 col-sm-6" data-players-view-ctr="09:22">
<div class="player player-free view" data-players-view="09:22"><span>P</span> <i class="fa fa-angle-double-down"></i> View Players</div>
</div>
<div class="players col-xs-12 col-sm-8 col-md-6" data-players="09:22">
<div class="player player-free">
<span>P1</span>
<a data-teetime-selected="2021-03-30 09:22" href="/Members/BookingAdd?dateTime=2021-03-30T09%3A22&courseId=7738&startPoint=1&crossOverStartPoint=0&crossOverMinutes=0">
Available
</a>
</div>
<div class="player player-free">
<span>P2</span>
<a data-teetime-selected="2021-03-30 09:22" href="/Members/BookingAdd?dateTime=2021-03-30T09%3A22&courseId=7738&startPoint=1&crossOverStartPoint=0&crossOverMinutes=0">
Available
</a>
</div>
<div class="player player-free">
<span>P3</span>
<a data-teetime-selected="2021-03-30 09:22" href="/Members/BookingAdd?dateTime=2021-03-30T09%3A22&courseId=7738&startPoint=1&crossOverStartPoint=0&crossOverMinutes=0">
Available
</a>
</div>
<div class="player player-free">
<span>P4</span>
<a data-teetime-selected="2021-03-30 09:22" href="/Members/BookingAdd?dateTime=2021-03-30T09%3A22&courseId=7738&startPoint=1&crossOverStartPoint=0&crossOverMinutes=0">
Available
</a>
</div>
</div>
<div class="col-xs-12 col-sm-6">
<div class="controls">
<a
data-book="1"
data-teetime-selected="2021-03-30 09:22"
href="/Members/BookingAdd?dateTime=2021-03-30T09%3A22&courseId=7738&startPoint=1&crossOverStartPoint=0&crossOverMinutes=0"
class="btn btn-primary theme_bg theme_border_primary"
>
Book
</a>
</div>
</div>
</div>
</div>
您可以使用属性=值select或。假设您想预订时间(不考虑日期),您可以使用
FindElementByCss(".controls [data-teetime-selected*='09:22']").click
这会在
中查找值为 09:22 的 data-teetime-selected
属性
如果要指定日期:
[data-teetime-selected*='2021-03-30 09:22']
至 select 播放器免费链接例如
[data-players='09:22'] .player-free
我无法从 html 中得知此属性 data-teetime-selected
是否是在执行其他步骤后动态添加的。
您的问题不在于 Selenium 本身。您的问题是了解 XPath(或其他定位器策略)的工作原理。在我看来,您的问题是您试图区分多个几乎相同的网络元素。
<a data-teetime-selected="2021-03-30 09:22" ...>...</a>
问题是,如何区分它们?您必须找到可区分的属性或值来区分它们。一种方法是通过 link 文本。您有 4 个属性的文本值为“可用”。如果您需要获得其中之一,那将非常困难,因为所有四个都完全相同。您将不得不求助于 select 四个中的第一个。为此,您可以使用 findElementByXPath
,这将 return 匹配表达式的第一个元素。或者,您可以使用 findElementsByXPath
并且 return 是一个您可以遍历的列表。
幸运的是,这里不是这种情况。对于另一个元素,您可以使用像这样的 XPath 表达式://a[contains(@data-teetime-selected, '09:22') and contains(text(), 'Book')]
.
其他建议
- 避免使用
//*
- 尝试查找满足特定条件的“任何”元素可能会导致错误匹配。更具体(注意我用 //a
作为我的表达)
- 避免在表达式中使用索引 -
../div/div[5]/div[2]/div[3]/div/a
像这样的表达式极难预测并且容易受到页面结构变化的影响;从而导致匹配错误的元素。另外,这么长的表达提出了我的下一个观点......
- 尽可能接近所需的元素 - 并非总是如此,但通常做
//div/a
之类的事情比 ../div/div[5]/div[2]/div[3]/div/a
更好。在这不是真的情况下,您可以使用这些元素的属性和值来优化您的路径(即 //div[@id='foo']//div/a
)
- 学会有效地使用 XPath axes。
抱歉新手所以希望以正确的格式发帖
我正在尝试查找并单击按钮。 这是针对发球台预订 sheet 的,每次可用时都有一个单独的按钮(文本 = 预订)。 我需要进入 Div Class 'controls' 部分并在一段时间内找到(比如 07:54),如果找到请点击。
我试过了
obj.FindElementByXPath("*//div[@class,'Controls' contains(text(),'07:54')]").Click
obj.FindElementByPartialLinkText("07:54").Click
和其他各种不起作用的和
obj.FindElementByXPath("//*//*[@id='booking-teesheet-container']/div/div[5]/div[2]/div[3]/div/a").Click
这有效但无法让我搜索特定时间 如您所见,我并不精通 VBA Selenium。
感谢任何帮助
<div class="tee available" data-hour-val="9" data-min-val="22" data-teetime="2021-03-30 09:22">
<div class="time theme_bg">
09:22
</div>
<div class="info">
<div class="col-xs-12 col-sm-6" data-players-view-ctr="09:22">
<div class="player player-free view" data-players-view="09:22"><span>P</span> <i class="fa fa-angle-double-down"></i> View Players</div>
</div>
<div class="players col-xs-12 col-sm-8 col-md-6" data-players="09:22">
<div class="player player-free">
<span>P1</span>
<a data-teetime-selected="2021-03-30 09:22" href="/Members/BookingAdd?dateTime=2021-03-30T09%3A22&courseId=7738&startPoint=1&crossOverStartPoint=0&crossOverMinutes=0">
Available
</a>
</div>
<div class="player player-free">
<span>P2</span>
<a data-teetime-selected="2021-03-30 09:22" href="/Members/BookingAdd?dateTime=2021-03-30T09%3A22&courseId=7738&startPoint=1&crossOverStartPoint=0&crossOverMinutes=0">
Available
</a>
</div>
<div class="player player-free">
<span>P3</span>
<a data-teetime-selected="2021-03-30 09:22" href="/Members/BookingAdd?dateTime=2021-03-30T09%3A22&courseId=7738&startPoint=1&crossOverStartPoint=0&crossOverMinutes=0">
Available
</a>
</div>
<div class="player player-free">
<span>P4</span>
<a data-teetime-selected="2021-03-30 09:22" href="/Members/BookingAdd?dateTime=2021-03-30T09%3A22&courseId=7738&startPoint=1&crossOverStartPoint=0&crossOverMinutes=0">
Available
</a>
</div>
</div>
<div class="col-xs-12 col-sm-6">
<div class="controls">
<a
data-book="1"
data-teetime-selected="2021-03-30 09:22"
href="/Members/BookingAdd?dateTime=2021-03-30T09%3A22&courseId=7738&startPoint=1&crossOverStartPoint=0&crossOverMinutes=0"
class="btn btn-primary theme_bg theme_border_primary"
>
Book
</a>
</div>
</div>
</div>
</div>
您可以使用属性=值select或。假设您想预订时间(不考虑日期),您可以使用
FindElementByCss(".controls [data-teetime-selected*='09:22']").click
这会在
中查找值为 09:22 的data-teetime-selected
属性
如果要指定日期:
[data-teetime-selected*='2021-03-30 09:22']
至 select 播放器免费链接例如
[data-players='09:22'] .player-free
我无法从 html 中得知此属性 data-teetime-selected
是否是在执行其他步骤后动态添加的。
您的问题不在于 Selenium 本身。您的问题是了解 XPath(或其他定位器策略)的工作原理。在我看来,您的问题是您试图区分多个几乎相同的网络元素。
<a data-teetime-selected="2021-03-30 09:22" ...>...</a>
问题是,如何区分它们?您必须找到可区分的属性或值来区分它们。一种方法是通过 link 文本。您有 4 个属性的文本值为“可用”。如果您需要获得其中之一,那将非常困难,因为所有四个都完全相同。您将不得不求助于 select 四个中的第一个。为此,您可以使用 findElementByXPath
,这将 return 匹配表达式的第一个元素。或者,您可以使用 findElementsByXPath
并且 return 是一个您可以遍历的列表。
幸运的是,这里不是这种情况。对于另一个元素,您可以使用像这样的 XPath 表达式://a[contains(@data-teetime-selected, '09:22') and contains(text(), 'Book')]
.
其他建议
- 避免使用
//*
- 尝试查找满足特定条件的“任何”元素可能会导致错误匹配。更具体(注意我用//a
作为我的表达) - 避免在表达式中使用索引 -
../div/div[5]/div[2]/div[3]/div/a
像这样的表达式极难预测并且容易受到页面结构变化的影响;从而导致匹配错误的元素。另外,这么长的表达提出了我的下一个观点...... - 尽可能接近所需的元素 - 并非总是如此,但通常做
//div/a
之类的事情比../div/div[5]/div[2]/div[3]/div/a
更好。在这不是真的情况下,您可以使用这些元素的属性和值来优化您的路径(即//div[@id='foo']//div/a
) - 学会有效地使用 XPath axes。