Python, Selenium : '元素不再附加到 DOM
我正在抓取一个网站,www.lipperleaders.com。我想提取新加坡的基金详情。我已经成功实现了下拉选择,并提取了提交选项后出现的第一页内容。但是,当我尝试点击“下一页”按钮时,出现了错误 'Element is no longer attached to the DOM'
。
我的代码大约有100行,但我可以给你一个大概的执行流程:
... # creating driver object and all the imports
def main():
...
result = find_elements_by_tag_name('span')
...
driver.find_element_by_id("ctl00_ContentPlaceHolder1_ucDataPager_btnNext").click()
main()
main()
这段代码在第一页运行得很好,但当再次调用 main()
方法以点击下一页时,就出问题了。在这个递归方法之前,我也尝试过把它放在一个循环里,结果也是同样的错误。
如果我这样写代码:
# some code
result = find_elements_by_tag_name('span')
driver.find_element_by_id("ctl00_ContentPlaceHolder1_ucDataPager_btnNext").click()
# some code
driver.find_element_by_id("ctl00_ContentPlaceHolder1_ucDataPager_btnNext").click()
.
.
这段代码在加载下一页时没有任何错误,后面的代码也能正常执行。但是我不能为500页都写相同的 driver.find_element_by_id().click()
,这样我还得重复每一页相关的其他代码。所以我才尝试使用循环或递归,但对我来说都不管用。
请告诉我,我的方法有什么问题。
2 个回答
1
这看起来是一个“过时元素异常”,通常发生在你试图查找某个元素的时候。这个元素每次都会加载,但你之前已经找到了它
,所以它就变成了过时的。
我建议使用一些自定义的方法来避免这个问题,下面是一个最简单的解决方案:
void clickOnStaleElement(String id, WebDriver driver) {
try {
driver.find_element_by_id(id).click();
} catch (StaleElementReferenceException e) {
// Trying to find element stale element
clickOnStaleElement(id, driver);
} catch (NoSuchElementException ele) {
clickOnStaleElement(id, driver);
}
}
8
问题在于,有一些JavaScript代码把这个元素给移除了。所以你需要让驱动程序等一下这个元素的出现:可以通过设置 implicitly_wait
来实现,具体可以参考:
from selenium import webdriver
ff = webdriver.Firefox()
ff.implicitly_wait(10) # seconds
...
myDynamicElement = ff.find_element_by_id("myDynamicElement")
来自 http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp#implicit-waits