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 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.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、是否在新的窗口中