【问题标题】:iterating through links in a footer section of a web page Selenium Java [duplicate]遍历网页页脚部分中的链接 Selenium Java [重复]
【发布时间】:2019-12-02 15:38:56
【问题描述】:

我正在尝试遍历页脚部分中的链接。我已经编写了这段代码,但它一直失败。我希望有人能够告诉我我做错了什么以及如何解决这个问题。

import java.awt.List;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;



import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class HomeWork {

public static void main(String[] args) throws InterruptedException {
    System.setProperty("webdriver.chrome.driver", "C:\\Work\\chromedriver_win32\\chromedriver.exe");
    WebDriver driver = new ChromeDriver();

    driver.manage().window().maximize();
    driver.manage().deleteAllCookies();
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);

    String url = "http://automationpractice.com/index.php?controller=authentication&back=my-account";
    driver.get(url);



    WebElement infoLinkSec = driver.findElement(By.xpath("//*[@id=\"block_various_links_footer\"]"));
    int noOfLink = infoLinkSec.findElements(By.tagName("a")).size();
    System.out.println(noOfLink);


    Iterator<WebElement> links = infoLinkSec.findElements(By.tagName("a")).iterator();





    WebElement[] link = new WebElement[noOfLink];


    for (int i = 0; i< noOfLink; i++ ) {
        link[i] = links.next();
            }


    for (int i = 0; i< noOfLink; i++ ) {

        link[i].click();
        Thread.sleep(2000L);

        String cUrl = driver.getCurrentUrl();
        String cPageTitle = driver.getTitle();
        System.out.println((i+1) +". The current url is "+cUrl+"\nThe current page title is "+cPageTitle);

        driver.navigate().back();
        driver.navigate().refresh();
        Thread.sleep(3000L);
        }


}

    }

当我尝试使用打开任何链接时 链接[3].click();或链接[4].click(); 它会打开链接, 问题似乎是当我们返回并刷新时,它会打开另一个链接。

错误是:

Starting ChromeDriver 78.0.3904.70         (edb9c9f3de0247fd912a77b7f6cae7447f6d3ad5-refs/branch-    heads/3904@{#800}) on port 5525
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test     frameworks to prevent access by malicious code.
[1575300793.350][WARNING]: Timed out connecting to Chrome,     retrying...
Dec 02, 2019 10:33:15 AM     org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
[1575300797.392][WARNING]: Timed out connecting to Chrome,     retrying...
8
1. The current url is     http://automationpractice.com/index.php?controller=prices-drop
The current page title is Prices drop - My Store
Exception in thread "main"     org.openqa.selenium.StaleElementReferenceException: stale     element reference: element is not attached to the page     document
  (Session info: chrome=78.0.3904.108)
For documentation on this error, please visit:     https://www.seleniumhq.org/exceptions/stale_element_reference.    html
Build info: version: '3.141.59', revision: 'e82be7d358',     time: '2018-11-14T08:25:48'
System info: host: 'LAPTOP-P9CFNEOV', ip: '192.168.56.1',     os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0',     java.version: '1.8.0_222'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName:     chrome, browserVersion: 78.0.3904.108, chrome:     {chromedriverVersion: 78.0.3904.70 (edb9c9f3de024...,     userDataDir: C:\Users\YSAMSE~1\AppData\L...},     goog:chromeOptions: {debuggerAddress: localhost:54615},     javascriptEnabled: true, networkConnectionEnabled: false,     pageLoadStrategy: normal, platform: XP, platformName: XP,     proxy: Proxy(), setWindowRect: true,     strictFileInteractability: false, timeouts: {implicit: 0,     pageLoad: 300000, script: 30000}, unhandledPromptBehavior:     dismiss and notify}
Session ID: 2377347e6ccb38499c3f86e0b8cc0862
    at     sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native     Method)
    at     sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeCo    nstructorAccessorImpl.java:62)
    at     sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Dele    gatingConstructorAccessorImpl.java:45)
    at     java.lang.reflect.Constructor.newInstance(Constructor.java:423    )
    at     org.openqa.selenium.remote.http.W3CHttpResponseCodec.createExc    eption(W3CHttpResponseCodec.java:187)
    at     org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3    CHttpResponseCodec.java:122)
at     org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3    CHttpResponseCodec.java:49)
    at     org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCom    mandExecutor.java:158)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execu    te(DriverCommandExecutor.java:83)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:285)
at org.openqa.selenium.remote.RemoteWebElement.click(RemoteWebElement.java:84)
at HomeWork.main(HomeWork.java:50)

【问题讨论】:

    标签: java selenium selenium-webdriver automated-tests selenium-chromedriver


    【解决方案1】:

    所以,您似乎在这里收到了StaleElementReferenceException。您说“问题似乎出在我们返回并刷新时”,这是完全正确的 - 这就是您遇到此异常的方式。

    当您找到WebElementWebElement 列表并将其存储在变量中,然后更改页面(通过刷新或转到其他页面)时,您对该元素的引用不再有效。您的变量指向一个已过时的元素。

    刷新页面后,重新查找与您交互的所有元素,可以解决此问题。

    所以,在driver.navigate.refresh(); 之后,link[i].click() 将抛出异常,因为link[] 现在包含在页面上不再有效的元素列表。您需要重新调用 driver.findElements 以将 link[] 设置回新元素的状态。

    您设置link[] 变量的代码在这里似乎有点复杂,所以它并不像刷新后调用driver.findElements 那样简单。您可能需要重构代码,以便在每次刷新后轻松找到一组新链接:

    System.setProperty("webdriver.chrome.driver", "C:\\Work\\chromedriver_win32\\chromedriver.exe");
    WebDriver driver = new ChromeDriver();
    
    driver.manage().window().maximize();
    driver.manage().deleteAllCookies();
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    
    String url = "http://automationpractice.com/index.php?controller=authentication&amp;back=my-account";
    driver.get(url);
    
    // get the links
    List<WebElement> links = driver.findElement(By.xpath("//*[@id='block_various_links_footer']//a"));
    
    // iterate links in a for loop
    for (int i = 0; i < links.size(); i++)
    {
        // click the link
        link[i].click();
        Thread.sleep(2000L);
    
        // print page info
        String cUrl = driver.getCurrentUrl();
        String cPageTitle = driver.getTitle();
        System.out.println((i+1) +". The current url is "+cUrl+"\nThe current page title is "+cPageTitle);
    
        // go back
        driver.navigate().back();
        driver.navigate().refresh();
        Thread.sleep(3000L);
    
        // re-find links list
        List<WebElement> links = driver.findElement(By.xpath("//*[@id='block_various_links_footer']//a"));
    }
    

    Selenium 在堆栈跟踪中的StaleElementReferenceException 上为您提供了指向their documentation 的有用链接。如果您特别好奇,可以在他们的页面上阅读更多内容。

    【讨论】:

    • 嗨,克里斯汀;非常感谢您的帮助,我非常感谢您为帮助我所付出的时间和精力。克里斯汀,我按照你的建议重写了代码,但我仍然遇到同样的错误。您是否认为 iterator() 可能不是单击链接的最佳方式,如果您要这样做,您的方法会是什么样子。谢谢你,非常感谢你的帮助。
    • @YSamKabir 我已经用您的代码的简化版本更新了答案。这是在 C# 中测试的,但转换为 Java,功能应该是相同的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    • 2022-08-19
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 2013-10-27
    • 2012-01-15
    相关资源
    最近更新 更多