selenium元素定位方法
元素定位是做UI自动化最基础也是最重要的部分之一了,搞定了元素定位,算是推开了web自动化的大门,即可走进web自动化的世界;
首先,我们需要认识元素。元素是可识别区分的属性。 Selenium 的 WebDriver 一共提供了九种定位方法,其中最常用的是前八种;

元素定位选择原则:
- 一般来说,如果 HTML 的 id 是可用的、唯一的,那么它就是在页面上定位元素的首选方法。它们的工作速度非常快,可以避免复杂的 DOM 遍历带来的大量处理。
- 如果没有唯一的 id,那么最好使用写得好的 CSS 选择器来查找元素。XPath 和 CSS 选择器一样好用,但是它语法很复杂,并且经常很难调试。尽管 XPath 选择器非常灵活,但是他们通常未经过浏览器厂商的性能测试,并且运行速度很慢。(xpath会遍历dom树,然后层层匹配,所以性能会偏慢)
- 基于链接文本和部分链接文本的选择策略有其缺点,即只能对链接元素起作用。此外,它们在 WebDriver 内部调用 XPath 选择器。
- 标签名可能是一种危险的定位元素的方法。页面上经常出现同一标签的多个元素。这在调用 findElements(By) 方法返回元素集合的时候非常有用。
建议尽可能保持定位器的紧凑性和可读性。使用 WebDriver 遍历 DOM 结构是一项性能花销很大的操作,搜索范围越小越好。
1、ID定位
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
try:
driver.get(url='<https://www.baidu.com/>')
time.sleep(3)
ele = driver.find_element(By.ID,"su")
print(ele)
except Exception as e:
raise e
finally:
driver.quit()
输出结果:
"D:\Program Files (x86)\Python39\python.exe" D:/Buyer_test_code/webuitest_jcmall/unit.py
<selenium.webdriver.remote.webelement.WebElement (session="8c9e8948493a5e9c8d40d90796652d13", element="ad1c838b-f7d5-4d50-af59-575518a86dbc")>
Process finished with exit code 0
输出结果是一个WebElement对象,对象中包含此次会话的session以及页面元素的element
- NAME定位

from selenium import webdriver
import time
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
try:
driver.get(url='<https://www.baidu.com/>')
time.sleep(3)
ele = driver.find_element(By.NAME,"wd")
print(ele)
except Exception as e:
raise e
finally:
driver.quit()
"D:\Program Files (x86)\Python39\python.exe" D:/Buyer_test_code/webuitest_jcmall/unit.py
<selenium.webdriver.remote.webelement.WebElement (session="36ee840cad5e4d18dcdbf8bee7903c04", element="1ce2702e-7777-4ea4-ac97-fa05dc3a82f2")>
Process finished with exit code 0
-
CLASS_NAME定位
from selenium import webdriver
import timefrom selenium.webdriver.common.by import By
driver = webdriver.Chrome()
try:
driver.get(url='https://www.baidu.com/')
time.sleep(3)
ele = driver.find_element(By.CLASS_NAME,"s_ipt")
print(ele)
except Exception as e:
raise e
finally:
driver.quit()"D:\Program Files (x86)\Python39\python.exe" D:/Buyer_test_code/webuitest_jcmall/unit.py
<selenium.webdriver.remote.webelement.WebElement (session="cf989d286cd3519eec64b2615033909e", element="26743821-2bdb-4189-8573-aae6cb82dc49")>Process finished with exit code 0
-
CSS_SELECTOR定位
在Web自动化中最推荐使用的一种方式,原因又如下几种:
- 例如
id这种元素在一个页面中可能并不唯一,并且很有可能是前端的框架自动生成的,研发人员并未对其进行维护,随时可能变;而CSS是前端开发最常用的一种维护方式,对于我们开发和维护自动化用例也更为清晰和方便 - 大部分定位都可以用
CSS来解决 CSS的写法相较于Xpath要更为简洁
常用的CSS选择器语法:

使用CSS_SELECTOR 结合ID定位
ele = driver.find_element(By.CSS_SELECTOR,"#kw")
使用CSS_SELECTOR 结合CLASS_NAME定位
ele = driver.find_element(By.CSS_SELECTOR,".s_ipt")
使用CSS_SELECTOR 结合标签中属性定位
driver.find_element(By.CSS_SELECTOR,"[href='/pc/account/login']")
使用CSS_SELECTOR 根据属性组合定位
# 通过CSS_SELECTOR 定位属性id=kw和name=wd的元素
driver.find_element(By.CSS_SELECTOR,"[id=kw][name=wd]")
使用CSS_SELECTOR 结点定位
ele = driver.find_element(By.CSS_SELECTOR,"#s-top-left > a:nth-child(3)") # 父元素id='s-top-left'下第3个a标签元素
在Chrome中的控制台使用CSS_SELECTOR调试定位
$("[class='question__option___3Crnb hydrated']") # $ 返回匹配到的第一个
$$("[class='question__option___3Crnb hydrated']") # $$ 返回匹配到的全部
使用LINK_TEXT定位
可以点击的链接跳转上面的文字,就是link text

ele = driver.find_element(By.LINK_TEXT,"新闻")
使用XPATH定位


使用XPATH根据id定位
ele = driver.find_element(By.XPATH,"//*[@id='kw']")
使用XPATH根据class定位
ele = driver.find_element(By.XPATH,"//*[@class='s_ipt']")
使用XPATH根据name定位
ele = driver.find_element(By.XPATH,"//*[@name='wd']")
使用XPATH根据节点关系定位
ele = driver.find_element(By.XPATH,"//*[@id='s-top-left']/a[3]") # id='s-top-left'父节点下的第3个a标签元素
使用XPATH逻辑运算组合定位
ele = driver.find_element(By.XPATH,"//*[@id='kw' and @name='wd']")
使用XPATH根据text文本进行定位
ele = driver.find_element(By.XPATH,"//*[contains(text(),'50万')]")
ele1 = driver.find_element(By.XPATH,"//*[text()='50万']")
在Chrome中的控制台中调试XPATH定位
$x("//*[@class='question__option___3Crnb hydrated']")
selenium中<select>...</select>标签下拉框元素定位
前端<select>标签下拉框html示例
<html>
<meta charset="utf-8">
<body>
<form>
<select name="zidonghua">
<option value="webui">selenium</option>
<option value="appui">appium</option>
<option value="api">requests</option>
<option value="mysql">pymysql</option>
<option value="jenkins">持续集成</option>
</select>
</form>
</body>
</html>

要定位<select>标签定义的下拉框的元素首先要导入from selenium.webdriver.support.select import Select
创建一个select的实例,Select类中传入<select>标签元素的element对象
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from time import sleep
diver = webdriver.Chrome()
diver.implicitly_wait(10)
try:
diver.get(r'file:///Users/fujinjie/Downloads/select.html')
diver.maximize_window()
select_ele = diver.find_element(By.XPATH, "//*[@name='zidonghua']")
select = Select(select_ele)
# 下拉框中元素索引从0开始,此处选择下拉框中第二个元素
select.select_by_index(1)
sleep(3)
# 根据<option>标签中的value属性进行定位
select.select_by_value("webui")
sleep(3)
# 根据<option>标签元素的text进行定位
select.select_by_visible_text("appium")
sleep(5)
except Exception as e:
raise e
finally:
diver.quit()
当然在下拉框的前端实现过程中不仅限于<select>标签实现,同样<ul>和<li>的组合同样能实现下拉列表;
注意:只有<select>标签来实现的下拉列表才能用Select()来实现下拉元素的定位,<ul>和<li>组合实现的下拉框用常规定位方法即可,当然<select>标签实现的下拉列表同样试用常规定位交互;
对于页面上一闪而过的页面元素的查看定位
selenium 中Js元素常用操作
在selenium中通过driver.execute_script('js语句')来执行javaScript脚本
1、js常用定位
document.getElementById("id") # 通过id定位
document.getElementsByName("name") # 通过name定位(获取list)
document.getElementsByClassName("class") # 通过class定位(获取list)
document.querySelector('css selector') # css selector定位
document.querySelectorAll("css selector") # css selector定位(获取list)
2、js元素常用操作
document.getElementById("su").value='百度两下' # 修改元素属性
document.getElementsByClassName("el-input__inner")[2].removeAttribute("readonly") # 去除元素属性
document.getElementsByClassName("el-input__inner")[2].scrollIntoView() # 滚动页面,真到元素可见
document.getElementById('kw').value='百度' #input输入框输入字符
document.getElementById("su").click() # 对元素的点击操作
3.Chrome控制台辅助定位
控制台的xpaht定位
$x("xpath表达式")
例如:$x("//*@id='su'")
控制台CSS定位
$("css表达式")
例如:("#su")、(".bg.s_btn")
问题:当元素定位不到是时,可能是什么原因?
1、查看页面是否加载完成
2、检查定位方法是否正确
3、查看这个元素是否有特殊的属性:disabled, readonly, style="display:none"
4、是否在frame中或iframe:
frameset是框架集, frame框架, iframe子框架
5、是否是一个动态元素,随机变化
6、是否在新的窗口中