Selenium:遍历一组元素时如何避免StaleElementReferenceException? [英] Selenium: How to avoid StaleElementReferenceException when looping through a set of elements?

查看:260
本文介绍了Selenium:遍历一组元素时如何避免StaleElementReferenceException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含一堆桌子的页面.我在外部循环中遍历表,然后在内部循环中遍历表中的每一行.一切正常.但是某些页面具有下一步"按钮.当我在完成页面后添加代码以单击该代码时,然后在遍历表的各行时开始获取StaleElementReferenceException.

I have a page that contains a bunch of tables. I loop through the tables in the outer loop and then loop through each row in the table in the inner loop. It all works fine. But some of the pages have a Next button. When I add code to click that after completing the page, then I start getting StaleElementReferenceException while looping through the rows of a table.

这是代码:

WebDriverWait wait1 = new WebDriverWait(driver, 10000);
WebElement maxPage = null;
WebElement auctionsWaitingDiv = driver.findElement(By.cssSelector("div[class='Head_W']"));
if (auctionsWaitingDiv.isDisplayed() == false) return properties;

try {
    maxPage = wait1.until(ExpectedConditions.visibilityOfElementLocated(By.id("maxWA")));
} catch (TimeoutException ex) {
    return properties;
}

Integer maxPageNo = 1;
if (!maxPage.getText().isEmpty()) 
    maxPageNo = Integer.parseInt(maxPage.getText());
for (int i = 1; i <= maxPageNo; i++) {
    driver.findElement(By.cssSelector("div[id='Area_W']"));    //only look at Auctions Waiting section
    WebDriverWait wait2 = new WebDriverWait(driver, 10000);
    List<WebElement> tables = null;
    try {
        tables = wait2.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("table[class='ad_tab']")));
    } catch (TimeoutException ex) {
        System.out.println("table not found in allotted time");
        return properties;
    } catch (StaleElementReferenceException ex) {
        System.out.println("returning due to StaleElementReferenceException");
        return properties;

    }
    for (WebElement table: tables) {  
        List<String> propAttributes = new ArrayList<>();

        // StaleElementReferenceException: The element reference of
        // <table class="ad_tab"> is stale; either the element is no
        // longer attached to the DOM, it is not in the current
        // frame context, or the document has been refreshed
        List<WebElement> rows = table.findElements(By.cssSelector("tr"));

        String parcelLink = "";
        for (WebElement row : rows) { 
            WebElement key = row.findElement(By.cssSelector("th"));
            WebElement val = row.findElement(By.cssSelector("td"));
            String keyVal = key.getText() + val.getText();
            propAttributes.add(keyVal);
            if (key.getText().equals("Parcel ID:")) {
                WebElement a = val.findElement(By.cssSelector("a"));
                parcelLink = a.getAttribute("href");
            }
        }
    }
    driver.findElement(By.xpath(".//*[@class='PageRight']")).click();  //click the "Next" button
}

我不明白的是,为什么过时的因素根本没有发生?该页面在循环过程中没有改变,我一直等到所有元素都被取走.如何避免StaleElementReferenceException?

What I don't understand is why the stale element is happening at all? The page is not changing during the loop and I've waited until all elements have been fetched. How to avoid the StaleElementReferenceException?

最后的堆栈跟踪显示此行正在发生:

The last stack trace shows it is happening in this line:

List<WebElement> rows = table.findElements(By.cssSelector("tr"));

及其上面的错误消息显示:

and the error message above it shows:

严重:空

org.openqa.selenium.StaleElementReferenceException:<table class="ad_tab">的元素引用是陈旧的;要么该元素不再附加到DOM,不在当前框架上下文中,要么文档已刷新

org.openqa.selenium.StaleElementReferenceException: The element reference of <table class="ad_tab"> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed

推荐答案

好了一天,我把头发扯了一下之后,我终于意识到发生了什么事.对我来说应该是显而易见的.单击下一步"按钮时,加载新页面需要一些时间.通过简单地添加一个延迟,就可以加载新的DOM并开始对其进行处理,而不是在上一个DOM上再次处理!

Well after tearing my hair out for a day, I finally realized what was happening. It should have been obvious to me. When the "Next" button is clicked, it takes some time for the new page to load. By simply adding a delay, the new DOM is loaded and processing begins on it, not again on the previous one!

            driver.findElement(By.xpath(".//*[@class='PageRight']")).click();
        try {
            Thread.sleep(4000); //provide some time for the page to load before processing it
        } catch (InterruptedException ex) {
            Logger.getLogger(RealAuction.class.getName()).log(Level.SEVERE, null, ex);
        }

现在它可以运行到没有StaleElementReferenceException的状态了.

Now it runs to completion with no StaleElementReferenceException.

这篇关于Selenium:遍历一组元素时如何避免StaleElementReferenceException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆