您好我是Selenium
我正在使用Java library
,已经尝试了Chrome
和Firefox
驱动程序。
我正在运行一个循环。有趣的是,循环有时会工作3次,2次,并不总是在同一次迭代中失败。我认为它与某种竞争条件有关(比如等待页面加载)。如果我在调试模式下运行它似乎完美。
我已经尝试了其他答案的建议,例如wait explicitly
和implicitly
,但仍然没有帮助。也许如果你看到代码,你可以帮我一把。
这是一个循环。
WebDriverWait wait = new WebDriverWait(driver,20);
WebElement searchResults = driver.findElement(new By.ById("searchresults"));
searchResults = searchResults.findElement(new By.ByClassName("table"));
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.tagName("a")));
List<WebElement> list=searchResults.findElements(By.tagName("a"));
for(WebElement w: list) {
result.add(w.getAttribute("href")); //EXCEPTION HAPPENS ALWAYS HERE
}
解
解决方案是完全破解。我仍然不明白,但它完成了这项工作。如果有人明白为什么请告诉我。
我只是等待所有等待,它表现更好。如果在某些数据检查中抛出异常以确保我得到了我想要的全部内容,我还接受了@Cyril的建议来重新运行迭代。
WebDriverWait wait = new WebDriverWait(driver,20);
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(new By.ById("searchresults")));
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(new By.ByClassName("table")));
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.tagName("a")));
答案 0 :(得分:2)
StaleElementReferenceException表示您正在访问的DOM元素已更改或从DOM中删除。所以等到元素可见或存在没有帮助(之后它们仍然可以更新)。
您可以通过在查找任何DOM元素之前通过Thread.sleep
显式等待5秒来修复异常。
另一个选择是look up the element again if the exception is thrown。但它只适用于单个元素。
答案 1 :(得分:2)
为了避免StaleElementReferenceException
,你可以在find元素中获取属性。这是一个片段(nth-child
第一个索引是1):
List<WebElement> list=searchResults.findElements(By.tagName("a"));
for(int i = 1; i < list.length; i++) {
result.add(searchResults.findElement(By.cssSelector("a:nth-child(" + i + ")")).getAttribute("href"));
}
这样,异常的唯一机会是元素在findElement
和getAttribute
之间变化,这是不太可能的(或表元素更改 - searchResults
)。
当然,有更好的方法来实现这个,就像findElement
周围的包装函数或使用页面对象模式一样,但对于你的情况,它应该足够了。
编辑:你的解决方案可能有效,因为它使脚本等到页面完全加载,然后元素不再改变。