【问题标题】:selenium stale element when traversing pages using for-each loop使用 for-each 循环遍历页面时的 selenium stale 元素
【发布时间】:2013-09-04 07:53:14
【问题描述】:

我一直在尝试制作一个与网站交互的小程序(更准确地说是浏览器游戏),从不同页面获取一些信息并将其打印到 GUI。

我的打印工作正常,我可以毫无问题地登录并浏览网站。但是当我尝试获取我需要的数据(使用 for-each 循环完成)时,selenium 不断抛出“元素似乎是陈旧的”错误并终止应用程序。

我从第一个星球上得到了数据,但这就是它结束的地方。这是sn-p的代码:

public void getResources()
    {
        List<WebElement> planets = driver.findElements(By.className("smallplanet"));
        String name;
        int metal;
        int crystal;
        int deuterium;
        int energy;
        boolean firstPlanet = true;

        for(WebElement planet : planets)
        {       
            if(!firstPlanet)
            {
                WebElement tag = planet.findElement(By.tagName("a"));
                tag.click();
            } else
            {
                firstPlanet = false;
            }

            name = planet.findElement(By.className("planet-name")).getText();
            System.out.println(name);
            metal = Integer.parseInt(driver.findElement(By.id("resources_metal")).getText().replace(".", ""));
            crystal = Integer.parseInt(driver.findElement(By.id("resources_crystal")).getText().replace(".", ""));
            deuterium = Integer.parseInt(driver.findElement(By.id("resources_deuterium")).getText().replace(".", ""));
            energy = Integer.parseInt(driver.findElement(By.id("resources_energy")).getText().replace(".", ""));        

            resources.add(new ResourceLine(name, metal, crystal, deuterium, energy));
        }
    }

这是错误:

Element appears to be stale. Did you navigate away from the page that contained it?  And is the current window focussed the same as the one holding this element?
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01'
System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_03'
Driver info: driver.version: HtmlUnitDriver

我认为这可能是因为 selenium 没有足够的时间来加载页面?但我认为硒在等待页面下载完成时停止了 EDT? 我知道它在我登录时会这样做,因为我的 UI 目前正在同一个线程上运行,并且在 selenium 完成加载页面之前它不会更新。

在任何情况下,我都尝试使用 Thread.sleep() 和 driver.wait,长度在 50 到 500 之间,但似乎都没有任何效果。

(注意:我已经为 HtmlUnitDriver 启用了 javascript)

编辑:我一直在调试更多,现在我可以确认这不是因为 selenium 没有足够的时间来加载页面。该程序确实等待新页面加载,但由于某种奇怪的原因它仍然抛出该异常......

另一个编辑:

我现在将每个 findElement 语句包装在一个 while 循环中,只要抛出异常,该循环就会继续执行相同的 try-catch 块。 但这只是一个无限循环,不断抛出相同的陈旧元素异常。

我可能还想补充一点,该页面确实是“自我刷新”的。例如,我尝试检索的值每 500 毫秒左右更新一次。

【问题讨论】:

    标签: java javascript selenium


    【解决方案1】:

    您正在收到 StaleElementReferenceException。这通常发生在您第一次成功定位 WebElement 然后您

    • 重新加载页面或导航到其他页面并返回或
    • 使用 Selenium 执行了一些导致 DOM 发生变化的操作

    您仍然尝试与该元素进行交互。后者似乎是你的问题。您正在代码中执行tag.click()。我现在不知道它做了什么,但我想它会导致一些数据出现?这会导致 DOM 发生变化,因此您无法引用单击之前定位的元素。每次调用 tag.click() 后,您可能都需要查找行星列表。 (这只是我的猜测,因为您没有写错误发生在哪一行)

    WebElement planet;
    int size = driver.findElements(By.className("smallplanet")).size();
    for(int i=0; i < size; i++)
    {           
        if(!firstPlanet)
        {
            planet = driver.findElements(By.className("smallplanet")).get(i);
            WebElement tag = planet.findElement(By.tagName("a"));
            tag.click();
            planet = driver.findElements(By.className("smallplanet")).get(i);
    
        } else
        {
            firstPlanet = false;
            planet = driver.findElements(By.className("smallplanet")).get(i);
        }
        //rest of the code...
    }
    

    【讨论】:

    • 我已经在 for 循环中使用 driver.findElement(By...) 的任何行查明了错误。每个页面看起来都相同,具有相同的项目只是不同的值。所以这个想法是: - 从第一个星球获取资源 - 去下一个星球 - 获取资源 - 去下一个星球 - 冲洗,重复。所以实际的行星名称(行星列表中的那个)永远不会改变。但它确实给了我一个想法。
    • 页面看起来如何并不重要。它们的 HTML 可能完全相同。但它们是不同的页面,不同的 DOM。所以很自然你会得到这个异常。
    • 原来你一直都是对的......更改了代码,所以它现在在每个 tag.click() 之后“刷新”行星列表(基本上就像你说的那样),它就像一个魅力!感谢您的帮助:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多