在 selenium - python 中收到“StaleElementReferenceException”,我该如何处理?

Receiving a 'StaleElementReferenceException' in selenium - python, how do I handle this?

提问人:Jeff Gordon 提问时间:11/8/2023 更新时间:11/8/2023 访问量:30

问:

我在将键发送到硒中的文本输入栏时遇到了一个奇怪的问题。最奇怪的部分是我看到字符在栏中出现一秒钟,然后它就消失了。我通过循环将每个(字符串)键发送到元素,您会看到前几个字母填充,但突然间它们消失了,然后我收到错误。如果我不使用循环,它最终会填充整个单词一秒钟,然后消失,但它会进入下一步。我必须完成整个表格才能继续,所以我不能只是消除该步骤。forStaleElementReferenceExceptionsend_keys

我正在尝试抓取的 HTML:
<input id="plaintiffDetails:city" name="plaintiffDetails:city" type="text" value="" 
onchange="jsf.ajax.request('plaintiffDetails:city',event,{execute:'@this ',render:'plaintiffDetails:additionalInfo ','javax.faces.behavior.event':'valueChange'})" 
maxlength="30" size="37"> == $0

我不确定该部分是否影响了这一点,因为我不熟悉 JavaScript。onchange=

法典:
        city_input = WebDriverWait(driver,10,ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located(\
            (By.XPATH, "//input[@name='plaintiffDetails:city']")))
        for c in client_city:
            city_input.send_keys(c)
错误:
StaleElementReferenceException            Traceback (most recent call last)
Cell In[23], line 347
    344 city_input = WebDriverWait(driver,10,ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located(\
    345     (By.XPATH, "//input[@name='plaintiffDetails:city']")))
    346 for c in client_city:
--> 347     client_input.send_keys(c)
    349 wait()
    351 zip_input = WebDriverWait(driver,10,ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located(\
    352     (By.XPATH, "//*[@id='plaintiffDetails:zip']")))

这特别奇怪,因为我已经设置了这个问题所引用的。然而,它仍然给了我这个例外。有谁知道为什么硒会产生这个异常/如何处理它?ignored_exceptionsignored_exceptions=(NoSuchElementException,StaleElementReferenceException)

python html selenium-webdriver xpath

评论

0赞 pcalkins 11/8/2023
是的,onchange 正在触发该脚本......看起来它正在进行查找,并可能显示您可以单击的匹配选项列表。当它更新该列表时,DOM 已更改,因此所有元素引用现在都已过时。您可以做的一件事是粘贴值。(填充剪贴板,并发送 Ctrl-V 的键)然后 DOM 将更新。之后,您需要重新获取您正在使用的任何元素。(也许先使用小睡眠或预期的陈旧状态......
0赞 Jeff Gordon 11/8/2023
有趣的是,我一般没想过用硒来复制和粘贴!但是,我没有选择可见的列表,因此我将从哪里复制值。当你说重新获取我正在使用的元素时,你的意思是重新建立元素的变量吗?我只是想知道,因为一旦该元素将密钥发送给它,就不需要再次与之交互。
0赞 pcalkins 11/9/2023
听起来像原来的send_keys('全文');可能已经奏效了。听起来,如果 ajax 调用找到匹配项,它将填写表单详细信息的其余部分,并提交它们。如果收到“过时元素”异常,则表示无法再使用当前的 webelement 引用。再次检索该元素变量(这是对 DOM 的引用)。DOM 已更新,使其过时。对过时引用的任何方法调用都将引发该过时元素异常。要使用粘贴方法,您需要在 Ctrl-V 之前将母语的剪贴板内容设置为 element。

答: 暂无答案