Java Selenium中的过时元素引用错误
运行selenium测试时出错Java Selenium中的过时元素引用错误,java,selenium,Java,Selenium,运行selenium测试时出错 Exception in thread "main" org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document (Session info: chrome=63.0.3239.84) (Driver info: chromedriver=2.34.522932 ( 4
Exception in thread "main"
org.openqa.selenium.StaleElementReferenceException: stale element
reference: element is not attached to the page document
(Session info: chrome=63.0.3239.84)
(Driver info: chromedriver=2.34.522932 (
4140ab217e1ca1bec0c4b4d1b148f3361eb3a03e),platform=Mac OS X 10.12.6
x86_64) (WARNING: The server did not provide any stacktrace
information)
Command duration or timeout: 0 milliseconds
For documentation on this error, please visit:
http://seleniumhq.org/exceptions/stale_element_reference.html
01T19:05:14.666Z'.
这是密码
List<WebElement> category =
driver.findElements(By.className("a2s-skill-block"));
for(int i = 0;i<category.size();i++) {
category.get(i).click();
Thread.sleep(7000);
driver.navigate().back();
// WebElement skills1 = driver.findElement(By.id("iApps"));
//skills1.click();
Thread.sleep(15000);
}
列表类别=
driver.findElements(按.className(“a2s技能块”);
for(int i=0;i您在for循环之前找到页面上的所有类别。当您单击循环中的某个内容进入另一个页面时,实际上“过时元素引用”已被触发,您最终无需后悔返回到最后一页
以下条件将触发“过时元素引用”
条件1
当您上次进入页面并至少离开页面一次(即使您再次返回)时,请使用find元素
您可以认为,当您输入页面时,Selenium将为Selenium内部的页面分配一个引用,即使您输入了相同的页面,但Selenium无法知道它们是相同的,因此它将分配一个新引用
只能使用页面引用与当前页面相同的已找到元素
条件2
停留在页面上(不要离开页面),但您的脚本触发了找到的元素的HTML DOM节点更改/重新附加/删除。例如,DOM节点的某些属性已更改,或者DOM节点已删除并重新添加,请不要更改所有附件
因此,在找到的元素的DOM节点上的任何更改/移动都将触发“Stale Element reference”。您可以认为条件1只是更改/移动DOM节点的另一种方式
为了解决这个问题,您应该读取一个all category属性,该属性可用于在循环中稍后识别该类别
下面的代码假设每个类别都有唯一的文本:
List<WebElement> category =
driver.findElements(By.className("a2s-skill-block"));
List<String> categoryTexts = new ArrayList<String>();
for(WebElement it: category) {
categoryTexts.add(it.getText());
}
for(int i = 0;i<category.size();i++) {
driver.findElement(By.xpath("//*[text()='"+categoryTexts.get(i)+"']")).click();
Thread.sleep(7000);
driver.navigate().back();
Thread.sleep(15000);
列表类别=
driver.findElements(按.className(“a2s技能块”);
List categoryTexts=new ArrayList();
for(WebElement it:category){
add(it.getText());
}
对于(int i=0;i您应该花一些时间阅读并理解什么是StaleElementReferenceException
。了解它的原因以及如何避免它非常重要
在本例中,您正在刮除页面并加载类别
,其中包含第1页中的元素。然后单击某个链接将您带到第2页。此时,类别
中的所有引用都已过时,但由于您尚未访问任何变量,因此尚未引发异常。然后使用.back()
返回第1页,尝试对类别执行操作,并获取异常
为了避免这种情况,在从另一个页面使用.back()
之后,您需要在第1页上重新将元素划分为类别
。一种方法是我在下面写的方法。该页面在每个循环的底部被刮除
List<WebElement> category = driver.findElements(By.className("a2s-skill-block"));
for (int i = 0; i < category.size(); i++)
{
category.get(i).click();
// sleeps are a bad practice, use WebDriverWait instead
driver.navigate().back();
driver.findElement(By.id("iApps")).click();
// sleeps are a bad practice, use WebDriverWait instead
category = driver.findElements(By.className("a2s-skill-block"));
}
List category=driver.findElements(按.className(“a2s技能块”);
对于(int i=0;i
非常感谢您的帮助!这对我很有用,而且我对今后如何解决这类问题有了很好的想法。如果这或任何其他答案有用,请向上投票。一旦找到问题的答案,请将其标记为已接受,这样问题就不会没有答案。谢谢,这很有效。Al所以详细的解释真的很有帮助