2024-06-05 19:29:42 发布
网友
嗨,我正试图通过元素的类名和它包含的文本来定位元素
<div class="fc-day-number">15</div>
页面上有一堆具有不同值的fc-day-number,我需要一个具有示例15的值。
fc-day-number
我知道
driver.find_element_by_class_name("fc-day-content")
但我也需要它等于15,我被困在这里,请帮助。
fc_day_contents = driver.find_elements_by_class_name("fc-day-content") the_one_you_want = [x for x in fc_day_contents if "15" == x.text][0]
第一行将类名为“fc day content”的所有元素放入一个列表中(还要注意它的elementsssssss如何带有S,这将按类名、按名称、按id或wahtever返回所有元素的列表)
第二行,遍历每个元素,查看是否有文本“15”作为其文本,并将其作为(可能更小的)列表返回
结尾的[0]返回列表中的第一个项(如果您想要一个包含“15”的所有项的列表,则可以将其删除)
可以使用xpath:
driver.find_element_by_xpath("//div[@class='fc-day-content' and text()='15']")
对于这种情况,更喜欢使用JavaScript:
els = driver.execute_script(""" return Array.prototype.slice.call(document.getElementsByClassName("fc-day-content")) .filter(function (x) { return x.textContent === "15"; }); """) assert len(els) == 1 el = els[0]
这样做的目的是获取所有将类fc-day-content作为类的元素。(顺便说一下,您的问题使用fc-day-content和fc-day-number。不清楚您真正要找的是哪一个,但这在总体方案中并不重要。)对Array.prototype.slice的调用从getElementsByClassName的返回值创建一个数组,因为此方法返回一个HTMLCollection,因此filter在它上不可用。一旦我们有了数组,运行一个filter来将它缩小到对文本有15的元素。这个元素数组由JavaScript代码返回。断言是为了确保我们不会无意中获得多个元素,这将是一个惊喜。然后从列表中提取元素。
fc-day-content
Array.prototype.slice
getElementsByClassName
HTMLCollection
filter
15
(如果您关心IE兼容性,则在IE 9之前,textContent不可用。如果您需要对IE8或更早版本的支持,您可以使用innerText或innerHTML来获得支持,也可以检查元素是否包含值为15的单个文本节点
textContent
innerText
innerHTML
我不喜欢像TehTris那样做(find_elements_by_class_name加上Python循环来查找带有文本的元素),因为该方法需要在Selenium客户机和Selenium服务器之间进行一次往返,以获取找到的每个元素的类fc-day-contentplus1次往返。因此,如果页面上有15个元素与类fc-day-content在一起,那就是16次往返。如果你通过浏览器堆栈或Sauce实验室运行测试,那将大大降低速度。
find_elements_by_class_name
我更喜欢避免使用@class='fc-day-content'的XPath表达式,因为只要向元素添加一个新类,这个表达式就会中断。也许您关心的元素现在只有一个CSS类,但是应用程序会改变。您可以使用XPath的contains()函数,但随后会遇到其他复杂问题,一旦您处理好所有事情,它就会变得有点笨拙。请参阅this answer了解如何可靠地使用它。
@class='fc-day-content'
contains()
第一行将类名为“fc day content”的所有元素放入一个列表中(还要注意它的elementsssssss如何带有S,这将按类名、按名称、按id或wahtever返回所有元素的列表)
第二行,遍历每个元素,查看是否有文本“15”作为其文本,并将其作为(可能更小的)列表返回
结尾的[0]返回列表中的第一个项(如果您想要一个包含“15”的所有项的列表,则可以将其删除)
可以使用xpath:
对于这种情况,更喜欢使用JavaScript:
这样做的目的是获取所有将类
fc-day-content
作为类的元素。(顺便说一下,您的问题使用fc-day-content
和fc-day-number
。不清楚您真正要找的是哪一个,但这在总体方案中并不重要。)对Array.prototype.slice
的调用从getElementsByClassName
的返回值创建一个数组,因为此方法返回一个HTMLCollection
,因此filter
在它上不可用。一旦我们有了数组,运行一个filter
来将它缩小到对文本有15
的元素。这个元素数组由JavaScript代码返回。断言是为了确保我们不会无意中获得多个元素,这将是一个惊喜。然后从列表中提取元素。(如果您关心IE兼容性,则在IE 9之前,
textContent
不可用。如果您需要对IE8或更早版本的支持,您可以使用innerText
或innerHTML
来获得支持,也可以检查元素是否包含值为15
的单个文本节点我不喜欢像TehTris那样做(
find_elements_by_class_name
加上Python循环来查找带有文本的元素),因为该方法需要在Selenium客户机和Selenium服务器之间进行一次往返,以获取找到的每个元素的类fc-day-content
plus1次往返。因此,如果页面上有15个元素与类fc-day-content
在一起,那就是16次往返。如果你通过浏览器堆栈或Sauce实验室运行测试,那将大大降低速度。我更喜欢避免使用
@class='fc-day-content'
的XPath表达式,因为只要向元素添加一个新类,这个表达式就会中断。也许您关心的元素现在只有一个CSS类,但是应用程序会改变。您可以使用XPath的contains()
函数,但随后会遇到其他复杂问题,一旦您处理好所有事情,它就会变得有点笨拙。请参阅this answer了解如何可靠地使用它。相关问题 更多 >
编程相关推荐