慕课网(imooc)Selenium自动化学习笔记03:遍历打印课程列表及获取下一页报错处理

这次练习遍历课程列表中的课程,然后分别点击进入详情页,然后再返回到上一页
具体步骤:
1. 打开课程列表页;
2. 打开详情页;
3. 返回到列表页,继续循环
4. 进入下一页

请注意:当前代码并不完善,只是循环了第一页,然后进入下一页即停止。后续下一页循环,直到全部页面循环完毕的代码,正在研究中……

具体实施:
1. 获取当前页面课程列表

   /**
     * 获取当前页面所有课程list
     */
    public List listElement(){
        List listString = new ArrayList();
        WebElement element = driver.findElement(By.className("shizhan-course-list"));
        List listElement = element.findElements(By.className("shizhan-course-box"));
        for(WebElement el:listElement){
            String titleCourse = el.findElement(By.className("shizan-name")).getText();
            listString.add(titleCourse);
        }
        return listString;
    }

2.循环遍历获取到的列表

@Test
    public void courseList(){
        driver.get("http://coding.imooc.com");
        List listCourse = driver.listElement();

//      WebElement nextPage = driver.findElement(By.xpath("//*[text()='下一页']"));
            for(int i=0;i
                driver.findElement(By.xpath("//*[contains(text(),'"+listCourse.get(i)+"')]")).click();
                System.out.println(listCourse.get(i).toString());

                        driver.back();
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                }

            driver.findElement(By.xpath("//*[text()='下一页']")).click();
    }

注意,这里如果是这么写,将会报错:

element not found in the cache - perhaps the page has changed since it was looked up

WebElement nextPage = driver.findElement(By.xpath("//*[text()='下一页']"));
......
nextPage.click();

解决办法:

driver.findElement(By.xpath("//*[text()='下一页']")).click();

具体详见:element not found in the cache - perhaps the page has changed since it was looked up
慕课网(imooc)Selenium自动化学习笔记03:遍历打印课程列表及获取下一页报错处理_第1张图片
报错原因大概为:
The browser rebuilds the DOM structure of the dynamic pages, so the elements do not need to keep you have to find them before to use.

而且,不要试图都去Thread.Sleep(2000);这并不是一个Good idea.
其实我也不知道为啥,人家大神这么说。仅此记载,以后遇到类似问题,就不会报错了。

注意要点:
当在首页点击第一个课程信息进入详情页,然后返回到首页时,页面已经刷新,之前获取到的课程定位信息已经失效,那么就会报错。
解决办法
先将页面内容获取到然后存储起来,再遍历存储的内容

List listElement = element.findElements(By.className("shizhan-course-box"));
        for(WebElement el:listElement){
            //针对页面刷新,之前获取到的定位信息失效;
            //解决办法:先将页面内容获取到然后存储起来,再遍历存储的内容
            String titleCourse = el.findElement(By.className("shizan-name")).getText();
            listString.add(titleCourse);
        }

以后遇到这类问题,可以参考!

后来找到了一个文章关于“StaleElementReferenException”
http://www.seleniumeasy.com/selenium-tutorials/staleelementreferenceexception-in-selenium-webdriver
讲的是关于“页面刷新了或者元素移除了,怎么办”

This Exception occurs when driver is trying to perform action on the element which is no longer exists or not valid.

WebElement ele = driver.findElement(By.id("sample"));
// Before clicking some thing happened and DOM has changed due to page refresh, or element is removed and re-added
ele.click();

Now at this point, the element which you're clicking is no longer valid.

When Javascript / Ajax updates the page between the findElement and the click call then will get a StaleElementException. Here the reference to the element in the DOM that previously had becomes stale and we can no longer able to use this reference (click call) to interact with the element in the DOM.

慕课网(imooc)Selenium自动化学习笔记03:遍历打印课程列表及获取下一页报错处理_第2张图片

// while the following loop runs, the DOM changes or page refreshed, or element removed and re-added
wait.until(elementIdentified(By.id("element")));        

//Or like
By byPageLoc = By.id("element");
wait.until(ExpectedConditions.elementToBeClickable(byPageLoc));

// now try to click the element
driver.findElement(By.id("element")).click();
private static Function elementIdentified(final By locator) {
    return new Function() {
        @Override
        public WebElement apply(WebDriver driver) {
            return driver.findElement(locator);
        }
    };
}

用到了一个内部类,这是一个新的知识点

现在发现,关于页面刷新后再去定位和点击,可能有两个异常抛出,但连个说法都不一样,甚至矛盾,有待实践证明。待续~~~

你可能感兴趣的:(java,selenium)