问答 selenium 元素点击报错 StaleElementReferenceException 找不到原因

tooluser · 2024年01月08日 · 最后由 大海 回复于 2024年01月10日 · 5655 次阅读

界面上不在 micro-app 微前端内部的元素都可以点击,唯独 micro-app 微前端内部的所有元素都操作不了。
selenium 4.16.0 版本定位界面元素在 micro-app 微前端内部
element = driver.find_element(By.XPATH, "//div[@id='app-alarm-search']/div/div[1]/div/button[1]")
element.click()
元素能查找到,但是 element.click() 一直报错:
driver.execute_script("arguments[0].click();", element)
File "D:\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 408, in execute_script
return self.execute(command, {"script": script, "args": converted_args})["value"]
File "D:\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 348, in execute
self.error_handler.check_response(response)
File "D:\Python38\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 229, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
网上查了一些方法增加等待时长,捕获 StaleElementReferenceException 异常重新查找点击都不能解决
此外,同一个元素使用相同的 css 定位,使用 driver.execute_script("document.querySelector('css').click();") 可以正常点击,使用 driver.find_element(By.CSS_SELECTOR, css).click() 报上述错误,
谁能帮忙解答下?

共收到 3 条回复 时间 点赞

元素状态变化了 重新定位元素后再执行动作 如果还报错 再重新定位 循环几次总有成功的

这个问题可能是由于 StaleElementReferenceException 异常引起的,这意味着当 Selenium 尝试操作一个元素时,该元素在 DOM 中已发生改变或不再存在。在微前端框架(如 single-spa、qiankun 等)中,由于其动态加载和渲染机制,可能会导致这种问题。

针对这种情况,你可以尝试以下策略:

  1. 使用 ExpectedConditions 配合 WebDriverWait 来等待元素可交互状态:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)  # 设置最长等待时间
element = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@id='app-alarm-search']/div/div[1]/div/button[1]")))
element.click()
  1. 在执行点击操作前,确保元素仍存在于 DOM 中,可以先检查一下元素是否可见或者是否存在:
def is_element_present(xpath):
    try:
        driver.find_element(By.XPATH, xpath)
        return True
    except NoSuchElementException:
        return False

while is_element_present("//div[@id='app-alarm-search']/div/div[1]/div/button[1]"):
    element = driver.find_element(By.XPATH, "//div[@id='app-alarm-search']/div/div[1]/div/button[1]")
    if element.is_displayed():
        element.click()
        break
  1. 如果上述方法仍无法解决,可能需要深入理解微前端框架的渲染机制,并根据实际情况调整定位和操作元素的方式。例如,在微前端应用完全加载完成之后再进行元素查找和点击操作。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册