【问题标题】:Selenium error "Element is no longer attached to the DOM" while scraping data抓取数据时出现 Selenium 错误“元素不再附加到 DOM”
【发布时间】:2013-09-24 00:13:03
【问题描述】:
        for i in driver.find_elements_by_class_name("endorse-count"):
            try:
                i.click()
            except:
                continue

            elem = WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.CLASS_NAME, "dialog-window")))
            src = elem.get_attribute("innerHTML")

            add_skill(name, src)

            WebDriverWait(driver, timeout=10)

运行上述代码时出现以下错误 -

selenium.common.exceptions.StaleElementReferenceException: Message: u'Element is no longer attached to the DOM' ; Stacktrace: 
    at fxdriver.cache.getElementAt (resource://fxdriver/modules/web_element_cache.js:7646)

换行-

src = elem.get_attribute("innerHTML")

登录后,我正在 LinkedIn 用户个人资料页面上运行此代码。

我尝试将以下代码行放在“i.click()”之后-

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

但后来我看到函数“add_skill(name, src)”没有被调用,也没有调用 driver.manage() 之后的代码,尽管 for 循环和进一步的 i.click() 工作正常。

【问题讨论】:

    标签: python dom selenium exception-handling selenium-webdriver


    【解决方案1】:

    Selenium 在验证目标元素是否已在页面上呈现之前尝试完成操作(例如单击按钮或链接)。 Selenium 可以更有耐心,但你必须明确要求他这样做。

    例如,如果您正在测试发出 AJAX 请求的东西,您可以尝试这样的事情(在 Ruby 中):

    # timeout is in seconds
    def wait_for_ajax(timeout=x)
     time_limit, interval = (Time.now + timeout), 0.5
     loop do
       break if @driver.execute_script "return jQuery.active == 0"
       sleep interval
       raise "Wait for AJAX timed out after waiting for #{timeout} seconds" if Time.now > time_limit
     end
    end
    

    为确保您的测试完全全面,请始终让 Selenium 在运行任务之前等待元素加载。

    【讨论】:

    • 如果你仔细看,我已经在我的代码中使用了等待 - elem = WebDriverWait(driver, 100).until(EC.presence_of_element_located((By.CLASS_NAME, "dialog-window"))) 但它没有帮助。
    【解决方案2】:

    我遇到了类似的问题,并尝试在找到该元素之前刷新页面,它确实有效...

    driver.navigate().refresh();
    

    虽然我无法解释这是如何工作的。

    如果这也适用于您,请告诉我。我只是想了解有关此异常的更多信息。

    you can refer this page to learn about a similar issue

    【讨论】:

    • 感谢您的帮助,但是刷新页面时我正在工作的弹出窗口消失了,所以这对我没有帮助。此处的弹出窗口是通过单击特定用户的特定技能的背书者数量生成的。我想处理那个弹出窗口,因此 - src = elem.get_attribute("innerHTML") - 我正在使用 HTML。
    【解决方案3】:

    我在尝试执行一些 javascript (IJavaScripExecutor) 时遇到了类似的问题。我创建了一个 IWebElement 并将其传递给 JSE,但对我来说失败了。当我将 driver.FindElement(BySelector) 移动到我的 JSE 调用中时,它就起作用了。 (前面有 C# 代码。)

    代替:

    IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
    IWebElement tableEl = driver.FindElement(selector);
    js.ExecuteScript(script, tableEl);
    

    我必须这样做:

    IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
    js.ExecuteScript(script, driver.FindElement(selector));
    

    您可能必须做类似的事情:将您的选择器或元素创建移到您尝试做的同一行。或者,也许,在你的情况下:

    src = driver.find_element_by_class_name("dialog-window").get_attribute("innerHTML")
    

    仔细检查后,这似乎是您的问题,当您尝试使用 get_attribute 方法时,存在一个陈旧的 Web 元素对象。

    【讨论】:

      猜你喜欢
      • 2021-08-05
      • 2014-07-15
      • 2014-06-06
      • 2014-10-05
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多