Loop内的Selenium Stale Element driver.get(url)

时间:2017-09-13 02:45:41

标签: python selenium

我希望使用Selenium通过一组URL进行迭代。我不时得到const parseJwt = (token) => { try { return JSON.parse(atob(token.split('.')[1])); } catch (e) { return null; } }; 。因此,在阅读了几个其他问题之后表明它是因为我正在改变正在查看的页面。但是我对这个论点不满意:

'element is not attached to the page document'

但是如果我添加这样的延迟:

for url in urlList:

   driver.get(url)

   WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, '//div/div')))
   #^ WebDriverWait shall had taken care of it  

   myString = driver.find_element_by_xpath('//div/div').get_attribute("innerHTML")
   # ^ Error occurs here

   # Then I call this function to go thru other elements given other conditions not shown
   if myString:
      getMoreElements(driver)

我觉得我通过在那里添加延迟来隐藏问题。我for url in urlList: driver.get(url) time.sleep(5) # <<< IT WORKS, BUT WHY? element = WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, '//div/div'))) myString = driver.find_element_by_xpath('//div/div').get_attribute("innerHTML") # Error occured here 设置为30秒,implicity_wait设置为90秒,这已经足够了。那么,为什么我还要面对添加看似无用的time.sleep?

2 个答案:

答案 0 :(得分:0)

您是否在开发工具中手动尝试xpath:// div / div以查看页面上将找到多少div?我认为应该有很多。所以你的下面明确的等待代码可以很容易地满足,也许不超过1秒,selenium可以在browser.get()和你的等待结束后找到这样一个div。

WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, '//div/div')))

考虑以下可能性:
由于你的上述明显的等待问题,页面加载不完整,越来越多的// div / div正在渲染到页面,在这个时间点,你要求selenium找到这样一个div并与之交互。

考虑selenium找到的第一个div的可能性不会被删除或移动到另一个DOM节点。

您认为上述可能性的比率是高还是低?我认为它非常高,因为div是当今网页中非常常见的标签,你使用这样一个放松的xpath,导致找到很多匹配的div,并且每一个都可能导致'Element Stale'问题< / p>

要解决您的问题,请使用更严格的定位器来等待一些特殊元素,而不是如此仓促的xpath导致找到非常常见且存在很多元素。

答案 1 :(得分:0)

您观察到的 element is not attached to the page document 几乎是可能的。

分析:

在您的代码中,在迭代urlList时,我们正在打开url,然后等待WebElement XPATH//div/div ExpectedConditions > presence_of_element_located 子句设置为 driver.find_element_by_xpath('//div/div').get_attribute("innerHTML") ,这并不一定意味着该元素可见可点击

因此,接下来当您尝试ExpectedConditions时,找不到先前搜索/ find_element的引用。

解决方案:

您的问题的解决方案是将 presence_of_element_located 条款从 element_to_be_clickable 更改为 for url in urlList: driver.get(url) WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, '//div/div'))) myString = driver.find_element_by_xpath('//div/div').get_attribute("innerHTML") 检查该元素可见启用,以便您甚至可以点击它。

代码块:

您的优化代码块可能如下所示:

time.sleep(5)

您的其他解决方案:

您的其他解决方案有效,因为您试图通过List<T>覆盖Selenium的工作,这不是最佳做法的一部分。