WEB自动化_元素定位
元素定位
思考:为什么要学习元素定位?
让程序操作指定元素,就必须先找到此元素。
- 火狐: Eirebug(E12获取直接点击Friebug图标>
如何进行元素定位?
- 要使用web自动化操作元素,必须首先找到此元素。
html页面由标签构成,标签的基本格式如下:
<标签名 属性名1="属性值1" 属性名2="属性值2">文本</标签名>
-
示例
<input id="username" type="text" name="username" placeholder="用户名"/> <div id="my_cart"> <span>我的购物车</span> </div>
-
元素定位就是通过元素的信息或元素层级结构来定位元素的。
定位元素依赖于:
- 标签名
- 属性
- 层级
- 路径
思考:如何快速的查看一个元素的相关信息?
元素定位方式
-
selenium提供了八种定位元素方式
- id
- name
- class_name (使用元素的class属性定位)
- tag_name (标签名称<标签名.../> )
- link_text (定位超连接 a标签)
- partial_link_text (定位超连接 a标签 模糊)
- XPath (基于元素路径)
- CSS (元素选择器)
-
汇总
- 基于元素属性特有定位方式(idlnamelclass_name)
- 基于元素标签名称定位: tag_name
- 定位超链接文本(link_text.partial_link_text)
- 基于元素路径定位(xpath)
- 基于选择器(css)
id定位
- 说明:id定位就是通过元素的 id属性 来定位元素,HTML规定id属性在整个HTML文档中必须是唯一的
- 前提:元素有id属性
语法
driver.find_element(By.ID,"kw").send_keys("百度")
案例
案例演示环境说明:
需求:打开注册A.html页面(本地),完成以下操作
1).使用id定位,输入用户名: admin
2).使用id定位,输入密码:1234563)
3).3秒后关闭浏览器窗口
-
提示:
1.输入方法:send_keys ("输入内容"); 2.退出浏览器驱动:driver.quit (); 3.打开url:driver.get (ur1) 4.导包:from selenium import webdriver 5.获取火狐浏览器驱动对象
-
代码
# 导包 from selenium import webdriver from time import sleep # 获取浏览器对象 driver = webdriver.Firefox() # 打开url url = r"D:\my_Python\网页\注册A.html" driver.get(url) # 查找元素 用户名 并输入 admin driver.find_element(By.ID, "username").send_keys("admin") # 查找元素 密码框 并输入 123456 driver.find_element(By.ID, "password").send_keys("123456") # 暂停3秒 sleep(3) # 关闭浏览器驱动对象 driver.quit()
name 定位
- 说明: name定位就是根据元素 name属性 来定位。HTML文档中name的属性值是可以重复的。
语法
-
前提:元素有name属性
driver.find_element(By.NAME,"wd").send_keys("百度")
class_name 定位
-
说明: class_name定位就是根据元素class属性值来定位元素。HTML通过使用class来定义元素的样式。
-
前提:元素有class属性
-
注意:如果class有多个属性值,只能使用其中的一个
语法
driver.find_element(By.CLASS_NAME,"telA" ).send_keys("18611111111")
tag_name 定位
- 是通过元素的标签名称来定位,标签名
- ( 查看元素时 尖括号(<) 紧挨 着的 单词或字母 就是标签名)
- 标签名也就是元素名
- 注意:页面中如果存在多个相同的标签名,默认返回第一个标签
语法
driver.find_element(By.TAG_NAME,"input").send_keys("admin")
link_text 定位
- 说明: link_text定位是专门用来定位超链接元素
(<a>标签</a>)
,并且是通过超链接的文本内容来定位元素
语法
driver.find_element(By.LINK_TEXT, "新闻").click()
案例
# 导包
from selenium import webdriver
from selenium.webdriver.common.by import By
# 获取浏览器对象
driver = webdriver.Firefox()
# 打开url
url = r"https://www.baidu.com"
driver.get(url)
# 超链接文本 click点击
driver.find_element(By.LINK_TEXT, "新闻").click()
注意
-
link_text
-
只能定位a标签
-
link_text 定位元素的内容必须为全部匹配 - 精准匹配
-
partial_link_text 定位 [ 推荐 ]
- 说明:部分文本定位
语法
driver.find_element(By.PARTIAL_LINK_TEXT, "新").click()
注意
-
partial_link_text
-
只能定位a标签
-
partial_link_text 定位元素的内容可以模糊部分值,但是必须能代表唯一性 - 模糊匹配
-
如果有多个值,默认返回第一个值
-
XPath 和 CSS
为什么使用XPath和css定位
-
id, name, class:依赖于元素这三个对应的属性,如果元素没有以上三个属性,定位方法不能使用。
-
link _text,partial_link_text:只适合超链接
-
tag_name:只能找页面唯一元素,或者 页面中多个相同元素中的第一个元素
XPath定位
-
说明:基于元素的路径
-
Xpath = XML + path
- XML:一种标记语言,用于数据的存储和传递。后缀.xml结尾
<?xml version="1.0" encoding="UTF-8"?> <node> <db id="db" desc="三条边的长度都一样"> <b1>3</b1>置 <b2>3</b2> <b3>3</b3> <expect>等边三角形</expect> </db> <dy> <b1>4</b1> <b2>4</b2> <b3>5</b3> <expect>等腰三角形</expect> </dy> < / node>
语法
driver.find_element(By.XPATH, xpath)
路径定位(绝对路径、相对路径)
绝对路径
- 从最外层元素到指定元素之间所有经过元素层级的路径
- 以/html根节点开始,使用 / 来分隔元素层级:
- 绝对路径一定是以 / 开头的
- 如:/htmI/body/div/fieldset/p[1]/input
- 绝对路径对页面结构要求比较严格,不建议使用
相对路径
-
匹配任意层级的元素,不限制元素的位置
-
以 // 开始
-
格式 :// input 或者 /*
XPath 定位策略/方式
- 路径-定位
- 绝对路径:以单斜杠开头逐级开始编写,不能跳级。
- 如:如: /htm1/body/div/p[1] /input
- 相对路径:以双斜杠开头,双斜杠后边跟元素名称,不知元素名称可以使用*代替。
- 如
- //input
- //*
- 如
- 绝对路径:以单斜杠开头逐级开始编写,不能跳级。
- 路径结合属性
- 在xpath中,所有的属性必须使用e符号修饰
- 如://*[@id='id值']
- 在xpath中,所有的属性必须使用e符号修饰
- 路径结合逻辑(多个属性)
- and等
- 如://*[@id='id值'] and [@属性='属性值']
- and等
- 路径结合层级
- 需要找父级节点时
- 如://[@id='父级id属性值']/input
- 需要找父级节点时
注意
- 一般建议使用指定标签名称,不使用*代替,它效率比较慢。
- 无论是绝对路径和相对路径,/ 后面必须为元素的名称或者 *
- 扩展:在工作中,如果能使用相对路径绝对不使用绝对路径
案例
-
使用相对路径,定位百度 搜索 123
from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Firefox() driver.get("http://www.baidu.com") driver.find_element(By.XPATH, "//input[@id='kw']").send_keys("123")
-
使用逻辑结合
driver.find_element_by_xpath("//input[@id='passwordA' and @placeholder='密码A']").send_keys("123")
-
使用层级结合
driver.find_element_by_xpath("//p[@id='p1']/input"). send_keys("admin")
XPath 扩展
-
//*[text()='xxx'] 文本内容是xxx的元素
- —般适合p标签,a标签
-
//*[contains(@attribute,'xxx')] 属性中含有xxx的元素
- contains为关键字,不可更改。
-
//*[starts-with(@attribute ,'xxx')]
属性以xxx开头的元素- //*starts-with[@id,'pa']
- starts-with为关键字,不可更改
CSS定位
- 说明:
- CSS是一种标记语言,焦点。数据的样式。控制元素的显示样式,就必须先找到元素,在css标记语言中找元素使用css选择器;
- CSS定位就是通过css选择器工具进行定位。
- 极力推荐使用,查找元素的效率比xpath高,语法比xpath更简单。
driver.find_element(By.CSS_SELECTOR,)
CSS 定位常用策略(方式)
- id选择器 、class选择器 、 元素选择器 、属性选择器 、 层级选择器
id选择器
- 说明:根据元素id属性来选择
- 格式:#id
- 例如:#userA
class选择器
- 说明:根据元素class属性来选择
- 格式:.class
- 例如:.telA
元素选择器
- 说明:根据元素的标签名选择
- 格式: element
- 例如: input
属性选择器
- 语法:[属性名 = 属性值]
层级选择器
-
语法
- p > input
- p input
-
提示
>
与空格的区别:大于号必须为子元素,空格则不用。
案例
-
需求:
-
使用css id选择器定位用户名输入admin
-
使用css属性选择定位密码框输入123456
-
使用css cLass选择器定位电话号码:18611112222
-
使用css 元素选择器定位span标签获取文本值
-
使用层级选择器定位email输入123@qq.com
-
-
获取文本的方法元素.text
-
代码
from time import sleep from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Firefox() driver.get(D:\lzy\注册A.html) driver.find_element(By.CSS_SELECTOR,"#userA").send_keys("admin") driver.find_element(By.CSS_SELECTOR, "[name='passwordA']").send_keys("123456") driver.find_element(By.CSS_SELECTOR,".telA").send_keys("18611112222") span = driver.find_element(By.CSS_SELECTOR,"span").text print("获取的span标签文本值:", span) driver.find_element(By.CSS_SELECTOR,"p>input[placeholder='电子邮箱A']").send_keys("123@126.com") sleep(3) driver.quit()
CSS 延伸
-
[type^='p'] type属性以p字母开头的元素
以指定字母开头
driver.find_element(By.CSS_SELECTOR,"[name^='us']").send_keys("admin")
-
[type$='d '] type属性以d字母结束的元素
以指定字母结束
driver.find_element(By.CSS_SELECTOR, "[name&='dA']").send_keys("123456")
-
[type*='w '] type属性包含w字母的元素
包含指定字母
driver.find_element(By.CSS_SELECTOR,"class*='el'").send_keys("18611112222")
八种元素定位方式分类-汇总
- id、name、 class_name:为元素属性定位
- tag_name:为元素标签名称
- link_text、partial_link_text:为超链接定位(a标签)
- XPath:为元素路径定位
- CSS:为CSS选择器定位
XPath与CSS类似功能对比
定位方式 | XPath | CSS |
---|---|---|
元素名 | //input | input |
id | //input | #userA |
class | //*[@class='telA'] | .telA |
属性 | 1.//*[text()="xxx"] 2.//input[starts-with(@attribute,'xxx')] 3.//input[contains(@attribute,'xxx')] |
1.input[type^='p'] 2.input[type$='d'] 3.input[type*='w'] |
定位一组元素
语法
elements2 = driver.find_elements(By.xxx, 'xxx')
返回结果
- 类型为列表,要对列表进行访问和操作必须指定下标或进行遍历
- 下标从0开始
find_element方法封装
语法
driver.find_elements(By.xxx,'value')
参数说明
- By.xxx:为By类的类型,如By.ID
- value:元素的定位值,如"userA"
By类
- 需要导包