在尝试提取嵌套iframe的{s}属性时获取陈旧元素引用异常

时间:2017-04-02 04:05:38

标签: java selenium

我正在尝试获取所有嵌套iframe的src属性,但我得到陈旧的引用异常。这是代码

public class findAllSources {

    ArrayList<String> sources = new ArrayList<String>();

    @Test
    public void iframeTest() {
        System.setProperty("webdriver.chrome.driver", "path to chrome driver");
        ChromeDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        driver.get("https://www.engadget.com/");
        List<WebElement> allFrames = driver.findElements(By.xpath("//iframe[not(contains(@style,'display:none'))]"));
        for (WebElement frame : allFrames) {
            if(frame.isDisplayed()){
                    System.out.println("We clicked frame "+frame);
                    System.out.println(" with a source  "+frame.getAttribute("src"));
                    sources.add(frame.getAttribute("src"));
                    driver.switchTo().frame(frame);
                    findDeeperFrames(driver); 
                    driver.switchTo().defaultContent();
            }
        }
    }

    public void findDeeperFrames(ChromeDriver driver){

        List<WebElement> deeperFrames = driver.findElements(By.xpath("//iframe[not(contains(@style,'display:none'))]"));
        for (WebElement nframe: deeperFrames) {
            if (nframe.isDisplayed()){

                if (!nframe.getAttribute("src").isEmpty()){
                sources.add(nframe.getAttribute("src"));
                System.out.println("Nested source "+ nframe.getAttribute("src"));}

                 driver.switchTo().frame(nframe);
                 findDeeperFrames(driver);
                 //getting out of the frame
                driver.switchTo().defaultContent();
            }
        }
    }
}

有没有其他方法可以实现我的目标?

2 个答案:

答案 0 :(得分:0)

<强>更新:

您的代码返回StaleExcceptionError,因为在使用driver.switchTo().defaultContent();之后,您的代码进入for LOOP的下一个迭代,该迭代仍在使用allFrames webElement列表,该列表在切换到新帧之前最初存储并且这些元素不再附加到DOM。因此,为了避免您必须再次识别该帧列表,如下所示:

 List<WebElement> deeperFrames = driver.findElements(By.xpath("//iframe[not(contains(@style,'display:none'))]"));


 for (int j=1; j<=deeperFrames.size(); j++) {


            List<WebElement> myFrames = driver.findElements(By.xpath("//iframe"));

            WebElement nframe = myFrames.get(j-1);


            if (nframe.isDisplayed())
            {
                 if (!nframe.getAttribute("src").isEmpty()){
            sources.add(nframe.getAttribute("src"));
            System.out.println("Nested source "+ nframe.getAttribute("src"));}

             driver.switchTo().frame(nframe);
             findDeeperFrames(driver);
             //getting out of the frame
            driver.switchTo().defaultContent();

            }
}

答案 1 :(得分:0)

当我尝试与 iframe(存储为 WebElement 变量)交互时,我遇到了同样的 StaleElementReferenceException,它实际上在页面上仍然可见,所以我不知道是什么导致了这个问题。原因是,首先,我将 iframe 存储为变量,然后,我使用 driver.switchTo().frame(thatFrame);(与框架内的元素进行交互)切换到该框架,但我从未切换回原始的主框架driver.switchTo().defaultContent();,之前我想再次与框架本身进行交互。而“从内部”框架,实际的框架 DOM 元素是一个陈旧的对象(不附加到内部框架的 DOM)。

也许不是您问题的确切答案,只是为搜索此异常和框架的人提供的注释。