我正在尝试使用Selenium测试复杂的javascript界面(使用Python界面,以及跨多个浏览器)。我有许多形式的按钮:
<div>My Button</div>
我希望能够根据“我的按钮”搜索按钮(或不区分大小写的部分匹配,例如“我的按钮”或“按钮”)
我发现这非常困难,在某种程度上,我觉得我错过了一些明显的东西。我到目前为止最好的事情是:
driver.find_elements_by_xpath('//div[contains(text(), "' + text + '")]')
然而,这是区分大小写的。我尝试过的另一件事是遍历页面上的所有div,并检查element.text属性。但是,每当您遇到以下形式的情况时:
<div class="outer"><div class="inner">My Button</div></div>
div.outer也有“我的按钮”作为文本。为了解决这个问题,我试图查看div.outer是否是div.inner的父节点,但是无法弄清楚如何做到这一点(element.get_element_by_xpath('..')返回一个元素的父节点,但它测试不等于div.outer)。此外,迭代遍历页面上的所有元素似乎非常慢,至少使用Chrome webdriver。
想法?
编辑:这个问题有点模糊。在这里询问(并回答)更具体的版本:How to get text of an element in Selenium WebDriver (via the Python api) without including child element text?
答案 0 :(得分:250)
尝试以下方法:
driver.find_elements_by_xpath("//*[contains(text(), 'My Button')]")
答案 1 :(得分:23)
您可以尝试使用xpath:
'//div[contains(text(), "{0}") and @class="inner"]'.format(text)
答案 2 :(得分:16)
在您提供的HTML中:
<div>My Button</div>
文本My Button
是innerHTML
,并且周围没有空格,因此您可以按如下方式轻松使用text()
:
my_element = driver.find_element_by_xpath("//div[text()='My Button']")
注意:
text()
选择上下文节点的所有文本节点子级
如果相关文本的开头包含空格:
<div> My Button</div>
或末尾:
<div>My Button </div>
或两端:
<div> My Button </div>
在这些情况下,您有两个选择:
您可以使用contains()
函数来确定第一个参数字符串是否包含第二个参数字符串,并按如下所示返回布尔值true或false:
my_element = driver.find_element_by_xpath("//div[contains(., 'My Button')]")
您可以使用normalize-space()
函数,该函数从字符串中去除开头和结尾的空格,将空格字符序列替换为一个空格,然后返回结果字符串,如下所示:
driver.find_element_by_xpath("//div[normalize-space()='My Button']]")
如果文本是变量,则可以使用:
foo= "foo_bar"
my_element = driver.find_element_by_xpath("//div[.='" + foo + "']")
答案 3 :(得分:12)
您也可以将它与页面对象模式一起使用,例如:
试试这段代码:
@FindBy(xpath = "//*[contains(text(), 'Best Choice')]")
WebElement buttonBestChoice;
答案 4 :(得分:8)
// *将寻找任何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')]")
答案 5 :(得分:2)
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(), 'YourTextHere')]")));
assertNotNull(driver.findElement(By.xpath("//*[contains(text(), 'YourTextHere')]")));
String yourButtonName=driver.findElement(By.xpath("//*[contains(text(), 'YourTextHere')]")).getAttribute("innerText");
assertTrue(yourButtonName.equalsIgnoreCase("YourTextHere"));
答案 6 :(得分:2)
简单地使用这个:
driver.find_elements_by_xpath('//*[text() = "My Button"]')
答案 7 :(得分:1)
有趣的是,几乎所有答案都围绕着xpath的函数contains()
,而忽略了区分大小写的事实敏感-与OP的要求相反。
如果您不区分大小写,则可以在xpath 1.0 (现代浏览器支持的版本)中实现,尽管它不是很漂亮-使用translate()
函数。通过使用转换表,它将源字符替换为其所需的形式。
构造一个由所有大写字母组成的表格将有效地将节点的文本转换为其lower()形式-允许不区分大小写的匹配(这里只是特权):
[
contains(
translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),
'my button'
)
]
# will match a source text like "mY bUTTon"
完整的python调用:
driver.find_elements_by_xpath("//*[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZЙ', 'abcdefghijklmnopqrstuvwxyzй'), 'my button')]")
自然,这种方法有其缺点-如给定的,它仅适用于拉丁文字;如果要覆盖Unicode字符-您必须将它们添加到翻译表中。我已经在上面的示例中完成了此操作-最后一个字符是西里尔字母"Й"
。
如果我们生活在一个浏览器支持xpath 2.0及更高版本的世界中[em>(但不久之后不会发生☹️) ,我们本可以使用函数lower-case()
(但不是)完全支持区域设置)和matches
(用于正则表达式搜索,不区分大小写('i'
)标志。
答案 8 :(得分:0)
对元素进行不区分大小写的搜索,使用driver.find_elements_by_xpath和matches正则表达式匹配功能。
driver.find_elements_by_xpath("//*[matches(.,'My Button', 'i')]")
答案 9 :(得分:0)
类似的问题:查找AndroidManifest.xml
也许这会给您一些想法(请将概念从Java转移到Python):
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@RunWith(AndroidJUnit4.class)
public class ExampleTest {
@Before
public void setUp() throws Exception {
// Setup here
}
@After
public void tearDown() {
// Tear down here
}
@Test
public void testExample() {
// Test code here
}
...
}
答案 10 :(得分:0)
如果使用 C#
ChromeOptions options = new ChromeOptions();
var driver = new ChromeDriver(options);
var urlLink = "https://www.pexels.com/tr-tr/arama/do%C4%9Fa/";
driver.Navigate().GoToUrl(urlLink);
Thread.Sleep(10000);
var divList = driver.FindElementsByXPath(".//div[contains(@class,'hide-featured-badge')]");
foreach (var divItem in divList)
{
var photoOwnerName = divItem.FindElement(By.XPath(".//span[@class='photo-item__name']")).GetAttribute("innerHTML");
}
答案 11 :(得分:-18)
试试这个。很容易:
driver.getPageSource().contains("text to search");
这在selenium web driver中对我有用。