V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tiRolin
V2EX  ›  Java

Java +Selenium 框架获取元素时报 StaleElementReferenceException: stale element reference: stale element not found

  •  
  •   tiRolin · 2023-07-12 14:08:14 +08:00 · 1135 次点击
    这是一个创建于 498 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想实现这个网站的爬虫自动登录功能: https://www.cnhnb.com/hangqing/cdlist-0-0-0-0-0-1/

    我的自动登录逻辑是先进入该网站,点击登录选项之后点击密码选项,输入账号密码同意协议并点击登录,暂时写了下面的代码

    public static void main(String[] args) {
                    System.getProperties().setProperty("webdriver.chrome.driver","D:\\pachong\\new\\chromedriver.exe");
            ChromeOptions options = new ChromeOptions();
            options.addArguments("--remote-allow-origins=*");
            ChromeDriver chromeDriver = new ChromeDriver(options);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Stirng url = "https://www.cnhnb.com/hangqing/cdlist-0-0-0-0-0-1/";
            chromeDriver.get(url);
            //获取登录选项并点击该选项
            WebElement loginButton = chromeDriver.findElement(By.xpath("//*[@id=\"__layout\"]/div/div/div[1]/div[1]/div/div[1]/div[2]/div[1]"));
                loginButton.click();
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //获取登录窗口并切换到该窗口
                WebElement element = chromeDriver.findElement(By.id("eye-iframe-sso-login"));
                chromeDriver.switchTo().frame(element);
                //获取密码登录选项并点击,该行发生 Bug
                WebElement pwdLogin = element.findElement(By.xpath("//*[@id=\"__layout\"]/div/div/div/div[1]/div[1]/div[3]"));
                pwdLogin.click();
                //此处省略更多业务处理
                chromeDriver.switchTo().defaultContent();
    }
    

    现在的问题是,每次我的代码运行到获取密码登录选项的时候就报 Exception in thread "main" org.openqa.selenium.StaleElementReferenceException: stale element reference: stale element not found

    百度说是要重新获取元素,我重新获取前一个元素也没用,照样报这个错误,ChromeDriver 版本按说是没问题的,因为之前用这个框架做了一些其他爬虫都是可以正常启动并爬取信息的,最多就是控制台报了警告: Unable to find an exact match for CDP version 114, so returning the closest version found: 110 ,这个应该问题不大

    我搞了好就,不管是问 GPT 还是查百度都找不到好的解决方法,我实在没法了所以我来问问各位,有没有懂得指导指导可好啊

    6 条回复    2023-07-12 18:00:02 +08:00
    gg1025
        1
    gg1025  
       2023-07-12 14:32:40 +08:00
    第一个问题
    ```java
    Stirng url = "https://www.cnhnb.com/hangqing/cdlist-0-0-0-0-0-1/";
    ```
    这里 String 拼写错误
    gg1025
        2
    gg1025  
       2023-07-12 14:34:23 +08:00
    一个可行的方案
    ```java
    public static void main(String[] args) {
    System.getProperties().setProperty("webdriver.chrome.driver","D:\\pachong\\new\\chromedriver.exe");
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--remote-allow-origins=*");
    ChromeDriver chromeDriver = new ChromeDriver(options);
    try {
    Thread.sleep(3000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    String url = "https://www.cnhnb.com/hangqing/cdlist-0-0-0-0-0-1/";
    chromeDriver.get(url);
    //获取登录选项并点击该选项
    WebElement loginButton = chromeDriver.findElement(By.xpath("//*[@id=\"__layout\"]/div/div/div[1]/div[1]/div/div[1]/div[2]/div[1]"));
    loginButton.click();
    try {
    Thread.sleep(3000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    //获取登录窗口并切换到该窗口
    WebElement element = chromeDriver.findElement(By.id("eye-iframe-sso-login"));
    chromeDriver.switchTo().frame(element);
    //获取密码登录选项并点击,该行发生 Bug
    // WebElement pwdLogin = element.findElement(By.xpath("//*[@id=\"__layout\"]/div/div/div/div[1]/div[1]/div[3]"));
    // 尝试这个方案
    WebElement tabs = webDriver.findElement(By.className("tabs"));
    WebElement pwdLogin = tabs.findElements(By.className("tab-item")).get(2);
    pwdLogin.click();
    //此处省略更多业务处理
    chromeDriver.switchTo().defaultContent();
    }
    ```
    kanchi240
        3
    kanchi240  
       2023-07-12 14:37:48 +08:00
    WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
    wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frame));
    tiRolin
        4
    tiRolin  
    OP
       2023-07-12 16:37:34 +08:00
    @gg1025 太感谢你了,这个确实解决了我的问题。虽然我不知道为什么,但是现在我还是先拿来主义,以后再搞明白个中原理
    Belmode
        5
    Belmode  
       2023-07-12 17:59:33 +08:00
    https://mjj.today/i/WTT8pI

    因为登录按钮处用的 xpath 不正确
    Belmode
        6
    Belmode  
       2023-07-12 18:00:02 +08:00
    ![d83193f01191c7cb71bf762769549f62.png]( https://i3.mjj.rip/2023/07/12/d83193f01191c7cb71bf762769549f62.png)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5791 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 01:57 · PVG 09:57 · LAX 17:57 · JFK 20:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.