尝试打印 link 名称时获取 StaleElementReferenceException

Getting StaleElementReferenceException while trying print the link names

我正在尝试打印 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

您的脚本试图点击第一页中的每个 link,这会将您带到一个新页面。一旦完成该页面上的工作,它似乎不会 return 到第一页,因此脚本无法在您的列表中找到下一个 link。

即使它对第一页做了 return,您仍然会有一个过时的元素,因为该页面已重新加载。您需要通过其他方式(例如 href ?)跟踪第一页中的 link,并在单击它之前通过该标识符再次找到 link。

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

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

几件事:

  1. 您的脚本按预期打印前 2 页的结果。
  2. 当您第一次调用 printLinksName() 时,它会起作用。
  3. 接下来,您将 10 个 PageNumbers 存储在类型为 WebElementGeneric List 中。
  4. 第一次在 for() 循环中单击 Page 2WebElement,然后通过调用 [=打印所有链接 printLinksName().
  5. 当您处于 for() 循环中的第二次迭代时,List<WebElement> fiveLinks 的引用丢失,因为 DOM 已更改。因此,您看到 StaleElementReferenceException.

解决方案

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

    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());

            }   
        }

    }

Note: In this simple solution when you finish printing the second page, next when you will create List<WebElement> fiveLinks through xpath with .//*[@id='nav']/tbody/tr/td/a for second time, Page 1 is the first element which gets stored in the fiveLinks List. Hence you may be again redirected to Page 1. To avoid that you may consider to take help of xpath with proper indexing.