我试图用Selenium测试一个复杂的JavaScript接口(使用Python接口,并跨多个浏览器)。我有一些按钮的形式:

<div>My Button</div>

我希望能够搜索基于“我的按钮”(或非大小写敏感,部分匹配,如“我的按钮”或“按钮”)的按钮。

我发现这非常困难,以至于我觉得我错过了一些明显的东西。到目前为止,我所拥有的最好的东西是:

driver.find_elements_by_xpath('//div[contains(text(), "' + text + '")]')

但是,这是区分大小写的。我尝试的另一件事是遍历页面上的所有div,并检查元素。文本属性。然而,每次你得到这样的情况:

<div class="outer"><div class="inner">My Button</div></div>

div.outer也有“My Button”作为文本。为了解决这个问题,我尝试查看div.outer是否是div.inner的父元素,但我不知道如何做到这一点(element.get_element_by_xpath('..')返回元素的父元素,但它测试不等于div.outer)。

此外,遍历页面上的所有元素似乎真的很慢,至少使用Chrome web驱动程序是这样。

想法吗?


我在这里问了一个更具体的版本:如何在Selenium WebDriver中获取元素的文本,而不包括子元素文本?


您可以尝试这样的XPath表达式:

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

试试下面的方法:

driver.find_elements_by_xpath("//*[contains(text(), 'My Button')]")

试试这个。这很简单:

driver.getPageSource().contains("text to search");

在Selenium WebDriver中,这真的很管用。


你也可以在页面对象模式中使用它,例如:

试试下面的代码:

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

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"));

使用驱动程序。Find_elements_by_xpath和matches正则匹配函数,用于根据文本对元素进行不区分大小写的搜索。

driver.find_elements_by_xpath("//*[matches(.,'My Button', 'i')]")

//*将寻找任何HTML标记。如果一些文本是常见的按钮和div标签,如果//*是类别,它将无法正常工作。如果你需要选择任何特定的,那么你可以通过声明HTML元素标签来获得它。如:

driver.find_element_by_xpath("//div[contains(text(),'Add User')]")
driver.find_element_by_xpath("//button[contains(text(),'Add User')]")

类似的问题:查找<button>Advanced…</button>

也许这将给你一些想法(请将概念从Java转移到Python):

wait.until(ExpectedConditions.elementToBeClickable(//
    driver.findElements(By.tagName("button")).stream().filter(i -> i.getText().equals("Advanced...")).findFirst().get())).click();

在你提供的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>

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

You can use contains() function which determines whether the first argument string contains the second argument string and returns boolean true or false as follows: my_element = driver.find_element_by_xpath("//div[contains(., 'My Button')]") You can use normalize-space() function which strips leading and trailing white-space from a string, replaces sequences of whitespace characters by a single space, and returns the resulting string as follows: driver.find_element_by_xpath("//div[normalize-space()='My Button']]")


变量文本的XPath表达式

如果文本是一个变量,你可以使用:

foo= "foo_bar"
my_element = driver.find_element_by_xpath("//div[.='" + foo + "']")

简单地使用这个:

driver.find_elements_by_xpath('//*[text() = "My Button"]')

如果使用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");
}