如何在Selenium Webdriver(Python)中找到包含特定文本的元素?

jos*_*osh 229 python selenium selenium-webdriver

我正在尝试使用Selenium测试复杂的javascript界面​​(使用Python界面,以及跨多个浏览器).我有许多形式的按钮:

<div>My Button</div>
Run Code Online (Sandbox Code Playgroud)

我希望能够根据"我的按钮"搜索按钮(或者不区分大小写的部分匹配,例如"我的按钮"或"按钮")

我发现这非常困难,在某种程度上我觉得我错过了一些明显的东西.我到目前为止最好的事情是:

driver.find_elements_by_xpath('//div[contains(text(), "' + text + '")]')
Run Code Online (Sandbox Code Playgroud)

但是,这是区分大小写的.我尝试过的另一件事是遍历页面上的所有div,并检查element.text属性.但是,每次你得到表格的情况:

<div class="outer"><div class="inner">My Button</div></div>
Run Code Online (Sandbox Code Playgroud)

div.outer还有"My Button"作为文本.为了解决这个问题,我试图查看div.outer是否是div.inner的父节点,但是无法弄清楚如何做到这一点(element.get_element_by_xpath('..')返回一个元素的父节点,但它测试不等于div.outer).此外,迭代浏览页面上的所有元素似乎非常慢,至少使用Chrome webdriver.

想法?

编辑:这个问题有点模糊.在这里询问(并回答)一个更具体的版本:如何在不包含子元素文本的情况下获取Selenium WebDriver中的元素文本(通过Python api)?

Ric*_*cky 286

请尝试以下方法:

driver.find_elements_by_xpath("//*[contains(text(), 'My Button')]")
Run Code Online (Sandbox Code Playgroud)

  • 对于其他搜索引擎访问者也值得一提:如果您正在寻找链接,那么有`find_element(s)_by_link_text`和`find_element(s)_by_partial_link_text`方法 (9认同)
  • 谢谢你的回复,这是我需要的50%(让我开始).我到达的表格是"(//*[contains(text(),'"+ text +"')] | //*[@ value ='"+ text +"'])"它将搜索不仅在元素节点内给出文本,而且在文本通过'value'属性设置的输入元素内,即<button value ="My Button"/>.虽然请注意,值必须严格匹配,而不仅仅包含文本. (3认同)
  • 如果文本是动态的怎么办?也就是说,可能包含引号.这不会打破这个解决方案吗? (3认同)
  • 搜索某些名称似乎打破了这一点.以下面的例子为例:"//*[contains(text(),'"+ username +"')]"if username ="O'Reilly"; 然后xpath将变为无效.有没有解决的办法? (3认同)
  • 当目标文本有多行时,它似乎不起作用。 (2认同)

Deb*_*anB 30

在您提供的 HTML 中:

<div>My Button</div>
Run Code Online (Sandbox Code Playgroud)

文本My ButtoninnerHTML并且周围没有空格,因此您可以轻松使用text()如下:

my_element = driver.find_element_by_xpath("//div[text()='My Button']")
Run Code Online (Sandbox Code Playgroud)

注意text()选择上下文节点的所有文本节点子节点


带有前导/尾随空格的文本

如果相关文本在开头包含空格

<div>   My Button</div>
Run Code Online (Sandbox Code Playgroud)

或最后:

<div>My Button   </div>
Run Code Online (Sandbox Code Playgroud)

或在两端:

<div> My Button </div>
Run Code Online (Sandbox Code Playgroud)

在这些情况下,您有两种选择:

  • 您可以使用contains()函数来确定第一个参数字符串是否包含第二个参数字符串并返回布尔值 true 或 false,如下所示:

      my_element = driver.find_element_by_xpath("//div[contains(., 'My Button')]")
    
    Run Code Online (Sandbox Code Playgroud)
  • 您可以使用normalize-space()函数从字符串中去除前导和尾随空格,用单个空格替换空格字符序列,并返回结果字符串,如下所示:

      driver.find_element_by_xpath("//div[normalize-space()='My Button']]")
    
    Run Code Online (Sandbox Code Playgroud)

可变文本的 XPath 表达式

如果文本是变量,您可以使用:

foo= "foo_bar"
my_element = driver.find_element_by_xpath("//div[.='" + foo + "']")
Run Code Online (Sandbox Code Playgroud)


and*_*ean 24

你可以尝试像xpath一样:

'//div[contains(text(), "{0}") and @class="inner"]'.format(text)
Run Code Online (Sandbox Code Playgroud)

  • xpath 2.0 有一个小写函数,所以这应该可以工作: '//div[contains(lower-case(text()), "{0}")]'.format(text) (2认同)

Krz*_*ski 12

您也可以将它与页面对象模式一起使用,例如:

试试这段代码:

@FindBy(xpath = "//*[contains(text(), 'Best Choice')]")
WebElement buttonBestChoice;
Run Code Online (Sandbox Code Playgroud)


Ish*_*hah 9

// *将寻找任何HTML标记。如果某些文本对于Button和div标签是通用的,并且// *是类别,则无法按预期工作。如果需要选择任何特定内容,则可以通过声明HTML Element标签来获取。喜欢:

driver.find_element_by_xpath("//div[contains(text(),'Add User')]")
driver.find_element_by_xpath("//button[contains(text(),'Add User')]")
Run Code Online (Sandbox Code Playgroud)


Tod*_*kov 8

有趣的是,几乎所有答案都围绕 XPath's function contains(),忽略了它区分大小写的事实- 与 OP 的要求相反。

如果您需要不区分大小写,可以在 XPath 1.0 (当代浏览器支持的版本)中实现,尽管它并不漂亮 - 通过使用该translate()功能。它通过使用转换表将源字符替换为其所需的形式。

构建一个包含所有大写字符的表格将有效地将节点的文本转换为其 lower() 形式 - 允许不区分大小写的匹配(这里只是特权)

[
  contains(
    translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),
    'my button'
  )
]
# will match a source text like "mY bUTTon"
Run Code Online (Sandbox Code Playgroud)

完整的 Python 调用:

driver.find_elements_by_xpath("//*[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ?', 'abcdefghijklmnopqrstuvwxyz?'), 'my button')]")
Run Code Online (Sandbox Code Playgroud)

自然,这种方法有其缺点——正如所给的,它仅适用于拉丁文本;如果您想涵盖 Unicode 字符 - 您必须将它们添加到翻译表中。我在上面的示例中已经这样做了 - 最后一个字符是西里尔符号"?"


如果我们生活在一个世界里,浏览器所支持的XPath 2.0及以上(但不会很快发生任何时候?) ,我们已经能够使用的功能lower-case()(但不完全区域识别),以及matches(对于正则表达式搜索,与不区分大小写 ( 'i') 标志)。


Ama*_*mar 6

只需使用这个:

driver.find_elements_by_xpath('//*[text() = "My Button"]')
Run Code Online (Sandbox Code Playgroud)