webdriver的元素定位很灵活,提供了多种定位方式:
- Id
- LinkText
- PartialLinkText
- Name
- TagName
- Xpath
- ClassName
- CssSelector
这些方法可以在org.openqa.selenium.By中找到,下面一一道来
假如有这样的需求:登录安居客网站,搜索陆家嘴附近的二手房源,网页是这样的
这个需求涉及到一个输入框和一个提交按钮,先查看网页源码
在输入框中输入“陆家嘴”然后点击“二手房”按钮,如果能跳转到陆家嘴相关页面就完成了这个需求,我们尝试用webdriver提供的元素定位方法来解决
Id
id是唯一标识,通过id来定位是非常快速和准确的
1 import org.openqa.selenium.By; 2 import org.openqa.selenium.WebDriver; 3 import org.openqa.selenium.chrome.ChromeDriver; 4 import org.openqa.selenium.WebElement; 5 6 public class NewTest 7 { 8 public static void main(String[] args) 9 { 10 System.setProperty("webdriver.chrome.driver", 11 "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"); 12 WebDriver driver = new ChromeDriver(); 13 driver.get("http://anjuke.com"); 14 15 //id 16 WebElement text=driver.findElement(By.id("glb_search0")); 17 text.sendKeys("陆家嘴"); 18 WebElement button=driver.findElement(By.id("btnSubmit")); 19 button.click(); 20 21 if(driver.getTitle().contains("陆家嘴")) 22 System.out.print("搜索成功,当前页面为"+driver.getTitle()); 23 else 24 System.out.print("搜索失败,当前页面为"+driver.getTitle()); 25 26 driver.quit(); 27 } 28 }
Name
提交表单时可以通过name属性获取数据,较id来说并不常用,有id属性时建议优先使用id属性,上面的源码中text输入框是有name属性的,button依然用id来获取(当然,如果测试需要的话可以修改源码,没有修改源码权限的自动化测试是很难进行的)。
1 import org.openqa.selenium.By; 2 import org.openqa.selenium.WebDriver; 3 import org.openqa.selenium.chrome.ChromeDriver; 4 import org.openqa.selenium.WebElement; 5 6 public class NewTest 7 { 8 public static void main(String[] args) 9 { 10 System.setProperty("webdriver.chrome.driver", 11 "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"); 12 WebDriver driver = new ChromeDriver(); 13 driver.get("http://anjuke.com"); 14 15 //name 16 WebElement text=driver.findElement(By.name("kw")); 17 text.sendKeys("陆家嘴"); 18 WebElement button=driver.findElement(By.id("btnSubmit")); 19 button.click(); 20 21 if(driver.getTitle().contains("陆家嘴")) 22 System.out.print("搜索成功,当前页面为"+driver.getTitle()); 23 else 24 System.out.print("搜索失败,当前页面为"+driver.getTitle()); 25 26 driver.quit(); 27 } 28 }
TagName
tagname一般用来获取批量数据,如统计页面链接数,输入框数量等等,用tagname来定位单一元素有点麻烦
1 import java.util.List; 2 import org.openqa.selenium.By; 3 import org.openqa.selenium.WebDriver; 4 import org.openqa.selenium.chrome.ChromeDriver; 5 import org.openqa.selenium.WebElement; 6 7 public class NewTest 8 { 9 public static void main(String[] args) 10 { 11 System.setProperty("webdriver.chrome.driver", 12 "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"); 13 WebDriver driver = new ChromeDriver(); 14 driver.get("http://anjuke.com"); 15 16 List<WebElement> inputs=driver.findElements(By.tagName("input")); 17 for(int index=0;index<inputs.size();index++){ 18 if(inputs.get(index).getAttribute("id").equals("glb_search0")) 19 inputs.get(index).sendKeys("陆家嘴"); 20 if(inputs.get(index).getAttribute("id").equals("btnSubmit")) 21 inputs.get(index).click(); 22 } 23 24 if(driver.getTitle().contains("陆家嘴")) 25 System.out.print("搜索成功,当前页面为"+driver.getTitle()); 26 else 27 System.out.print("搜索失败,当前页面为"+driver.getTitle()); 28 29 driver.quit(); 30 } 31 }
ClassName
当标签具有class属性时也可使用classname来定位,不过要注意class的值不是唯一的findElement方法返回匹配到的第一个元素
1 import org.openqa.selenium.By; 2 import org.openqa.selenium.WebDriver; 3 import org.openqa.selenium.chrome.ChromeDriver; 4 import org.openqa.selenium.WebElement; 5 6 public class NewTest 7 { 8 public static void main(String[] args) 9 { 10 System.setProperty("webdriver.chrome.driver", 11 "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"); 12 WebDriver driver = new ChromeDriver(); 13 driver.get("http://anjuke.com"); 14 15 //classname 16 WebElement text=driver.findElement(By.className("kw")); 17 text.sendKeys("陆家嘴"); 18 WebElement button=driver.findElement(By.className("btn")); 19 button.click(); 20 21 if(driver.getTitle().contains("陆家嘴")) 22 System.out.print("搜索成功,当前页面为"+driver.getTitle()); 23 else 24 System.out.print("搜索失败,当前页面为"+driver.getTitle()); 25 26 driver.quit(); 27 } 28 }
Xpath
xpath相关教程可以参考w3school上的教程,为了程序的统一性,平时工作中我都是使用xpath来定位元素的
1 import org.openqa.selenium.By; 2 import org.openqa.selenium.WebDriver; 3 import org.openqa.selenium.chrome.ChromeDriver; 4 import org.openqa.selenium.WebElement; 5 6 public class NewTest 7 { 8 public static void main(String[] args) 9 { 10 System.setProperty("webdriver.chrome.driver", 11 "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"); 12 WebDriver driver = new ChromeDriver(); 13 driver.get("http://anjuke.com"); 14 15 //xpath 16 WebElement text=driver.findElement(By.xpath("//input[@id='glb_search0']")); 17 text.sendKeys("陆家嘴"); 18 WebElement button=driver.findElement(By.xpath("//input[@id='btnSubmit']")); 19 button.click(); 20 21 if(driver.getTitle().contains("陆家嘴")) 22 System.out.print("搜索成功,当前页面为"+driver.getTitle()); 23 else 24 System.out.print("搜索失败,当前页面为"+driver.getTitle()); 25 26 driver.quit(); 27 } 28 }
CssSelector
CssSelector教程可以参考css3-selectors,CssSelector和xpath应该是实际工作中用的最多的定位方法了,两者没有优劣之分,看个人喜好吧。
1 import org.openqa.selenium.By; 2 import org.openqa.selenium.WebDriver; 3 import org.openqa.selenium.chrome.ChromeDriver; 4 import org.openqa.selenium.WebElement; 5 6 public class NewTest 7 { 8 public static void main(String[] args) 9 { 10 System.setProperty("webdriver.chrome.driver", 11 "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"); 12 WebDriver driver = new ChromeDriver(); 13 driver.get("http://anjuke.com"); 14 15 //cssSelector 16 WebElement text=driver.findElement(By.cssSelector("input[id='glb_search0']")); 17 text.sendKeys("陆家嘴"); 18 WebElement button=driver.findElement(By.cssSelector("input[id='btnSubmit']")); 19 button.click(); 20 21 if(driver.getTitle().contains("陆家嘴")) 22 System.out.print("搜索成功,当前页面为"+driver.getTitle()); 23 else 24 System.out.print("搜索失败,当前页面为"+driver.getTitle()); 25 26 driver.quit(); 27 } 28 }
LinkText和PartialLinkText
LinkText和PartialLinkText用来定位网页中的超链接,需要a标签中的全部或部分内容即可。例如,需要访问热门版块中的古美罗阳可以这样定位
1 import org.openqa.selenium.By; 2 import org.openqa.selenium.WebDriver; 3 import org.openqa.selenium.chrome.ChromeDriver; 4 import org.openqa.selenium.WebElement; 5 6 public class NewTest 7 { 8 public static void main(String[] args) 9 { 10 System.setProperty("webdriver.chrome.driver", 11 "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"); 12 WebDriver driver = new ChromeDriver(); 13 driver.get("http://anjuke.com"); 14 15 //linkText 16 WebElement a=driver.findElement(By.linkText("古美罗阳")); 17 a.click(); 18 //partialLinkText 19 //WebElement a=driver.findElement(By.partialLinkText("古美")); 20 //a.click(); 21 if(driver.getTitle().contains("古美罗阳")) 22 System.out.print("访问成功,当前页面为"+driver.getTitle()); 23 else 24 System.out.print("访问失败,当前页面为"+driver.getTitle()); 25 26 driver.quit(); 27 } 28 }
层级定位
webdriver提供了层级定位的方式即通过父元素访问其子元素,比如,输出热门版块下的所有版块
1 import java.util.List; 2 import org.openqa.selenium.By; 3 import org.openqa.selenium.WebDriver; 4 import org.openqa.selenium.chrome.ChromeDriver; 5 import org.openqa.selenium.WebElement; 6 7 public class NewTest 8 { 9 public static void main(String[] args) 10 { 11 System.setProperty("webdriver.chrome.driver", 12 "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"); 13 WebDriver driver = new ChromeDriver(); 14 driver.get("http://anjuke.com"); 15 16 17 WebElement element=driver.findElement(By.xpath("//div[@id='content_Rd0']/dl[@class='dl0']/dd")); 18 19 List<WebElement> links=element.findElements(By.tagName("a")); 20 21 for(int index=0;index<links.size();index++){ 22 System.out.println(links.get(index).getAttribute("text")); 23 } 24 25 driver.quit(); 26 } 27 }