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

306 天前
 tiRolin

我想实现这个网站的爬虫自动登录功能: 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 还是查百度都找不到好的解决方法,我实在没法了所以我来问问各位,有没有懂得指导指导可好啊

942 次点击
所在节点    Java
6 条回复
gg1025
306 天前
第一个问题
```java
Stirng url = "https://www.cnhnb.com/hangqing/cdlist-0-0-0-0-0-1/";
```
这里 String 拼写错误
gg1025
306 天前
一个可行的方案
```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
306 天前
WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frame));
tiRolin
306 天前
@gg1025 太感谢你了,这个确实解决了我的问题。虽然我不知道为什么,但是现在我还是先拿来主义,以后再搞明白个中原理
Belmode
306 天前
https://mjj.today/i/WTT8pI

因为登录按钮处用的 xpath 不正确
Belmode
306 天前
![d83193f01191c7cb71bf762769549f62.png]( https://i3.mjj.rip/2023/07/12/d83193f01191c7cb71bf762769549f62.png)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/956142

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX