Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Selenium中的过时元素引用错误_Java_Selenium - Fatal编程技术网

Java 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

运行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 ( 
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所以详细的解释真的很有帮助