我正在尝试使用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
}
答案 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
}