迭代并打开新的浏览器页面导致 StaleElementReferenceException

Iterate and open new browser pages causes StaleElementReferenceException

我有一个非常简单的脚本,可以找到页面中的所有 HREF 并迭代并记录它:

Photo search scroll
    Go To   https://xxx
    ${elements}=    Get WebElements     xpath://a[contains(@href,'photo')]
    FOR    ${element}    IN    @{elements}
        Log    ${element.get_attribute('href')}
    END

它工作得很好。 因为我需要为每个 HREF 打开一个新的浏览器,所以我添加了 Selenium Browser 命令:

Photo search scroll
    Go To   https://xxx
    ${elements}=    Get WebElements     xpath://a[contains(@href,'photo')]
    FOR    ${element}    IN    @{elements}
        Log    ${element.get_attribute('href')}
        Go To      ${element.get_attribute('href')}
        sleep   2s
        Capture Page Screenshot
        Go Back
    END

我总是在第一次迭代后得到这个错误:

Resolving variable '${element.get_attribute('href')}' failed: StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=86.0.4240.111)

我不明白为什么会这样。 任何 help/comments 表示赞赏。 非常感谢

###更新 我创建了一个列表变量并添加了额外的循环:

@{hrefs} =  Create List
    FOR    ${element}    IN    @{elements}
        Log    ${element.get_attribute('href')}
        Append To List  ${hrefs}        ${element.get_attribute('href')}  
    END

    FOR     ${href}     IN      @{hrefs}
        Go To           ${href}
        sleep  2s
        Capture Page Screenshot
    END

现在我得到这个错误代码:

Opening url 'Create List'   
20:08:36.739    FAIL    InvalidArgumentException: Message: invalid argument
  (Session info: chrome=86.0.4240.111)

why this happens

因为当您调用 Get WebElements 时,您获得了对当前页面和会话中对象的引用;浏览器还保留对当前 DOM 元素的相同引用。

当您转到另一个页面然后返回时,对于浏览器来说这是一个不同的页面。视觉上是一样的;它的 html 是一样的。
但是对于浏览器来说,这是一个不同于您开始的页面;它对其中元素的内部引用是不同的(它为您正在浏览的页面构建的“地图”)。同时,您请求浏览器通过引用给您一个对象。但是浏览器没有它——那些对象对它的调用不一样,引用是不同的。你有一个陈旧的(过期的,无效的,旧的)参考,没有指向它在其“地图”中的任何 DOM 对象。 StaleElementReferenceException:)

解决办法——在新标签页打开目标链接;因此您的页面将不会刷新,并且引用将有效。 或者更好,获取所有链接,并在新循环中打开它们。