Selenium 在遍历WebElement列表时获取StaleElementReferenceException

Selenium 在遍历WebElement列表时获取StaleElementReferenceException,selenium,selenium-webdriver,staleelementreferenceexception,Selenium,Selenium Webdriver,Staleelementreferenceexception,我试图自动化以下场景: 访问amazon.com 搜索耳机 将第一个结果页面中的所有畅销书添加到购物车 我按照以下步骤编写此场景的脚本: 访问amazon.com 在“搜索”字段中输入文本“耳机” 点击搜索按钮 单击标记为“畅销书”的链接 单击“添加到购物车”按钮 导航回结果页面 单击另一个标记为“畅销书”的链接 单击“添加到购物车”按钮 导航回结果页面 所有畅销书都有相同的xpath: //span[.='Best Seller']/../../../../../../../../follow

我试图自动化以下场景:

访问amazon.com 搜索耳机 将第一个结果页面中的所有畅销书添加到购物车 我按照以下步骤编写此场景的脚本:

访问amazon.com 在“搜索”字段中输入文本“耳机” 点击搜索按钮 单击标记为“畅销书”的链接 单击“添加到购物车”按钮 导航回结果页面 单击另一个标记为“畅销书”的链接 单击“添加到购物车”按钮 导航回结果页面 所有畅销书都有相同的xpath:

//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span
因此,我实现了以下WebElements列表:

List<WebElement> bestsellers = driver.findElements(By.xpath("xpath of bestsellers"));
for(WebElement product: bestsellers) {
    product.click();
    clickOnAddToCartButton();
    driver.navigate().back();
}



for(int i=0; i<bestsellers.size(); i++) {
        System.out.println(bestsellers.size());
        bestsellers.get(i).click();
        clickOnAddToCartButton();
        driver.navigate().back();

    }



Iterator<WebElement> i = bestsellers.iterator();
    while(i.hasNext()) {
        WebElement product = i.next();
        wait.until(ExpectedConditions.elementToBeClickable(product));

        product.click();
        clickOnAddToCartButton();
        driver.navigate().back();
    }
for(int i=0; i<bestsellers.size(); i++) {

        System.out.println("Current :" + i);
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span")));
        driver.findElements(By.xpath(".//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span")).get(i).click();
        clickOnAddToCartButton();
        //clickOnViewCart();
        try {
            wait.until(ExpectedConditions.elementToBeClickable(cartButton));
        }catch(TimeoutException e) {
            wait.until(ExpectedConditions.elementToBeClickable(viewCartButton));
        }
        if(i==(bestsellers.size()-1)) {
            try {
                wait.until(ExpectedConditions.elementToBeClickable(cartButton));    
                cartButton.click();
                break;
            }catch(TimeoutException e) {
                wait.until(ExpectedConditions.elementToBeClickable(viewCartButton));    
                viewCartButton.click();
                break;
            }
        }

        driver.navigate().back();
我通过以下3种方式实现了单击链接并使用循环添加到购物车:

List<WebElement> bestsellers = driver.findElements(By.xpath("xpath of bestsellers"));
for(WebElement product: bestsellers) {
    product.click();
    clickOnAddToCartButton();
    driver.navigate().back();
}



for(int i=0; i<bestsellers.size(); i++) {
        System.out.println(bestsellers.size());
        bestsellers.get(i).click();
        clickOnAddToCartButton();
        driver.navigate().back();

    }



Iterator<WebElement> i = bestsellers.iterator();
    while(i.hasNext()) {
        WebElement product = i.next();
        wait.until(ExpectedConditions.elementToBeClickable(product));

        product.click();
        clickOnAddToCartButton();
        driver.navigate().back();
    }
for(int i=0; i<bestsellers.size(); i++) {

        System.out.println("Current :" + i);
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span")));
        driver.findElements(By.xpath(".//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span")).get(i).click();
        clickOnAddToCartButton();
        //clickOnViewCart();
        try {
            wait.until(ExpectedConditions.elementToBeClickable(cartButton));
        }catch(TimeoutException e) {
            wait.until(ExpectedConditions.elementToBeClickable(viewCartButton));
        }
        if(i==(bestsellers.size()-1)) {
            try {
                wait.until(ExpectedConditions.elementToBeClickable(cartButton));    
                cartButton.click();
                break;
            }catch(TimeoutException e) {
                wait.until(ExpectedConditions.elementToBeClickable(viewCartButton));    
                viewCartButton.click();
                break;
            }
        }

        driver.navigate().back();
当我运行脚本时,畅销书列表中有3个元素。执行循环时,第一个元素被单击并添加到购物车中,驱动程序导航回结果页面。然后我使用上述3种方法得到staleElementReferenceException

更新: 我实现了如下场景:

for(int i=0; i<bestsellers.size(); i++) {

        System.out.println("Current :" + i);
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span")));
        driver.findElements(By.xpath(".//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span")).get(i).click();
        clickOnAddToCartButton();
        //clickOnViewCart();
        try {
            wait.until(ExpectedConditions.elementToBeClickable(cartButton));
        }catch(TimeoutException e) {
            wait.until(ExpectedConditions.elementToBeClickable(viewCartButton));
        }
        if(i==(bestsellers.size()-1)) {
            try {
                wait.until(ExpectedConditions.elementToBeClickable(cartButton));    
                cartButton.click();
                break;
            }catch(TimeoutException e) {
                wait.until(ExpectedConditions.elementToBeClickable(viewCartButton));    
                viewCartButton.click();
                break;
            }
        }

        driver.navigate().back();

当您在浏览器中单击元素或返回时,元素引用将在selenium中更新,因此您无法指向具有旧引用的元素,这导致了StatleElementException

当您必须迭代多个元素交互时,请考虑这种方法

List<WebElement> bestsellers = driver.findElements(By.xpath("xpath of bestsellers"));
for(int i=0; i<bestsellers.size(); i++) {
    System.out.println("Current Seller " + i);
    // here you are getting the elements each time you iterate, which will get the
    // latest element references
    driver.findElements(By.xpath("xpath of bestsellers")).get(i).click();
    clickOnAddToCartButton();
    driver.navigate().back();

}

driver.navigate.back;-这将刷新导致此staleElementReferenceException.ok的页面上的元素。谢谢你的信息。你能给我推荐一个解决方案吗?我应该打开链接新标签并在我完成它的时候关闭标签吗?这样,我可以在不刷新元素的情况下返回结果页面。你可以考虑将HRIFS URL存储到列表中的单个产品中,然后导航到HRFS,点击添加到购物车,导航下一个HREF,等等…尝试了上面的代码。当页面中有4本畅销书时,只有2本畅销书添加到购物车中。它将进入所有4个畅销书产品页面,但只有2个被添加到购物车中。请尝试使用'driver.findElementsBy.xpathxpath of bestsellers.get0.click;`只需将i替换为0,以便始终添加第一个项目。否,我要添加第一页中的所有畅销书项目。单击“添加到购物车”后,将显示“转到购物车”和“继续签出”选项。我一直在等待他们确认是否单击了“添加到购物车”,否则我就会知道问题所在。成功了。我已经更新了问题中的代码