当子元素与使用selenium的文本匹配时选择父-子元素

2024-10-17 11:33:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样的html:

<div class="card">
  <div>Foo</div>
  <a>View Item</a>
</div>
<div class="card">
  <div>Bar</div>
  <a>View Item</a>
</div>

我想选择卡片匹配“栏”并点击“查看项目”链接。我试过了

cards = browser.find_elements_by_class_name('card')
for card in cards:
  if card.find_element_by_partial_link_text('Bar'):
     item_anchor = card.find_element_by_partial_link_text('View Item')
     item_anchor.click()

但是我得到了一个错误:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"partial link text","selector":"Bar"}


Tags: textdivviewbylinkbarelementfind
3条回答
There are two ways to handle this situation based on your UI behavior:

1) If UI is fixed, use this xpath to identify and use click() to click on it.

//*[@class='card']/div[.='Bar']/following-sibling::a

2) If you are taking data from any external sources (like Database or Excel), pass your expected value (like Bar or Foo) as a parameter to the xpath method like below:

Define a class called Element like as below:

public class Element {

    private WebElement element;
    private WebDriver driver;
    private String xpath;

//  Constructor will wrap web element into Object and will allow to use any of the method declared below
    public Element(String xpath) {
        this.driver = new ChromeDriver();
        this.xpath = xpath;
        this.element = this.driver.findElement(By.xpath(this.xpath));
    }

    public void click() {
        this.element.click();
    }
}

Create POM class and write a methods like below:

public class PageObjectClass {

        private Element elementToClick(String value) {
            return new Element("//*[@class='card']/div[.='" + value + "']/following-sibling::a");
        }

        public void clickOnViewItemsLink(String value) {
            this.elementToClick(value).click();
        }
    }

By this way, you can click on any of View Item link just by passing value as a parameter

如果要单击BarView Item,可以直接使用以下xpath:

//div[text()='Bar']/following-sibling::a[text()='View Item']  

不过,引入webdriver wait对于稳定性来说是个不错的主意,正如@supputuri所提到的那样

尝试使用EC和下面的xpath。你知道吗

选项1:

检查链接是否存在,然后单击(如果要查找任何特定链接,可以在xpath中添加属性到link)

link =WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,"//div[@class='card' and div[normalize-space(.)='Bar']]/a")))
if (link):
    link.click()

选项2:

使用不同的xpath和len

links =WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.XPATH,"//div[@class='card']/div[normalize-space(.)='Bar']/following-sibling::a[normalize-space(.)='View Item']")))
if len(links)>0:
    links[0].click()

方案3:

如果您不确定在BA之间是否存在任何级别,可以使用下面的xpath。你知道吗

links =WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.XPATH,"//div[normalize-space(.)='Bar']/ancestor::div[@class='card']//a[normalize-space(.)='View Item']")))
if len(links)>0:
    links[0].click()

相关问题 更多 >