selenium< element未附加到页面文档“in selenium>java”

2eafrhcq  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(379)

我试图使用xpath从活动元素中立即获取数据,但是当我运行项目时,出现了这个错误
线程“main”org.openqa.selenium.staleelementreferenceexception中出现异常:stale元素引用:元素未附加到页面文档

package read;

    import java.util.concurrent.TimeUnit;
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.chrome.ChromeDriver;

    public class ResdeStoFromBrowser {

        public static final String TEXT_RESET = "\u001B[0m";
        public static final String TEXT_RED = "\u001B[31m";
        public static final String TEXT_GREEN = "\u001B[32m";
        public static final String TEXT_CYAN = "\u001B[36m";

        public void ResdeSto() throws InterruptedException {
            System.setProperty("webdriver.chrome.driver", "C:\\Users\\owner\\....\\chromedriver.exe");
            WebDriver driver = new ChromeDriver();
            driver.navigate().to("https:.........");
            driver.manage().window().maximize();
            while (true) {
                TimeUnit.SECONDS.sleep(1);
                String sel2 = driver.findElement(By.xpath("/html/body/div[2]/div[1]/div/div[2]/div[2]/div[2]/div[2]/div[1]/div[1]/span[3]")).getText();
                System.out.println(TEXT_GREEN + "  " + sel2 + TEXT_RESET + "    ");
            }
        }
    }
tyg4sfes

tyg4sfes1#

你写了“我正在尝试立即获取数据…”好吧,这可能是个问题。 StaleElementReferenceException 在网页内容刷新之前或刷新过程中获取web元素时抛出。换句话说,它是过早获得的。解决方案是等待页面完全加载完毕。
“元素未附加到页面文档”意味着web元素可能不再位于html文档中。
获取web元素有两种方法:

WebDriver driver = new ChromeDriver();
driver.findElement(...);

假设你在正确的页面上, findElement 将立即尝试定位元件。如果页面在加载过程中,很可能会导致op帖子中提到的错误。解决这个问题的正确方法是添加隐式等待。

WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); // Time amount and time units are arbitrary.
// get to the page...
driver.findElement(...);

在上面的片段中,从 implicitlyWait 调用,直到测试会话结束,在尝试获取web元素之前,应用程序将等待传递给函数的最短时间;在我的例子中是10秒。
更好的方法是使用 WebDriverWait 班级。

WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, 10); // max. wait time set to 10 seconds with default 500 ms polling interval
``` `WebDriverWait` 有一个三参数变量,其中第三个参数是以毫秒为单位的轮询间隔。例如, `WebDriverWait(driver, 10, 100)` 将最多等待10秒,每100毫秒轮询一次 `wait` 对象,它将用于获取 `WebElement` 对象传递由提供的正确预期条件 `ExpectedConditions` 班级。例如,等待按钮变为“可单击”(可见和启用)

WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.xpath(XPATH EXPRESSION HERE)));
button.click();

这种方法,假设您已经在正确的页面上,将尝试定位所需的组件,并将最长的时间传递给 `WebDriverWait` 在它超时之前。但是,如果在超时之前找到了组件并且达到了预期的条件,它将返回请求的组件。这是避免过时元素(尽管不是完全)的更好方法。
最好的方法可能是将这两种方法结合起来。
首先,在获得web驱动程序示例后设置隐式等待时间

WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

然后,导航到页面

driver.navigate().to("https:.........");

最后,使用第二种方法获取web元素

WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("...")));
button.click();

当隐式和显式等待一起使用时,出现过时元素问题的可能性几乎为零。你只需要聪明一点,在你要使用它之前,总是先获得它。。。。绝对不要把这样的代码放在一个无休止的循环中。
基本上,这个代码是。。。。某种程度上。

public class TickerPageTest {
@Test
public void printTickerValueEndlessLoop() {
System.setProperty("webdriver.chrome.driver", "F:\Users\Hector\webdriver\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://coincheck.com/exchange/tradeview");

    while (true) {
    WebDriverWait wait = new WebDriverWait(driver, 10, 10);
    WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html/body/div[2]/div[1]/div/div[2]/div[2]/div[2]/div[2]/div[1]/div[1]/span[3]")));
    System.out.println(element.getTagName() + ":" + element.getText());
    }
}

}

以上代码输出以下内容(大多数情况下)

span:5898999
...
span:5900895
...
span:5898999

最好的办法是将与web元素的交互 Package 在try/catch中,您将在其中捕获 `StaleElementReferenceException` 忽略它继续。在一个真正的selenium测试中,您可以使用此策略来重试获取丢失的元素,但在这种情况下您不需要这样做。

try {
System.out.println(element.getTagName() + ":" + element.getText());
} catch (StaleElementReferenceException e) {
System.err.println("Test lost sync... this will be ignored.");
}

当我这样做的时候,在几百行(或更多行)之后,我能够同步捕捉到丢失:

span:5906025
Test lost sync... this will be ignored.
span:5906249

但是,正如你所看到的,我只是忽略了它,继续下一个更新。

相关问题