【问题标题】:Getting StaleElementReferenceException while trying print the link names尝试打印链接名称时出现 StaleElementReferenceException
【发布时间】:2017-12-11 17:57:19
【问题描述】:

我正在尝试打印 google 搜索中显示的前 5 页链接。但收到 StateElementReferenceException 不确定哪个出错了。

    public class GoogleCoInTest {

    static WebDriver driver = null;
    public static void main(String[] args) throws InterruptedException {
        System.setProperty("webdriver.gecko.driver", "D:\\bala back up\\personel\\selenium\\Jars\\Drivers\\geckodriver.exe");
        driver=new FirefoxDriver();
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        driver.get("https://www.google.co.in/");
        //driver.findElement(By.xpath("//input[class='gsfi']")).sendKeys("Banduchode");;
        WebElement search=driver.findElement(By.cssSelector("input#lst-ib"));
        search.sendKeys("Banduchode");
        search.sendKeys(Keys.ENTER);
        printLinksName();
        List<WebElement> fiveLinks=driver.findElements(By.xpath(".//*[@id='nav']/tbody/tr/td/a"));


        for(int i=0;i<5;i++){
            System.out.println(fiveLinks.get(i).getText());
            fiveLinks.get(i).click();
            Thread.sleep(5000);
            printLinksName();


        }
    }   


    public static void printLinksName() throws InterruptedException{

        List<WebElement> allLinks=driver.findElements(By.xpath("//*[@id='rso']/div/div/div/div/div/h3/a"));
        System.out.println(allLinks.size()); 

        //print all list        
        for(int i=0;i<allLinks.size();i++){
            System.out.println("Sno"+(i+1)+":"+allLinks.get(i).getText());

        }   
    }
}

它打印到第 2 页都很好,但是在我得到之后就在那里

Exception in thread "main" org.openqa.selenium.StaleElementReferenceException: The element reference of <a class="fl"> stale: either the element is no longer attached to the DOM or the page has been refreshed
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html

【问题讨论】:

    标签: java selenium selenium-webdriver staleelementreferenceexception


    【解决方案1】:

    有几点:

    1. 您的脚本按预期打印前 2 页的结果。
    2. 当您第一次调用 printLinksName() 时,它会起作用。
    3. 接下来,您将这 10 个页码存储在类型为 WebElementGeneric List 中。
    4. 第一次在for() 循环中单击Page 2WebElement,然后调用printLinksName() 打印所有链接。
    5. 当您在for() 循环中进行第二次迭代时,List&lt;WebElement&gt; fiveLinks 的引用会随着 DOM 的变化而丢失。因此,您会看到 StaleElementReferenceException

    解决方案

    避免 StaleElementReferenceException 的简单解决方案是在 for() 循环中移动代码行 List&lt;WebElement&gt; fiveLinks=driver.findElements(By.xpath(".//*[@id='nav']/tbody/tr/td/a")); 。所以你的代码块看起来像:

        import java.util.List;
        import java.util.concurrent.TimeUnit;
    
        import org.openqa.selenium.By;
        import org.openqa.selenium.Keys;
        import org.openqa.selenium.WebDriver;
        import org.openqa.selenium.WebElement;
        import org.openqa.selenium.firefox.FirefoxDriver;
    
        public class Q44970712_stale 
        {
    
            static WebDriver driver = null;
    
            public static void main(String[] args)  throws InterruptedException
            {
            System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
            driver=new FirefoxDriver();
            driver.manage().window().maximize();
            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
            driver.get("https://www.google.co.in/");
            //driver.findElement(By.xpath("//input[class='gsfi']")).sendKeys("Banduchode");;
            WebElement search=driver.findElement(By.cssSelector("input#lst-ib"));
            search.sendKeys("Banduchode");
            search.sendKeys(Keys.ENTER);
            printLinksName();
    
    
    
            for(int i=0;i<5;i++)
            {
                List<WebElement> fiveLinks=driver.findElements(By.xpath(".//*[@id='nav']/tbody/tr/td/a"));
                System.out.println(fiveLinks.get(i).getText());
                fiveLinks.get(i).click();
                Thread.sleep(5000);
                printLinksName();
            }
            }
    
            public static void printLinksName() throws InterruptedException
            {
                List<WebElement> allLinks=driver.findElements(By.xpath("//*[@id='rso']/div/div/div/div/div/h3/a"));
                System.out.println(allLinks.size()); 
    
                //print all list        
                for(int i=0;i<allLinks.size();i++)
                {
                System.out.println("Sno"+(i+1)+":"+allLinks.get(i).getText());
    
                }   
            }
    
        }
    

    注意:在这个简单的解决方案中,当您完成第二页的打印后,接下来您将第二次使用.//*[@id='nav']/tbody/tr/td/a 创建List&lt;WebElement&gt; fiveLinksxpathPage 1 是第一个存储在fiveLinks 列表中的元素。因此,您可能会再次被重定向到 Page 1。为避免这种情况,您可以考虑通过正确的索引来帮助 xpath

    【讨论】:

    • 感谢@DebanjanB,阐述得很好
    【解决方案2】:

    这是由于在移动到另一个页面后引用了对象。请尝试在最后的 for 循环中添加以下行。它可能会解决过时的引用问题。

        driver.navigate().back();
        fiveLinks=driver.findElements(By.xpath(".//*[@id='nav']/tbody/tr/td/a"));
    

    【讨论】:

    • 谢谢穆尔蒂。这适用于我的代码。我唯一的问题是为什么我们每次都应该返回..我们不能通过任何继承方式继续下一页..就像我想像 1->2->3 一样。但在这种情况下,代码会像 1->2->1->3->1->4
    【解决方案3】:

    您的脚本正在尝试单击第一页中的每个链接,这会将您带到一个新页面。完成该页面上的工作后,它似乎不会返回到第一页,因此脚本无法在您的列表中找到下一个链接。

    即使它确实返回了第一页,您仍然会有一个陈旧的元素,因为该页面已被重新加载。您需要通过其他方式(比如可能的 href?)跟踪第一页中的链接,并在单击之前通过该标识符再次找到该链接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多