Ссылка на устаревший объект при навигации с использованием 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);
}
Надеюсь, это поможет вам. Благодарю.