问题
I'm trying to print first 5 pages links displayed in google search.. But getting StateElementReferenceException Not sure which one went wrong..
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<WebElement> 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<WebElement> 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());
}
}
}
it prints fine till 2nd page , but there after I am getting
Exception in thread "main" org.openqa.selenium.StaleElementReferenceException: The element reference of <a class="fl"> 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
回答1:
A couple of things:
- Your script prints the result from the first 2 pages as expected.
- When you call
printLinksName()
for the first time it works. - Next, you are storing the 10 PageNumbers in a
Generic List
of typeWebElement
. - First time within the
for()
loop you are clicking on theWebElement
ofPage 2
and then printing all the links by callingprintLinksName()
. - While you are in the second iteration within
for()
loop, the reference ofList<WebElement> fiveLinks
is lost as the DOM have changed. Hence, you seeStaleElementReferenceException
.
Solution
A simple solution to avoid StaleElementReferenceException
would be to move the line of code List<WebElement> fiveLinks=driver.findElements(By.xpath(".//*[@id='nav']/tbody/tr/td/a"));
with in the for()
loop. So your code block will look like:
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<WebElement> 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<WebElement> 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());
}
}
}
Note: In this simple solution when you finish printing the second page, next when you will create
List<WebElement> fiveLinks
throughxpath
with.//*[@id='nav']/tbody/tr/td/a
for second time,Page 1
is the first element which gets stored in thefiveLinks
List. Hence you may be again redirected toPage 1
. To avoid that you may consider to take help ofxpath
with proper indexing.
回答2:
your script is trying to click on each link from the first page, which brings you to a new page. once it completes work on that page, it doesn't seem to return to the first page, so the script can't find the next link in your list.
even if it did return to the first page, you would still have a stale element because the page has been reloaded. You'll need to keep track of the links in the first page by something else (like the href maybe?), and find the link again by that identifier before you click on it.
回答3:
This is due to referencing object after moving to another page. please try to add the following lines inside the for loops at the end. It may resolve stale reference issue.
driver.navigate().back();
fiveLinks=driver.findElements(By.xpath(".//*[@id='nav']/tbody/tr/td/a"));
来源:https://stackoverflow.com/questions/44970712/getting-staleelementreferenceexception-while-trying-print-the-link-names