Получение StaleElementReferenceException при попытке напечатать имена ссылок

Я пытаюсь напечатать первые 5 страниц ссылок, отображаемых в поиске Google.. Но получаю 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

3 ответа

Решение

Вот ответ на ваш вопрос:

  1. Ваш скрипт печатает результат с первых 2 страниц, как и ожидалось.
  2. Когда вы звоните printLinksName() в первый раз это работает.
  3. Затем вы сохраняете 10 PageNumbers в Generic List типа WebElement,
  4. Первый раз в for() цикл вы нажимаете на WebElement из Page 2 а затем распечатать все ссылки по телефону 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());

            }   
        }

    }

Примечание: в этом простом решении, когда вы закончите печатать вторую страницу, затем, когда вы создадите List<WebElement> fiveLinks через xpath с .//*[@id='nav']/tbody/tr/td/a во второй раз, Page 1 это первый элемент, который хранится в fiveLinks Список. Следовательно, вы можете быть снова перенаправлены на Page 1, Чтобы избежать этого, вы можете воспользоваться помощью xpath с правильной индексацией.

Дайте мне знать, если это отвечает на ваш вопрос.

Ваш скрипт пытается нажать на каждую ссылку с первой страницы, которая приводит вас на новую страницу. По завершении работы на этой странице он, похоже, не возвращается на первую страницу, поэтому сценарий не может найти следующую ссылку в вашем списке.

даже если он вернется на первую страницу, у вас все равно будет устаревший элемент, потому что страница была перезагружена. Вам нужно будет отслеживать ссылки на первой странице с помощью чего-то еще (например, href возможно?) И снова найти ссылку по этому идентификатору, прежде чем щелкнуть по ней.

Это связано с ссылкой на объект после перехода на другую страницу. пожалуйста, попробуйте добавить следующие строки внутри цикла for в конце. Это может решить проблему устаревших ссылок.

    driver.navigate().back();
    fiveLinks=driver.findElements(By.xpath(".//*[@id='nav']/tbody/tr/td/a"));
Другие вопросы по тегам