如何将WebDriver重定向到新页面并返回每个找到的链接,避免StaleElementReferenceException?

时间:2022-01-02 01:00:44

So, the simplest example would be fetching data from google search engine results.

因此,最简单的示例是从谷歌搜索引擎结果中获取数据。

Example code:

void test() {

    WebDriver driver = new FirefoxDriver();

    driver.get("https://www.google.com");

    driver.findElement(By.id("lst-ib")).sendKeys("pizza"); // type pizza in search field

    driver.findElement(By.name("btnK")).click(); // perform search

    // for every header link in search results page
    for(WebElement link : driver.findElements(By.xpath("//h3[@class = 'r']/a"))) {

        link.click(); // click the link

        System.out.println(driver.getCurrentUrl()); // fetch page url or something else

        driver.navigate().back(); // go back to search results

    }
}

But, on second iteration, exception is thrown:

但是,在第二次迭代时,抛出异常:

Exception in thread "main" org.openqa.selenium.StaleElementReferenceException: The element reference of stale: either the element is no longer attached to the DOM or the page has been refreshed

线程“main”中的异常org.openqa.selenium.StaleElementReferenceException:陈旧的元素引用:元素不再附加到DOM或页面已刷新

That's because the remaining links are invalidated the moment i click one of them. How can somehow iterate over them all for this task?

那是因为当我点击其中一个时,剩下的链接就会失效。怎么能以某种方式迭代他们所有这一任务?

2 个解决方案

#1


1  

You can use for loop with index for this and relocate the list each iteration

您可以为此使用带索引的循环,并在每次迭代时重新定位列表

int count = 1;
for (int i = 0 ; i < count ; i++) {
    List<WebElement> links = driver.findElements(By.xpath("//h3[@class = 'r']/a"))
    count = links.size();
    link.get(i).click(); // click the link
    System.out.println(driver.getCurrentUrl()); // fetch page url or something else
    driver.navigate().back(); // go back to search results
}

#2


1  

As per your code block to avoid StaleElementReferenceException I would suggest a change in the approach as follows :

根据你的代码块来避免StaleElementReferenceException我建议改变方法如下:

  • Create a List out of your search results, extract the href attribute and strore them in a new List.
  • 从搜索结果中创建一个列表,提取href属性并在新列表中对它们进行处理。

  • Open each href in a new TAB, switch to the newly opened TAB and perform the required operations.
  • 在新TAB中打开每个href,切换到新打开的TAB并执行所需的操作。

  • Once you complete the operations on the new tab, Close the TAB and switch back to the main TAB.
  • 完成新选项卡上的操作后,关闭TAB并切换回主TAB。

  • Here is the sample code block to perform the above mentions steps :

    以下是执行上述提及步骤的示例代码块:

    List <WebElement> my_list = driver.findElements(By.xpath("//div[@id='rso']//div[@class='srg']/div[@class='g']//h3/a"));
    ArrayList<String> href_list = new ArrayList<String>();
    for(WebElement element:my_list)
        href_list.add(element.getAttribute("href"));
    for(String myhref:href_list)
    {
        ((JavascriptExecutor) driver).executeScript("window.open(arguments[0])", myhref); 
        //switch to the required TAB, perform the operations, close and switch back to main TAB
        //For demonstration I didn't switch/close any of the TABS
    }
    

#1


1  

You can use for loop with index for this and relocate the list each iteration

您可以为此使用带索引的循环,并在每次迭代时重新定位列表

int count = 1;
for (int i = 0 ; i < count ; i++) {
    List<WebElement> links = driver.findElements(By.xpath("//h3[@class = 'r']/a"))
    count = links.size();
    link.get(i).click(); // click the link
    System.out.println(driver.getCurrentUrl()); // fetch page url or something else
    driver.navigate().back(); // go back to search results
}

#2


1  

As per your code block to avoid StaleElementReferenceException I would suggest a change in the approach as follows :

根据你的代码块来避免StaleElementReferenceException我建议改变方法如下:

  • Create a List out of your search results, extract the href attribute and strore them in a new List.
  • 从搜索结果中创建一个列表,提取href属性并在新列表中对它们进行处理。

  • Open each href in a new TAB, switch to the newly opened TAB and perform the required operations.
  • 在新TAB中打开每个href,切换到新打开的TAB并执行所需的操作。

  • Once you complete the operations on the new tab, Close the TAB and switch back to the main TAB.
  • 完成新选项卡上的操作后,关闭TAB并切换回主TAB。

  • Here is the sample code block to perform the above mentions steps :

    以下是执行上述提及步骤的示例代码块:

    List <WebElement> my_list = driver.findElements(By.xpath("//div[@id='rso']//div[@class='srg']/div[@class='g']//h3/a"));
    ArrayList<String> href_list = new ArrayList<String>();
    for(WebElement element:my_list)
        href_list.add(element.getAttribute("href"));
    for(String myhref:href_list)
    {
        ((JavascriptExecutor) driver).executeScript("window.open(arguments[0])", myhref); 
        //switch to the required TAB, perform the operations, close and switch back to main TAB
        //For demonstration I didn't switch/close any of the TABS
    }