Ссылка на устаревший объект при навигации с использованием Selenium

Я пробовал простую программу, которая перемещается и получает данные с новой страницы, возвращается в историю и открывает другую страницу, получает данные и так далее, пока все ссылки не будут посещены и данные не будут выбраны.

После получения результатов на сайте ниже, я пытаюсь перебрать все ссылки, которые я получаю в первом столбце, открыть эти ссылки одну за другой и извлечь текст с каждой из этих страниц. Но приведенная ниже программа только посещает первую ссылку и дает исключение StaleElementReferenceException, которое я пытался использовать Actions но это не сработало, и я не знаю о JavascriptExecutor, Я также попробовал решения, опубликованные по другим вопросам SO, один из которых был моим здесь. Я хотел бы исправить ошибку в приведенном ниже коде и рабочем коде.

public class Selenium {

    private final static String CHROME_DRIVER = "C:\\Selenium\\chromedriver\\chromedriver.exe";
    private static WebDriver driver = null;
    private static WebDriverWait wait = null;

    private void setConnection() {
        try {
            System.setProperty("webdriver.chrome.driver", CHROME_DRIVER);
            driver = ChromeDriver.class.newInstance();
            wait = new WebDriverWait(driver, 5);
            driver.get("https://sanctionssearch.ofac.treas.gov");
            this.search();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void search() {
        try {
            driver.findElement(By.id("ctl00_MainContent_txtLastName")).sendKeys("Dawood");
            driver.findElement(By.id("ctl00_MainContent_btnSearch")).click();
            this.extractText();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void extractText() {
        try {
            List<WebElement> rows = driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr"));
            List<WebElement> links = null;
            for (int i = 1; i <= rows.size(); i++) {

                links = driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr/td[1]/a"));

                for (int j = 0; j < links.size(); j++) {
                    System.out.println(links.get(j).getText() + ", ");
                    links.get(j).click();
                    System.out.println("Afte click");
                    driver.findElement(By.id("ctl00_MainContent_btnBack")).click();
                    this.search();
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] ar) {
        Selenium object = new Selenium();
        object.setConnection();
    }

}

3 ответа

Пожалуйста, проверьте этот код

   private void extractText() {
        try {
            List<WebElement> rows = driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr"));
            List<WebElement> links = null;
            System.out.println(rows.size());
            for (int i = 0; i < rows.size(); i++) {
                links = driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr/td[1]/a"));
                WebElement ele= links.get(0);
                System.out.println(ele.getText() + ", ");
                ele.click();
                System.out.println("After click");
                driver.findElement(By.id("ctl00_MainContent_btnBack")).click();                     
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Причина, по которой вы получаете исключение StaleElementReference, обычно заключается в том, что вы сохранили элемент (ы) в некоторой переменной, однако после этого вы выполнили какое-то действие, и страница изменилась (из-за некоторого ответа ajax), и поэтому ваш сохраненный элемент стал устаревшим.

Лучшее решение - не хранить элемент в какой-либо переменной в таком случае.

Это должно работать.

links = driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr/td[1]/a"));

for (int j = 0; j < links.size(); j++) {
    System.out.println(links.get(j).getText() + ", ");
    driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr/td[1]/a")).get(j).click();
    System.out.println("Afte click");
    driver.findElement(By.id("ctl00_MainContent_btnBack")).click();
    this.search();
}

Как правило, мы получим исключение Stale, если атрибуты элемента или что-то изменилось после запуска webelement. Например, в некоторых случаях, если пользователь пытается щелкнуть по тому же элементу на той же странице, но после обновления страницы, появляется исключение staleelement.

Чтобы преодолеть это, мы можем создать новый веб-элемент на случай, если страница будет изменена или обновлена. Ниже код может дать вам некоторое представление.

Пример:

 webElement element = driver.findElement(by.xpath("//*[@id='Stackru']"));
 element.click();
 //page is refreshed
 element.click();//This will obviously throw stale exception

Чтобы преодолеть это, мы можем сохранить xpath в некоторой строке и использовать его для создания нового веб-элемента.

String xpath = "//*[@id='Stackru']";
driver.findElement(by.xpath(xpath)).click();
//page has been refreshed. Now create a new element and work on it
driver.fineElement(by.xpath(xpath)).click();   //This works

В этом случае мы собираем группу webelements и выполняем итерацию, чтобы получить текст. Но, кажется, в webelement произошли некоторые изменения после сбора webelement и gettext бросает устаревание. Мы можем использовать цикл и создать элемент на ходу и получить текст.

for(int i = 0; i<5; i++)
{
  String value = driver.findElement(by.xpath("//.....["+i+"]")).getText);
  System.out.println(value);
}

Надеюсь, это поможет вам. Благодарю.

Другие вопросы по тегам