当前位置: 首页 > 知识库问答 >
问题:

seleniumJava中的“页面文档”

颜瀚漠
2023-03-14

我试图使用Xpath立即从活动元素获取数据,但当我运行该项目时,我遇到了这个错误

线程“main”组织中出现异常。openqa。硒。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 + "    ");
            }
        }
    }

共有1个答案

赏夕
2023-03-14

你写道:“我正在努力立即获取数据……”这可能是个问题。

当在网页内容刷新之前或刷新过程中获得web元素时,将引发StaleElementReourceExc0019。换句话说,它是过早获得的。解决方法是等到页面完全加载完毕。

“元素未附加到页面文档”意味着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(...);

在上面的代码片段中,从调用隐式wait的那一刻起,直到测试会话结束,在尝试获取web元素之前,应用程序将等待传递给函数的最短时间;在我的例子中,这是10秒。

这样做的一个更好的方法是使用WebDriverWAT类。

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,10100)将最多等待10秒,每100毫秒轮询一次。一旦获得wait对象,它将用于获得通过ExpectedConditions类提供的正确预期条件的WebElement对象。例如,等待按钮变为“可点击”(可见和启用)

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();

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

基本上,这个代码是有效的。。。。某种程度上。

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元素的交互包装在try/catch中,在那里您将捕获StaleElementReiscceExc0019以忽略它并继续。在真正的硒测试中,您可以使用此策略重试获取丢失的元素,但在这种情况下,您不需要这样做。

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

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

 类似资料:
  • 想象有一个页面在说http://google.com/AddUser在这里输入记录的详细信息,然后单击保存。完成此操作后,页面将重定向到 http://google.com/userList 您可以在其中查看用户列表,包括您刚刚输入的新记录。 如果我们按照页面对象模型,那么在和验证记录是否实际保存和显示的方法应该在 如果我们认为addUser和userList是两个类的对应对象,它会像下面这样:

  • 有人知道我如何为分页页面设置不同的posts_per_pages吗? 例如: 主页=每页帖子20主页第2-5页=每页帖子10 我使用的查询是$wp\u query-

  • easyopen提供一个简单的api文档查看页面,类似于swagger,基于注解功能来生成文档页面。生成的文档页面可以查看参数、结果说明,也可以进行模拟请求。对于前后端分离的项目来说会很有帮助。文档界面如下图所示: 左边的树形菜单对应文档名称,点击树可前往查看对应的接口说明。点击请求按钮可以发起请求进行测试。可修改业务参数中的值进行测试。 下面来讲解文档注解的使用方法。 文档页面默认是关闭的,需要

  • 我希望我所有的课程都按顺序进行。下面是我的testng xml文件: 我试过在套房里用姓名标签来做:

  • 本文向大家介绍如何取消页面中选中的文字?相关面试题,主要包含被问及如何取消页面中选中的文字?时的应答技巧和注意事项,需要的朋友参考一下

  • 我的客户有以下wordpress站点= http://texasdentalimplants.com/index.php/blog 这就是blog页面传统上的工作方式: 用户点击博客页面-->显示一系列文章-->用户选择点击博客文章,用户看到选择的博客文章 客户机,不管是谁,都希望每页只显示一篇博文,所以现在“blog”页面,有点变得多余了(它只是博文的精确副本)。 我想做的是让它像这样运行--