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()工作正常。
答案 0 :(得分:1)
在确认目标元素已在页面上呈现之前,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在运行任务之前等待加载元素。
答案 1 :(得分:1)
我遇到了类似的问题,并在找到该元素之前尝试刷新页面,并且它有效...
driver.navigate().refresh();
虽然我无法推断这是如何运作的。
如果这对你有用,请告诉我。我只是想了解更多有关此例外的信息。
答案 2 :(得分:0)
我在尝试执行一些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元素对象。