迭代并打开新的浏览器页面导致 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
:)
解决办法——在新标签页打开目标链接;因此您的页面将不会刷新,并且引用将有效。
或者更好,获取所有链接,并在新循环中打开它们。
我有一个非常简单的脚本,可以找到页面中的所有 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
:)
解决办法——在新标签页打开目标链接;因此您的页面将不会刷新,并且引用将有效。 或者更好,获取所有链接,并在新循环中打开它们。