1、什么是元素定位
根据元素的某个特征在网页中找到对应的元素,定位元素的目的是为了操作元素,在Web自动化中,定位元素是后续一切操作的前提条件。
2、元素的八大定位方式
2.1、id : 根据标签/元素的id属性值定位
一般情况下元素的id是唯一的,所以通过这个方法可以很轻松地找到元素。
eg:通过id定位百度的输入框并发送值
# 创建浏览器对象driver
# 百度输入框的id值为kw,需要导入定位选择方式By
from selenium.webdriver.common.by import By
driver.find_element(By.ID, "kw").send_keys("python")
不能通过id定义的情况
- id是动态变化的
- 不存在id
- id的属性值不唯一
- id中有数字不用
2.2、name:根据标签/元素的name属性值定位
一般情况下元素的名称也是唯一的,所以通过名称可以找到元素。
eg:通过name定位百度的输入框并发送值
# 创建浏览器对象driver
# 百度输入框的name值为wd,需要导入定位选择方式By
from selenium.webdriver.common.by import By
driver.find_element(By.NAME, "wd").send_keys("python")
2.3、tag_name:根据标签/元素的tag_name属性值定位
根据元素的标签名称来定位元素,因为一个页面上往往有多个同名的标签,所以这种方法的局限性较大。这个方法返回值的类型是一个webelement对象。
eg:定位input标签
# 创建浏览器对象driver
# 定位input标签,需要导入定位选择方式By
from selenium.webdriver.common.by import By
element_input = driver.find_element(By.TAG_NAME, 'input')
2.4、class_name:根据标签/元素的class_name属性定位
根据元素的类名定位元素,需要注意的是作为定位条件的类名必须是唯一的,否则会定位不到想找的元素,当元素有多个类名时, 选择其中一个唯一的类名来定位。
# 创建浏览器对象driver
# 通过类名来定位这个元素,并输入Selenium WebDriver
driver.find_element(By.CLASS_NAME, "s_ipt").send_keys("python")
# 选择其中一个唯一的类名s_btn来定位元素, 中间的空格也可用使用.代替
driver.find_element(By.CLASS_NAME, "bg.s_btn").click()
2.5、link_text:根据超链接的文本进行定位
根据元素的链接文本来定位元素,适用于超链接元素,超链接元素的标签是a,在一个页面上,超链接文本一般是唯一的。返回值是一个WebElement对象
# 创建浏览器对象driver
# 定位文本是新闻的超链接元素,并点击
driver.find_element(By.LINK_NAME,"新闻").click()
2.6、partial_link_text:根据超链接的模糊文本进行定位
根据元素的链接文本的一部分来定位元素,要注意选取的部分文本要唯一,否则定位不到需要找的元素。
# 创建浏览器对象driver
# 在京东页面定位文本包含家用的超链接元素,并点击
driver.find_element(By.PARTIAL_LINK_NAME,"家用").click()
2.7、xpath:根据xpath表达式定位
特殊符号表示的含义:
/ :表示根或者子节点
//:任意节点
@ :表示当前的节点的对象
* :表示通配符,只针对标签名
[ ]:相当于过滤器
(1)、绝对路径
根据网页中的层级目录递进进行查找对应元素。
eg:查找百度的输入框,并发送元素“Python”
PS:这个例子有两个查询结果,定位时会返回在前面的结果,这个例子不是很合适,但是我懒了。
# 创建浏览器对象driver
# 通过XPath定位用户名输入框
driver.find_element(By.XPATH,"/html/body/div/div/div/div/div/form/span/input").send_keys("四川")
(2)、//标签名[@属性名=属性值]
把相对路径和属性结合起来查找对应元素。
# 创建浏览器对象driver
# 定位百度首页输入框,输入Python
driver.find_element(By.XPATH,'//input[@id="kw"]').send_keys("Python")
# 定位百度一下按钮,点击
driver.find_element(By.XPATH,'//input[@id="su"]').click()
(3)、//标签名[text()=值]
如果一个标签有文本,并且文本在页面中是唯一的,可以通过指定文本来定位元素。
eg:定位百度首页中的文本为“新闻”的内容
# 创建浏览器对象driver
# 定位文本是新闻的标签
driver.find_element(By.XPATH, "//a[text()='新闻']").click()
(4)、//标签名[contains(@ 属性,值)]
根据标签中包含的部分内容来定位。
eg:定位标签中包含 "百度一下" 的标签
# 创建浏览器对象driver
# 定位标签中包含 "百度一下" 的标签, 并点击一下
driver.find_element(By.XPATH, '//input[contains(@value,"百度一下")]').click()
(5)、//标签名[starts-with(@ 属性,值)]
根据标签中开头的部分内容来定位。
eg:定位标签中以 "result_t" 开头的标签
# 创建浏览器对象driver
# 定位标签中以 "result_t" 开头的标签
element = driver.find_element(By.XPATH, '//*[starts-with(@id,"result_t")]')
(6)、//标签名[@ 属性名1=值1 and @ 属性名2=值2]
如果通过一个属性不能准确地定位到元素,可以使用逻辑运算符and来指定多个属性定位元素。
# 创建浏览器对象driver
# 定位百度输入框,输入Python
driver.find_element(By.XPATH,"//input[@id='kw' and @name='wd']").send_keys("Python")
# 定位百度一下按钮,点击
driver.find_element(By.XPATH,"//input[@id='su' and @value='百度一下']").click()
(7)、//标签[@ 属性名=值]/标签名[n]
当通过一个属性不能准确地定位到元素,可以使用逻辑运算符and来指定多个属性来定位元素。
eg:定位百度输入框并发送值“python”
# 创建浏览器对象driver
# 定位百度输入框,输入Python
driver.find_element(By.XPATH,"//input[@id='kw' and @name='wd']").send_keys("Python")
(8)、//标签名[ends-with(@ 属性,值)]------已被移除
2.8、css_selector:根据样式表达式进行定位
(1)、#id:用元素的id属性进行定位
# 创建浏览器对象driver
# 定位百度一下输入框,输入Python
driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("python")
(2)、 .class . class:以元素的类名进行定位
如果元素有一个class属性,就通过.class进行定位
如果元素有多个class属性,class类名之间用.来连接
# 创建浏览器对象driver
# 定位百度输入框,输入Python
driver.find_element(By.CSS_SELECTOR, ".s_ipt").send_keys("python")
#定位百度一下按钮,这个元素有多个class值,可以指定多个类名定位,也可以选择其中一个唯一的类名来定位
driver.find_element(By.CSS_SELECTOR, ".bg.s_btn").click()
(3)、标签名:以元素的标签的名称进行定位
直接写标签名,前面不需要加任何符号
一般结合其他属性使用
# 创建浏览器对象driver
# 定位百度输入框,输入Python
driver.find_element(By.CSS_SELECTOR, "input").send_keys("python")
(4)、标签名#id:以元素的标签名的名称和id属性进行定位
# 创建浏览器对象driver
# 定位百度输入框,输入Python
driver.find_element(By.CSS_SELECTOR, "input#kw").send_keys("python")
(5)、标签名.class:以元素的标签名的名称和class属性进行定位
# 创建浏览器对象driver
# 定位百度输入框,输入Python
driver.find_element(By.CSS_SELECTOR, "input.s_ipt").send_keys("python")
(6)、[属性名=值]:以属性的值进行定位
# 创建浏览器对象driver
# 定位百度输入框,输入Python
driver.find_element(By.CSS_SELECTOR, "[name='wd']").send_keys("python")
(7)、[属性名1=值1][属性名2=值2]:以属性1的值1和属性2的值2进行定位
# 创建浏览器对象driver
# 定位百度输入框,输入Python
driver.find_element(By.CSS_SELECTOR, "[name='wd']").send_keys("python")
(8)、标签名[属性名=值]:以属性等于一个值进行定位;
标签名[属性名1=值1][属性名2=值2]:多个属性值进行定位
# 创建浏览器对象driver
# 标签和单个属性值进行定位,并发送值
driver.find_element(By.CSS_SELECTOR, "input[name='wd']").send_keys("python")
# 标签和多个属性值进行定位,并发送值
driver.find_element(By.CSS_SELECTOR, "input[name='wd']").send_keys("python")
(9)、标签名[属性名*=值]:以属性包含一个值进行定位
# 创建浏览器对象driver
# 定位百度一下按钮,点击
driver.find_element(By.CSS_SELECTOR, "input[value*='百度']").click()
(10)、标签名[属性名^=值]:以属性的开始值进行定位
# 创建浏览器对象driver
# 定位百度一下按钮,并点击
driver.find_element(By.CSS_SELECTOR, "input[value^='百度']").click()
(11)、标签名[属性名$=值]:以属性的结束值进行定位
# 创建浏览器对象driver
# 定位百度一下按钮,并点击
driver.find_element(By.CSS_SELECTOR, "input[value$='一下']").click()
(12)、标签名 > 子标签[属性名$=值] + 兄弟标签名
# 创建浏览器对象driver
driver.find_element(By.CSS_SELECTOR, '#s-top-left>a[href$="tieba.baidu.com/"] + a').click()
(13)、定义兄弟标签
a、标签名 > 子标签 :first-child
定位标签下该子标签的第一个子标签
# 创建浏览器对象driver
# 定位百度输入框所在目录下的的第一个标签,输入Python
# 使用fist-child
driver.find_element(By.CSS_SELECTOR, "span#s_kw_wrap>input:first-child").send_keys("Python")
b、标签名 > 子标签 :nth-child(n)
定位标签下该子标签的第n个子标签
# 创建浏览器对象driver
# 定位百度输入框,输入Python
# 使用nth-child(n)
driver.find_element(By.CSS_SELECTOR, "span#s_kw_wrap>input:nth-child(2)").send_keys("Python")
c、标签名 > 子标签 :last-child
定位标签下该子标签的最后一个子标签-----慎用
# 创建浏览器对象driver
# 定位百度输入框,输入Python
# 使用last-child
driver.find_element(By.CSS_SELECTOR, "span#s_kw_wrap>input:last-child").send_keys("Python")