如何使用selenium java单击不在第一页上的谷歌搜索结果

时间:2014-12-22 13:13:24

标签: java selenium selenium-webdriver

我正在尝试使用selenium webdriver浏览google的搜索结果。我有一个界面供用户插入搜索和网站标题来选择。如果结果不在第一页上,则驱动程序应转到下一页以查找该站点,如果不是,则不要到下一页等等。 不知怎的,如果我进入第二页并且正确的网站在那里,我没有设法超越第二页结束,驱动程序没有点击它。 以下是Java中的一些代码:

private void setLoopNum(int l){

        String getText = urlText.getText();
        String getSiteName = linkToChoose.getText();

        System.setProperty("webdriver.chrome.driver", "C:\\selenium-2.44.0\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize(); //Maximize window
        driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);

        for(int i=0;i<l;i++){
            //WebDriver driver =  new FirefoxDriver();
            driver.get("http://google.com");
            //driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
            WebElement element1 = driver.findElement(By.name("q"));
            element1.sendKeys(getText);
            element1.submit();
            //driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS); //wait for page to load
                //try{
                boolean flag = false;
                String page_number = "1";
                while(! flag){
                //get all the search results 
                List<WebElement> linkElements = driver.findElements(By.xpath("//h3[@class='r']/a"));

                for(WebElement eachResult: linkElements){
                    if(eachResult.getAttribute(getSiteName).equals(getSiteName)){           
                        eachResult.findElement(By.xpath("//a[@href='" + getSiteName + "']")).click();;
                        flag =true;
                    }else{
                        driver.findElement(By.xpath("//a[@id='pnnext']/span")).click();
                        linkElements.clear(); //celean list
                        break;
                    }   //end else
                }
                }//end while loop
                //}catch(Exception e){
                //  System.out.println("Error!");
            //  }
        }
        driver.quit(); //clear memory

    }

2 个答案:

答案 0 :(得分:0)

每当链接元素中的任何Web元素不是您要查找的内容时,您似乎都会移动到下一页。这会导致问题,因为您需要重新定位任何重新渲染的元素。

试一试:

boolean found = false;
            int page_number = 1; //If you need this as a string, you can make it one later
            while(! found){
            //get all the search results 
            List<WebElement> linkElements = driver.findElements(By.xpath("//h3[@class='r']/a"));

            for(WebElement result: linkElements){
                if(result.getAttribute("href").equals(getSiteName))
                {           
                    result.click();
                    found=true;
                    break;
                }
            }//End of foreach-loop
                if(!found){
                    driver.findElement(By.xpath("//a[@id='pnnext']/span")).click();
                    page_number++;
                }
            }//End of while-loop

此外,您还希望获得一些元素发现保护。假设您搜索的结果为0或者只有一页(尽管很少见)。在第一种情况下,你很幸运,因为driver.findElements()应该只返回一个空列表而不是抛出一些异常,并且foreach循环只是不会运行,但在这两种情况下,都赢了&# 39;是#pnnext的锚点,它会导致driver.findElement在搜索时抛出异常。有几种方法可以防止这种情况发生,例如编写一个小的包装器函数(IIRC,它们在selenium网站上的某个地方有一个简单的findelementwithwithoutoutwait()实现)。我建议你选择/写一个并开始使用它,而不是原始的Selenium函数。

答案 1 :(得分:0)

您的代码中缺少三件事: 首先,在您的代码中,您只查找列表中的第一个元素。

其次,在getAttribute中,您传递的是链接而不是 href

if(eachResult.getAttribute(getSiteName).equals(getSiteName)){

它应该是:

if(eachResult.getAttribute("href").equals(getSiteName)){

第三次,点击下一步该页面是通过Google Ajax Api加载的。因此,webdriver click将永远不会阻止您的代码执行,并load linkElements with previous page links only。为避免这种情况,请让驱动程序刷新或等待代码中的某些条件。

可以尝试使用此代码:

WebDriverWait wait = new WebDriverWait(driver, 10)
while (!flag) {
    // get all the search results
    linkElements = wait
        .until(ExpectedConditions
            .presenceOfAllElementsLocatedBy(By
                .xpath("//h3[@class='r']/a")));

    for (WebElement eachResult : linkElements) {
        if (eachResult.getAttribute("href").contains(getSiteName)) {
            eachResult.click();
            flag = true;
            break;
        }
    }
    if (!flag) {
        driver.findElement(By.xpath("//a[@id='pnnext']/span[1]"))
            .click();
        pageNumber++;
        linkElements.clear(); // celean list
        wait.until(ExpectedConditions
            .textToBePresentInElementLocated(
                By.xpath("//td[@class='cur']"), pageNumber
                    + "")); // Checking whether page number is changed as expected.
    }
}// end while loop

修改

List<WebElement> linkElements = new ArrayList<WebElement>();
ListIterator<WebElement> itr = null;
System.setProperty("webdriver.chrome.driver",
    "webdrivers/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize(); // Maximize window
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
        driver.get("http://google.com");
WebElement element1 = driver.findElement(By.name("q"));
WebElement toClick = null;
element1.sendKeys(getText);
element1.submit();

// try{
int pageNumber = 1;
WebDriverWait wait = new WebDriverWait(driver, 10);
boolean flag = false;
while (!flag) {
    linkElements = wait.until(ExpectedConditions
        .presenceOfAllElementsLocatedBy(By
            .xpath("//h3[@class='r']/a")));
    itr = linkElements.listIterator(); // re-initializing iterator
    while (itr.hasNext()) {
        toClick = itr.next();
        if (toClick.getAttribute("href").contains(getSiteName)) {
            toClick.click();
            flag = true;
            break;
        }
    }
    if (!flag) {
        driver.findElement(By.xpath("//a[@id='pnnext']/span[1]"))
            .click();
        pageNumber++;
        linkElements.clear(); // clean list
        wait.until(ExpectedConditions.textToBePresentInElementLocated(
            By.xpath("//td[@class='cur']"), pageNumber + ""));
    }
}
driver.quit(); // clear memory
}