使用Selenium进行导航时的陈旧对象引用

时间:2017-08-01 09:43:58

标签: java selenium automation staleobjectstate

我一直在尝试一个简单的程序来导航和从新页面获取数据,在历史记录中返回并打开其他页面并获取数据等等,直到访问了所有链接并获取数据。

在下面的网站上获得结果后,我试图遍历我在第一列中获得的所有链接并逐个打开这些链接并从这些页面中提取文本。但是下面的程序只访问第一个链接并给出StaleElementReferenceException,我尝试使用Actions但它没有工作,我不知道JavascriptExecutor。我也尝试过在其他SO问题上发布的解决方案,其中一个是here以上的问题。我想在下面的代码和工作代码中纠正错误。

public class Selenium {

    private final static String CHROME_DRIVER = "C:\\Selenium\\chromedriver\\chromedriver.exe";
    private static WebDriver driver = null;
    private static WebDriverWait wait = null;

    private void setConnection() {
        try {
            System.setProperty("webdriver.chrome.driver", CHROME_DRIVER);
            driver = ChromeDriver.class.newInstance();
            wait = new WebDriverWait(driver, 5);
            driver.get("https://sanctionssearch.ofac.treas.gov");
            this.search();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void search() {
        try {
            driver.findElement(By.id("ctl00_MainContent_txtLastName")).sendKeys("Dawood");
            driver.findElement(By.id("ctl00_MainContent_btnSearch")).click();
            this.extractText();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void extractText() {
        try {
            List<WebElement> rows = driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr"));
            List<WebElement> links = null;
            for (int i = 1; i <= rows.size(); i++) {

                links = driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr/td[1]/a"));

                for (int j = 0; j < links.size(); j++) {
                    System.out.println(links.get(j).getText() + ", ");
                    links.get(j).click();
                    System.out.println("Afte click");
                    driver.findElement(By.id("ctl00_MainContent_btnBack")).click();
                    this.search();
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] ar) {
        Selenium object = new Selenium();
        object.setConnection();
    }

}

3 个答案:

答案 0 :(得分:0)

你得到StaleElementReference Exception的原因通常是因为你将元素存储到某个变量中,但是之后你做了一些操作并且页面已经改变(由于某些ajax响应),所以你的存储元素已经过时了。

在这种情况下,最好的解决方案不是将元素存储在任何变量中。

这应该有效。

links = driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr/td[1]/a"));

for (int j = 0; j < links.size(); j++) {
    System.out.println(links.get(j).getText() + ", ");
    driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr/td[1]/a")).get(j).click();
    System.out.println("Afte click");
    driver.findElement(By.id("ctl00_MainContent_btnBack")).click();
    this.search();
}

答案 1 :(得分:0)

一般来说,如果在启动webelement之后更改了元素属性或某些内容,我们将获得Stale Exception。例如,在某些情况下,如果用户尝试在同一页面上单击同一元素但在页面刷新后,则会获取staleelement异常。

为了解决这个问题,我们可以创建新的webelement,以防页面被更改或刷新。下面的代码可以给你一些想法。

示例:

 webElement element = driver.findElement(by.xpath("//*[@id='StackOverflow']"));
 element.click();
 //page is refreshed
 element.click();//This will obviously throw stale exception

为了解决这个问题,我们可以将xpath存储在某个字符串中,然后使用它创建一个新的webelement。

String xpath = "//*[@id='StackOverflow']";
driver.findElement(by.xpath(xpath)).click();
//page has been refreshed. Now create a new element and work on it
driver.fineElement(by.xpath(xpath)).click();   //This works

在这种情况下,我们正在收集一组webelements并迭代以获取文本。但是在收集了webelements和gettext抛出陈旧之后,似乎有一些变化。我们可以使用循环并在旅途中创建元素并获取文本。

for(int i = 0; i<5; i++)
{
  String value = driver.findElement(by.xpath("//.....["+i+"]")).getText);
  System.out.println(value);
}

希望这会对你有所帮助。感谢。

答案 2 :(得分:0)

请检查此代码

   private void extractText() {
        try {
            List<WebElement> rows = driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr"));
            List<WebElement> links = null;
            System.out.println(rows.size());
            for (int i = 0; i < rows.size(); i++) {
                links = driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr/td[1]/a"));
                WebElement ele= links.get(0);
                System.out.println(ele.getText() + ", ");
                ele.click();
                System.out.println("After click");
                driver.findElement(By.id("ctl00_MainContent_btnBack")).click();                     
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }