selenium 元素定位
文章目录
- 一、什么是selenium
- 二、定位方法
- ID定位
- NAME 定位
- CLASS_NAME 定位
- TAG_NAME 定位
- LINK_TEXT 定位
- PARTIAL_LINK_TEXT 定位
- CSS_SELECTOR 定位
- abc > li:nth-child(3) 正序
- abc > li:nth-last-child(3) 倒序
- XPATH 定位
- 三、最佳实践建议
- 四、实例
- 五、总结
一、什么是selenium
-
简介
Selenium 是一个用于自动化 Web 浏览器交互的工具集,主要用于 Web 应用程序的自动化测试,但也可用于网页抓取和浏览器自动化任务。 -
主要组件
-
Selenium WebDriver:核心组件,提供 API 来控制浏览器
-
Selenium IDE:录制和回放测试的浏览器扩展
-
Selenium Grid:在多台机器上并行运行测试
-
-
主要功能
-
自动化浏览器操作(点击、输入、导航等)
-
提取网页内容
-
处理 JavaScript 渲染的页面
-
-
支持的语言和浏览器
-
语言:Java、Python、C#、JavaScript、Ruby 等
-
浏览器:Chrome、Firefox、Edge、Safari 等主流浏览器
-
-
常见用途
-
自动化测试:功能测试、回归测试
-
网页抓取:特别是需要 JavaScript 执行的动态内容
-
自动化任务:如表单填写、网页监控等
-
_______________________________________________ ★________________________________________________
二、定位方法
Selenium 提供了多种元素定位方法,用于在网页上查找和操作特定的 HTML 元素。还是那句话,不管黑猫白猫,能抓到耗子就是好猫,这么多定位方法,我们只需要选择合适的,让我们能准确的定位到元素。以下是 Python 中 Selenium 最常用的八种元素定位方法及其详细说明:
有前端知识基础的小伙伴们应该能所有感觉,元素定位有点类似与给页面的某些元素添加样式一样,也是通过元素的标签和属性进行定位,而整个web界面又是树形结构,也支持通过父级、子级和兄弟节点定位。
ID定位
find_element(By.ID, “id_value”)
最推荐的定位方式,因为 ID 在 HTML 中应该是唯一的。(也有可能id不存在或者是不固定的)
from selenium.webdriver.common.by import By
element = driver.find_element(By.ID, "est_cn")
适用元素
<div id="est_cn" class="est_selected" tabindex="-1" aria-label="国内版">国内版</div>
-
特点:
-
定位速度快
-
通常唯一性最好
-
不是所有元素都有 ID
-
_______________________________________________ ★________________________________________________
NAME 定位
find_element(By.NAME, “name_value”)
通过 HTML 元素的 name 属性定位。
element = driver.find_element(By.NAME, "referrer")
-
特点:
-
常用于表单元素
-
可能有多个元素同名
-
比 ID 定位稍慢
-
适用元素
<meta name="referrer" content="origin-when-cross-origin">
_______________________________________________ ★________________________________________________
CLASS_NAME 定位
find_element(By.CLASS_NAME, “class_value”)
通过 HTML 元素的 class 属性定位。
element = driver.find_element(By.CLASS_NAME, "text-back")
-
特点:
-
一个元素可能有多个 class
-
一个 class 可能被多个元素使用
-
注意:如果 class 名包含空格,表示多个 class,只能使用其中一个
-
适用元素
<div class="text-back"><div class="text" href="#">跳至内容</div></div>
_______________________________________________ ★________________________________________________
TAG_NAME 定位
find_element(By.TAG_NAME, “tag_value”)
通过 HTML 标签名定位。
element = driver.find_element(By.TAG_NAME, "a") # 定位<a>标签
-
特点:
-
通常用于获取同类元素的集合
-
很少单独使用,因为重复性太高
-
常用于查找子元素
-
适用元素
<a id="b_skip_to_content" data-priority="2" href="#" role="button" tabindex="0"><div class="text-back"><div class="text" href="#">跳至内容</div></div></a>
_______________________________________________ ★________________________________________________
LINK_TEXT 定位
find_element(By.LINK_TEXT, “link_text”)
专门用于定位超链接文本(完全匹配)。
element = driver.find_element(By.LINK_TEXT, "网页")
-
特点:
-
仅适用于标签
-
必须完全匹配链接文本
-
对中文支持良好
-
适用元素
<a class="" aria-current="page" disableredirectlink="False" href="/?scope=web&FORM=HDRSC1" h="ID=SERP,5028.1">网页</a>
_______________________________________________ ★________________________________________________
PARTIAL_LINK_TEXT 定位
find_element(By.PARTIAL_LINK_TEXT, “partial_text”)
通过超链接的部分文本定位(模糊匹配)
element = driver.find_element(By.PARTIAL_LINK_TEXT, "网") #通过超链接的部分文本定位(模糊匹配)
-
特点:
-
仅适用于<a>标签
-
匹配部分文本即可
-
可能有多个匹配结果
-
适用元素
<a class="" aria-current="page" disableredirectlink="False" href="/?scope=web&FORM=HDRSC1" h="ID=SERP,5028.1">网页</a>
_______________________________________________ ★________________________________________________
CSS_SELECTOR 定位
find_element(By.CSS_SELECTOR, “css_selector”)
通过 CSS 选择器定位,功能强大且灵活。(通过匹配的模式,与css文件的匹配规则一致)
element = driver.find_element(By.CSS_SELECTOR, "#b-scopeListItem-academic")
-
常用模式:
-
#id - 通过 ID
-
. class - 通过 class
-
tag - 通过标签名
-
[attribute=value] - 通过属性
-
parent > child - 父子关系
-
A B - 后代选择器
-
-
特点:
-
语法复杂但功能强大
-
浏览器原生支持,速度快
-
可以组合多种条件
-
-
示例
-
通过id定位
#abc
- 通过class定位
. abk
<p class="abk">hello world</p><p class="abk jdk">hello world</p> /*空格隔开类似于 or */
- 标签匹配
p 命中所有的p标签的元素
p.abk 命中标签为p class为abk的元素
<p class="abk">hello world</p>
<p class="abk jdk">hello world</p> /*空格隔开类似于 or */
- 分组选择器
p**,** a 分组选择器,用于作用与多个标签,每个标签之间用 逗号 分开
不指定属性的值的话,所有的有这个属性的元素都会命中
- 属性选择器
[title=“opq”] 用于查找title="opq"的元素
[title] 不指定属性的值的话,所有的有这个属性的元素都会命中
span[title=“abk”] 可以加上标签用于辅助定位
组合选择符
匹配案例
<div><ul><li>天干<ul><li id="abc">甲(jiǎ)</li><li>乙(yǐ)</li><li>丙(bǐng)</li><li>丁(dīng)</li><li>戊(wù)</li><li>己(jǐ)</li><li>庚(gēng)</li><li>辛(xīn)</li><li>壬(rén)</li><li>癸(guǐ)</li></ul></li><li>地支<ul><li class="ab1">子(zǐ)</li><li>丑(chǒu)</li><li>寅(yín)</li><li>卯(mǎo)</li><li>辰(chén)</li><li>巳(sì)</li><li>午(wǔ)</li><li>未(wèi)</li><li>申(shēn)</li><li>酉(yǒu)</li><li>戌(xū)</li><li>亥(hài)</li></ul></li></ul></div>
- 后代选择器,以空格分隔,用于选择某元素所有后代元素
div li
div li.ab1 可以组合其他选择器使用
- 子元素选择器,用大于号匹配, 只查询下一级,没有就不会往下找了
ul > li
- 相邻兄弟选择器,选择元素之后的一个元素,他们需要有相同的父级元素
#abc + li
- 后续兄弟选择器 以小波浪线分隔,所有的元素要有相同的父级
#abc ~ li
- 选择列表中的第几个 就算中间标签不一样也是按顺序往下数的第几个
abc > li:nth-child(3) 正序
abc > li:nth-last-child(3) 倒序
适用元素
<li class="" data-menuurl="" id="b-scopeListItem-academic" data-query=""><a class="" aria-current="false" disableredirectlink="False" href="/academic/search?q=%e7%99%be%e5%ba%a6%e4%b8%80%e4%b8%8b%e4%bd%a0%e5%b0%b1%e7%9f%a5%e9%81%93&FORM=HDRSC4" h="ID=SERP,5031.1" target="_blank">学术</a></li>
_______________________________________________ ★________________________________________________
XPATH 定位
find_element(By.XPATH, “xpath_expression”)
最灵活的定位方式,通过 XML 路径表达式定位元素。 (通过遍历的方式,有点类似于文件路径)
element = driver.find_element(By.XPATH, "//li[@id='b-scopeListItem-academic']")
-
常用表达式:
-
//tag - 查找所有tag元素
-
//tag[@attr=‘value’] - 按属性查找
-
//tag[contains(@attr, ‘value’)] - 属性包含
-
//tag[text()=‘text’] - 按文本查找
-
/ 和 // - 绝对路径和相对路径
-
. 代表当前路径 **…**代表上层路径 //span/button/…/…/a
-
-
特点:
-
功能最强大
-
可以定位几乎所有元素
-
语法复杂,性能比 CSS 选择器稍差
-
支持按文本查找
-
-
示例
-
表示父级:使用/ 父级/子级 例如 a标签的父级是div 不同的标签也可以加上属性参数辅助定位
//div/a
//div[@id=‘123’]/a[@class=‘456’]
- 多个元素用类似数组一样的查找方式
//div[1]/a[2]
- 一个元素有多个属性的时候可以使用 and和or辅助匹配
//p[@id=‘1’ and @name='xyz]
- 标签可以使用通配符 *
//*[@class=‘yu’]
- 可以通过标签的文本进行匹配 用 text()=‘xxx’
//p[text()=‘登 录’]
轴定位: 以当前的元素为中心进行定位
- 使用ancesstor::tag 指定元素的所有的先辈标签
//p[text()=‘登 录’]/ancestor::span
- 使用ancesstor-or-self::tag 指定元素的所有的先辈标签,或者当前元素本身
//p[text()=‘登 录’]/ancesstor-or-self::span
- 使用preceding-sibling::tag 指定元素的所有前面的兄弟节点
//p[text()=‘登 录’]/preceding-sibling::tag
- 使用descendant::tag 指定元素的的所有子级标签
//p[text()=‘登 录’]/descendant::tag
- 使用descendant-or-self::tag 指定元素的的所有子级标签,或者当前元素
//p[text()=‘登 录’]/descendant-or-self::tag
适用元素
<li class="" data-menuurl="" id="b-scopeListItem-academic" data-query=""><a class="" aria-current="false" disableredirectlink="False" href="/academic/search?q=%e7%99%be%e5%ba%a6%e4%b8%80%e4%b8%8b%e4%bd%a0%e5%b0%b1%e7%9f%a5%e9%81%93&FORM=HDRSC4" h="ID=SERP,5031.1" target="_blank">学术</a></li>
_______________________________________________ ★________________________________________________
三、最佳实践建议
-
定位优先级:ID > NAME > CSS > XPATH > 其他
-
相对定位:优先使用相对路径而非绝对路径
-
避免纯文本定位:页面文本变化会导致定位失败
-
组合定位:可以组合多种定位方式提高准确性
-
显式等待:配合 WebDriverWait 使用更稳定
四、实例
五、总结
以上就是今天要讲的内容,本文仅仅简单介绍了元素定位的使用。东西太多记不住就进行记录,通过不断获取实践积累经验,找出一个适合自己的方案