DrissionPage 入门教程
多属性组合定位
本教程共 42 篇 · 第 14 篇 · 更新于 2026-07-29 · 约 8 分钟阅读
DrissionPageDrissionPage 入门教程多属性组合模糊匹配正则匹配链式查找
14. 多属性组合定位
本节目标:掌握多属性组合定位方法,能处理复杂的定位场景,理解链式查找和相对定位。
单属性搞不定的场景,就需要组合多个条件。
DrissionPage 提供了灵活的组合方式。
与关系 @@
多个条件同时满足,每个条件用 @@ 开头:
# class 为 p_cls 且文本为"第三行"
tab.ele('@@class=p_cls@@text()=第三行')
# id 为 one 且标签为 div
tab.ele('@@id=one@@tag()=div')
# 三个条件组合
tab.ele('@@tag()=p@@class=p_cls@@id=row1')
tag 可以放在开头配合 @@ 使用:
# 标签为 p,class 为 p_cls,文本为"第二行"
tab.ele('tag:p@@class=p_cls@@text()=第二行')
或关系 @|
满足任意一个条件,每个条件用 @| 开头:
# id 为 row1 或 id 为 row2
tab.eles('@|id=row1@|id=row2')
# class 为 p_cls 或文本为"第二行"
tab.eles('@|class=p_cls@|text()=第二行')
tag 配合或关系:
# 标签为 li,文本包含"前沿技术"或"程序开发"
tab.ele('tag:li@|text():前沿技术@|text():程序开发')
WARNING:使用
@@或@|时,text()不能作为唯一条件。否则会定位到文档最高层元素。
错误示范:
# 错误!会定位到 <html>
tab.ele('@@text():前沿技术')
正确做法:
# 正确,加上 tag 限制范围
tab.ele('tag:li@@text():前沿技术')
否定匹配 @!
排除某个条件:
# id 不等于 one
tab.ele('@!id=one')
# 没有 class 属性的元素
tab.ele('@!class')
# class 包含 p_ 但 id 不等于 row1
tab.ele('@@class:p_@!id=row1')
@! 可以和 @@ 或 @| 混用:
# 与关系 + 否定
tab.ele('@@class=p_cls@!id=row1')
# 或关系 + 否定
tab.ele('@|class=p_cls@!id=row1')
模糊匹配技巧
文本模糊匹配
# 文本包含"技术"
tab.ele('text:技术')
# 文本以"前沿"开头
tab.ele('text^前沿')
# 文本以"开发"结尾
tab.ele('text$开发')
属性模糊匹配
# class 包含"btn"
tab.ele('@class:btn')
# href 以"https"开头
tab.ele('@href^https')
# src 以".png"结尾
tab.ele('@src$.png')
@text() 与 text 的区别
单属性时用 @text() 或 text 都行:
tab.ele('@text()=第一行')
tab.ele('text=第一行')
多属性组合时,必须用 @text():
# 正确
tab.ele('@@class=p_cls@@text()=第三行')
# 错误!text 不能直接用在 @@ 组合中
# tab.ele('@@class=p_cls@@text=第三行')
@@text() 搜索范围更广
@text() 只匹配直接文本节点。
@@text() 搜索整个元素内部的所有文本:
<ul class="item">
<a href="/new-tech">
<i class="icon"></i>
前沿技术
</a>
</ul>
# 匹配不到 <li>,因为"前沿技术"不是 <li> 的直接文本
tab.ele('tag:li@text()=前沿技术')
# 能匹配到,@@text() 搜索整个元素内部
tab.ele('tag:li@@text()=前沿技术')
链式查找
先定位父元素,再在范围内查找子元素:
# 先找到 div
div = tab.ele('#one')
# 在 div 内查找 p 元素
p_list = div.eles('tag:p')
# 在 div 内查找文本为"第二行"的元素
p2 = div.ele('第二行')
链式查找效率更高,结果更精确。
相对定位
元素对象提供了相对定位方法:
ele = tab.ele('#row1')
# 获取父元素
parent = ele.parent()
# 获取下一个兄弟元素
next_ele = ele.next()
# 获取上一个兄弟元素
prev_ele = ele.prev()
# 获取子元素
child = ele.child('tag:i')
# 获取后面第一个符合条件的元素
after = ele.after('tag:div')
正则匹配
DrissionPage 的定位语法本身不支持正则。
需要正则时,直接用 xpath:
# 用 xpath 正则匹配
tab.ele('xpath://div[re:test(@id, "^row\d+")]')
或者用模糊匹配替代大部分正则场景:
# 以 row 开头,后面模糊匹配
tab.ele('@id^row')
实际应用
假设要找一个表格中”状态”列为”已完成”的行:
# 获取所有行
rows = tab.eles('tag:tr')
for row in rows:
# 在行内查找状态单元格
status = row.ele('tag:td@@class=status')
if status.text == '已完成':
# 获取该行的操作按钮
btn = row.ele('tag:button@@class=action')
btn.click()
break
速查表
| 需求 | 写法 |
|---|---|
| id 为 one | #one 或 @id=one |
| class 为 btn | .btn 或 @class=btn |
| 文本为”确定” | text=确定 |
| 标签为 div | tag:div |
| 多条件与 | @@class=btn@@text()=确定 |
| 多条件或 | `@ |
| 否定条件 | @!class=disabled |
| 模糊匹配 | @class:btn |
| 匹配开头 | @href^https |
| 匹配结尾 | @src$.png |
| css 选择器 | css:.btn.primary |
| xpath | xpath://div[@id="one"] |
TIP:定位语法是 DrissionPage 的核心技能。多练习,多尝试,熟能生巧。遇到复杂场景,先用简单条件定位大范围,再逐步缩小。