如何在python selenium中按类名及其文本定位元素

时间:2014-10-14 21:22:10

标签: python selenium

您好我正在尝试按类名及其包含的文本找到元素

<div class="fc-day-number">15</div>

页面上有一堆fc-day-number有不同的值,我需要一个例如15的。

我做

driver.find_element_by_class_name("fc-day-content") 

但是我也需要它等于15,我被困在这里,请帮忙。

3 个答案:

答案 0 :(得分:12)

您可以使用xpath:

driver.find_element_by_xpath("//div[@class='fc-day-content' and text()='15']")

答案 1 :(得分:4)

 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]

第一行将所有元素放入类名&#34; fc-day-content&#34;在列表中(还要注意它的元素SSSSSSSSS如何与S一起,这将返回所有元素的列表by_class_name,by_name,by_id或wahtever)

第二行,浏览每个元素并查看是否有文本&#34; 15&#34;作为其文本,并将其作为(可能更小的)列表返回

最后的[0],返回列表中的第一个项目(如果你想要列出所有的&#34; 15&#34;),你可以删除它。

答案 2 :(得分:4)

对于这样的事情,更喜欢使用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-contentfc-day-number。不清楚你真正想要的是哪一个,但在宏观方案中并不重要。)对{{1从Array.prototype.slice的返回值创建一个数组,因为此方法返回getElementsByClassName,因此HTMLCollection不可用。获得数组后,运行filter将其缩小为包含filter文本的元素。 JavaScript代码返回此元素数组。断言是为了确保我们不会在不知不觉中获得多个元素,这将是一个惊喜。然后从列表中提取元素。

(如果您关心IE兼容性,在IE 9之前15不可用。如果您需要支持IE 8或更早版本,您可以使用textContent或{{1或者您可以检查该元素是否包含值为innerText的单个文本节点。)

我不喜欢像TehTris那样(innerHTML加上Python循环来找到带有文本的那个),因为该方法需要在Selenium客户端和Selenium服务器之间进行1次往返以获取所有元素已找到的课程15 加上 1次往返元素。因此,如果您的网页上有15个元素find_elements_by_class_name,那就是16次往返。如果您通过浏览器堆栈或Sauce Labs运行测试,这将大大减慢速度。

我更喜欢避免使用fc-day-content的XPath表达式,因为只要向元素添加新类,该表达式就会中断。也许您关心的元素只有一个CSS类现在,但应用程序会发生变化。你可以使用XPath的fc-day-content功能,但是你会遇到其他并发症,一旦你处理好所有事情,就会变得有点笨拙。请参阅this answer了解如何使用它。