尝试打印链接名称时获取StaleElementReferenceException
我正在尝试打印谷歌搜索中显示的前5页链接..但是获取StateElementReferenceException不确定哪个出错了..
public class GoogleCoInTest { static WebDriver driver = null; public static void main(String[] args) throws InterruptedException { System.setProperty("webdriver.gecko.driver", "D:\\bala back up\\personel\\selenium\\Jars\\Drivers\\geckodriver.exe"); driver=new FirefoxDriver(); driver.manage().window().maximize(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://www.google.co.in/"); //driver.findElement(By.xpath("//input[class='gsfi']")).sendKeys("Banduchode");; WebElement search=driver.findElement(By.cssSelector("input#lst-ib")); search.sendKeys("Banduchode"); search.sendKeys(Keys.ENTER); printLinksName(); List fiveLinks=driver.findElements(By.xpath(".//*[@id='nav']/tbody/tr/td/a")); for(int i=0;i<5;i++){ System.out.println(fiveLinks.get(i).getText()); fiveLinks.get(i).click(); Thread.sleep(5000); printLinksName(); } } public static void printLinksName() throws InterruptedException{ List allLinks=driver.findElements(By.xpath("//*[@id='rso']/div/div/div/div/div/h3/a")); System.out.println(allLinks.size()); //print all list for(int i=0;i<allLinks.size();i++){ System.out.println("Sno"+(i+1)+":"+allLinks.get(i).getText()); } } }
它打印得很好,直到第二页,但在我得到之后
Exception in thread "main" org.openqa.selenium.StaleElementReferenceException: The element reference of stale: either the element is no longer attached to the DOM or the page has been refreshed For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
以下是您的问题的答案:
- 您的脚本按预期打印前2页的结果。
- 第一次调用
printLinksName()
时它会起作用。 - 接下来,将10个PageNumbers存储在
WebElement
类型的Generic List
中。 - 第一次在
for()
循环中单击Page 2
的WebElement
,然后通过调用printLinksName()
打印所有链接。 - 当您在
for()
循环中进行第二次迭代时,由于DOM已更改,List
的引用将丢失。 因此,您会看到fiveLinks StaleElementReferenceException
。
解
避免StaleElementReferenceException
简单解决方案是移动代码行List
在for()
循环中。 所以你的代码块看起来像:
import java.util.List; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; public class Q44970712_stale { static WebDriver driver = null; public static void main(String[] args) throws InterruptedException { System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe"); driver=new FirefoxDriver(); driver.manage().window().maximize(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://www.google.co.in/"); //driver.findElement(By.xpath("//input[class='gsfi']")).sendKeys("Banduchode");; WebElement search=driver.findElement(By.cssSelector("input#lst-ib")); search.sendKeys("Banduchode"); search.sendKeys(Keys.ENTER); printLinksName(); for(int i=0;i<5;i++) { List fiveLinks=driver.findElements(By.xpath(".//*[@id='nav']/tbody/tr/td/a")); System.out.println(fiveLinks.get(i).getText()); fiveLinks.get(i).click(); Thread.sleep(5000); printLinksName(); } } public static void printLinksName() throws InterruptedException { List allLinks=driver.findElements(By.xpath("//*[@id='rso']/div/div/div/div/div/h3/a")); System.out.println(allLinks.size()); //print all list for(int i=0;i
注意:在这个简单的解决方案中,当你完成第二页的打印时,接下来你将通过
xpath
创建List
fiveLinks .//*[@id='nav']/tbody/tr/td/a
,第二次使用.//*[@id='nav']/tbody/tr/td/a
List
fiveLinks xpath
.//*[@id='nav']/tbody/tr/td/a
List
fiveLinks xpath
.//*[@id='nav']/tbody/tr/td/a
,Page 1
是第一个存储在fiveLinks
列表中的fiveLinks
。 因此,您可能会再次被重定向到Page 1
。 为避免这种情况,您可以考虑使用正确的索引来获取xpath
帮助。
如果这回答你的问题,请告诉我。
您的脚本正在尝试单击第一页上的每个链接,这会将您带到一个新页面。 一旦它完成该页面上的工作,它似乎不会返回到第一页,因此脚本无法找到列表中的下一个链接。
即使它确实返回到第一页,您仍然会有一个陈旧的元素,因为页面已经重新加载。 您需要通过其他内容跟踪第一页中的链接(比如href可能?),然后在单击之前再次通过该标识找到该链接。
这是由于在移动到另一个页面后引用对象。 请尝试在最后的for循环中添加以下行。 它可能会解决陈旧的参考问题。
driver.navigate().back(); fiveLinks=driver.findElements(By.xpath(".//*[@id='nav']/tbody/tr/td/a"));