【问题标题】:Selenium - iterate over elementsSelenium - 遍历元素
【发布时间】:2019-04-18 07:47:54
【问题描述】:

我的目标是:

  • 迭代网页中的 WebElements
  • 点击所有创建的元素并在同一会话中打开链接
  • 使用其他逻辑解析新页面
  • 返回上一页并为所有上一页匹配的 id 继续循环

我有这个代码:

List<WebElement> links = driver.findElements(By.cssSelector("div[data-sigil='touchable']"));

// this will display list of all images exist on page
for(WebElement ele:links)
{
    System.out.println("test->"+ele.getAttribute("id"));
    ele.click();
    Thread.sleep(500);
    System.out.println("URI->"+driver.getCurrentUrl());
    js.executeScript("window.history.go(-1)");
} 

return "ok";

哪个工作正常,它找到正确的元素 id,“ele.click()”实际上工作,但是当我执行 js.executeScript("window.history.go(-1)") 时总是失败

这是我的错误信息:

org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
  (Session info: chrome=73.0.3683.103)
  (Driver info: chromedriver=2.40.565498 (ea082db3280dd6843ebfb08a625e3eb905c4f5ab),platform=Windows NT 10.0.17134 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds

所以基本上我无法继续循环。 是否有任何有用的技术可以“点击进入新标签”并管理不同的 Selenium 驱动程序会话?

非常感谢您的任何建议。

【问题讨论】:

  • 我相信您的js 变量是一个WebElement,并且由于页面发生了变化而发生了变化,您需要重新查找该元素。
  • 谢谢,但是如何标记我已经处理的 webelements ID?
  • 那是一个不同的问题。您需要找到每个链接的独特之处(如 url),将其添加到字典或列表中,然后查找整个列表并删除字典/列表中的那些。

标签: java selenium google-chrome


【解决方案1】:

发生的情况是,当您进入另一个页面时,它会使列表中的所有元素都过时。当您再次返回页面时,这些元素不会附加到页面上。每次加载页面时都需要查找元素。

试试这个:

List<WebElement> links = driver.findElements(By.cssSelector("div[data-sigil='touchable']"));
        // this will display list of all images exist on page
String address;
        for(int i=0; i<links.size(); i++){
            address = driver.getCurrentUrl();
            links = driver.findElements(By.cssSelector("div[data-sigil='touchable']"));
            System.out.println("size: "+links.size());
            WebElement ele = links.get(i);
            System.out.println("test->"+ele.getAttribute("id"));
            ele.click();
            Thread.sleep(500);
            System.out.println("URI->"+driver.getCurrentUrl());
            //js.executeScript("window.history.go(-1)");
            //driver.navigate().back();
            driver.get(address);
        }

编辑:

在等待页面加载时尝试driver.get()。或者您可以在单击后直接添加另一个睡眠。

【讨论】:

  • 谢谢,我收到了这个错误:ava.lang.IndexOutOfBoundsException: Index: 2, Size: 0 at java.util.ArrayList.rangeCheck(Unknown Source) at java.util.ArrayList.get(Unknown来源)在
  • 你好,即使使用 driver.get() 返回相同的错误。我应该在哪里检查明确的等待?抱歉,我对此有点困惑 - 非常感谢
  • 由于它返回大小 0,我假设它没有等待页面加载。我已经编辑了答案。你能再试试这个吗?另外,是否有机会更改重新加载时的元素数量?如果它发生变化,那么解决方案将不起作用。
  • 嗨,同样的错误,但我在想:有没有办法打开一个新标签?还是硒中的新会话?就像我得到了所有元素的 ID,单击它并在新会话中打开,做这些事情并杀死它。谢谢
  • 嗨,我已经使用driver.get() 代码进行了编辑。你能用这个,让我知道它是否有效吗?另外请检查列表的大小是否保持不变。
【解决方案2】:

我认为您需要像这样创建js 对象。

原因是您“丢失”了对 JavascriptExecutor 的引用

List<WebElement> links = driver.findElements(By.cssSelector("div[data-sigil='touchable']"));
// this will display list of all images exist on page
for(WebElement ele:links){
    System.out.println("test->"+ele.getAttribute("id"));
    ele.click();
    Thread.sleep(500);
    System.out.println("URI->"+driver.getCurrentUrl());
    // Re initialise js executor
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("window.history.go(-1)");
} 
return "ok";

【讨论】:

  • 我认为当您运行以下行(根据 OP)js.executeScript("window.history.go(-1)"); 时不会发生错误,我怀疑它是在 for 循环尝试迭代到 links 中的下一个项目时发生的。
猜你喜欢
  • 2015-01-16
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多