You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

循环执行Selenium代码触发StaleElementReferenceException异常求助

解决Selenium的StaleElementReferenceException问题

问题原因

你碰到的StaleElementReferenceException,本质是页面导航后,之前获取的WebElement已经和当前页面的DOM树完全脱离了。具体来说:

  • 初始循环依赖的listofItems是第一次加载商品页时获取的元素列表
  • 当你调用driver.navigate().to("https://www.saucedemo.com/inventory.html")回到商品页后,页面DOM已经重新渲染,之前的product元素早已失效,再调用product.click()必然触发错误
  • 你在循环里重新获取了listofItems,但循环迭代的还是最初的旧列表,新获取的元素根本没被用到,等于做了无用功

修复方案

别直接循环WebElement列表,改成先收集所有商品按钮的唯一标识(比如id),存储成字符串列表,再循环这个字符串列表——每次循环都通过id重新定位元素,确保操作的是当前页面的有效元素。

另外你的代码里每次循环都固定点击sauce-labs-fleece-jacket的加入购物车按钮,这明显是多余操作,建议删掉。

修改后的代码

// 先收集所有商品按钮的id,存成字符串列表
List<String> itemIds = new ArrayList<>();
List<WebElement> initialItems = driver.findElements(By.xpath("//button[starts-with(@id,'add-to-cart-')]"));
for (WebElement item : initialItems) {
    itemIds.add(item.getAttribute("id"));
}

// 循环id列表,每次重新定位当前页面的元素
for (String itemId : itemIds) {
    // 回到商品页后,重新定位要操作的按钮
    WebElement product = driver.findElement(By.id(itemId));
    product.click();
    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

    // 进入购物车并发起结算
    driver.findElement(By.xpath("//*[contains(@class, 'shopping_cart_container')]")).click(); 
    driver.findElement(By.xpath("//button[@id='checkout']")).click(); 

    CadastraComprador("joao", "costa", "35510");
    driver.findElement(By.xpath("//*[contains(@class, 'submit-button btn btn_primary cart_button btn_action')]")).click();

    comparaPrecoTotal("Item total: $65.98");
    buttonFinish.click();
    
    // 回到商品页,准备下一次循环
    driver.navigate().to("https://www.saucedemo.com/inventory.html");
}

额外优化建议

  • 隐式等待只需提前设置一次,不用每次循环重复配置
  • 优先用id定位元素,比xpath更稳定高效
  • 如果结算总价和当前商品挂钩,comparaPrecoTotal方法要根据商品动态调整预期值,不然固定用$65.98会出现校验错误

内容的提问来源于stack exchange,提问作者joao victor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 03:47:43