如何使用selenium java从google搜索中单击不在第一页的结果
我正试图用SeleniumWebDriver浏览谷歌的搜索结果。我有一个界面供用户插入单词进行搜索,并选择网站标题。如果结果不在第一页,驱动程序应转到下一页查找站点,如果不在下一页,则转到下一页,依此类推。。 不知何故,我无法超越第二页的结尾。如果我确实到达了第二页,并且正确的站点就在那里,那么驱动程序就不会点击它。 以下是一些Java代码:如何使用selenium java从google搜索中单击不在第一页的结果,java,selenium,selenium-webdriver,Java,Selenium,Selenium Webdriver,我正试图用SeleniumWebDriver浏览谷歌的搜索结果。我有一个界面供用户插入单词进行搜索,并选择网站标题。如果结果不在第一页,驱动程序应转到下一页查找站点,如果不在下一页,则转到下一页,依此类推。。 不知何故,我无法超越第二页的结尾。如果我确实到达了第二页,并且正确的站点就在那里,那么驱动程序就不会点击它。 以下是一些Java代码: private void setLoopNum(int l){ String getText = urlText.getText();
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
}
每次linkElements中的任何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.findElement应该只返回一个空列表,而不是抛出一些异常,并且foreach循环不会运行,但在这两种情况下,都不会有锚pnnext,这将导致driver.findElement在搜索时抛出异常。有几种方法可以防止这种情况,例如编写一个小包装函数IIRC,它们在Selenium网站的某处有一个简单的findelementwithtimeoutwait实现。我建议您选择/编写一个并开始使用它,而不是原始的Selenium函数。代码中缺少的三点: 首先,在代码中,您只查找列表中的第一个元素 其次,在getAttribute中,您传递的是链接而不是href: 应该是:
if(eachResult.getAttribute("href").equals(getSiteName)){
第三,单击next,页面将通过GoogleAjax Api加载。因此,webdriver click永远不会阻止代码的执行,只会加载带有上一页链接的linkElements。为了避免这种情况,请让驱动程序刷新,或者在代码中设置一些等待条件
您可以试用以下代码:
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
编辑:
你的意思是你的代码只检查结果到2页吗?是的,如果有的话,它只会转到第二页。永远不要超过这个。谢谢,但它不起作用。它被卡在第一个if语句上:ifeachResult.getAttributegetSiteName.EqualGetSiteName也不会转到下一页,很抱歉问这个问题,但是页码在代码中没有用处:编辑我的答案时,我没有更正您将站点名称作为要评估的属性的名称传递。它应该是href,因为您希望查看href以查看其值是否为您想要的URL。它可能会返回null,然后当您尝试评估它是否等于您的URL时,它会抛出一个异常。至于页码,我用了你的变量,使它更实用。我不知道你要用它做什么。谢谢你的回答,但是搜索只会转到第二页,而不是第三页或其他。我回家后会测试它。谢谢,即使这样,如果找不到网站,程序也只会转到第二页。此外,它只找到第一个元素,因为它看起来像只有当第一个结果是正确的,它点击它,如果任何其他它不是。也许我需要将列表转换为ArrayList,然后遍历它直到找到正确的页面…你确定它只转到第二页吗?因为当我在这里发布这个答案时,我在第5页上用我期望的链接运行了5次,这也使循环值保持在3…:D N将列表转换为ArrayList是什么意思?它没有超出第二页。即使在第三个上出现了预期结果。如果您上传java文件并与我们共享,这将是一件好事…似乎有什么阻碍了您的环境…如果您可以共享,我可以检查我的本地环境…文件位于该链接中:
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
}