Playwright 元素定位

Playwright 和 Selenium 的元素定位方式**不完全相同,**Selenium的定位策略有8种,Playwright拥有独特的 Role、Text、Label 等定位方式

1. locator() -- CSS 选择器

HTML 示例:

html 复制代码
<div id="app">
  <input type="text" class="username-input" placeholder="用户名">
  <button class="btn-primary">登录</button>
  <ul class="menu">
    <li><a href="/home">首页</a></li>
    <li><a href="/profile">个人信息</a></li>
  </ul>
</div>

python 代码:

python 复制代码
# 通过 id 定位
page.locator("#app").click()

# 通过 class 定位
page.locator(".username-input").fill("admin")

# 通过标签 + 属性组合
page.locator("button.btn-primary").click()

# 通过层级关系
page.locator("ul.menu li:first-child a").click()

2. locator() -- XPath(需加 xpath= 前缀)

HTML 示例:

html 复制代码
<div class="container">
  <form>
    <div class="form-group">
      <label>邮箱</label>
      <input type="email" name="email">
    </div>
    <div class="form-group">
      <label>密码</label>
      <input type="password" name="password">
    </div>
    <button>提交</button>
  </form>
</div>

python 代码:

python 复制代码
# 使用绝对 XPath(脆弱,不推荐)
page.locator("xpath=/html/body/div/form/div[1]/input").fill("test@example.com")

# 使用相对 XPath(推荐)
page.locator("xpath=//input[@name='email']").fill("test@example.com")
page.locator("xpath=//button[text()='提交']").click()

3. get_by_text() -- 文本内容

HTML 示例:

html 复制代码
<nav>
  <a href="/">首页</a>
  <a href="/about">关于我们</a>
  <button>点击关闭</button>
</nav>
<div class="notice">系统维护通知</div>

python 代码:

python 复制代码
# 精确匹配文本
page.get_by_text("首页", exact=True).click()

# 包含子串(默认行为)
page.get_by_text("维护").click()

# 忽略大小写
page.get_by_text("CLOSE", exact=False).click()  # 匹配 "点击关闭"

4. get_by_role() -- ARIA 角色(最稳定)

HTML 示例:

html 复制代码
<button aria-label="提交表单">Submit</button>
<input type="text" role="textbox" name="username" placeholder="用户名">
<a href="/login">去登录</a>

python 代码:

python 复制代码
# 定位按钮
page.get_by_role("button", name="提交表单").click()
page.get_by_role("button", name="Submit").click()

# 定位文本框
page.get_by_role("textbox", name="用户名").fill("zhangsan")

# 定位链接
page.get_by_role("link", name="去登录").click()

5. get_by_placeholder() -- 占位符文本

HTML 示例:

html 复制代码
<input type="text" placeholder="请输入手机号/邮箱">
<input type="password" placeholder="密码">

python 代码:

python 复制代码
page.get_by_placeholder("请输入手机号/邮箱").fill("13800000000")
page.get_by_placeholder("密码").fill("123456")

6. get_by_label() -- 关联的 <label> 文本

HTML 示例:

html 复制代码
<label>用户名 <input type="text" id="username"></label>
<label for="email">电子邮箱</label>
<input type="email" id="email">

python 代码:

python 复制代码
# 嵌套 label
page.get_by_label("用户名").fill("alice")

# 通过 for 属性
page.get_by_label("电子邮箱").fill("alice@example.com")

7. get_by_title() -- title 属性

HTML 示例:

html 复制代码
<button title="关闭弹窗">X</button>
<img src="logo.png" title="公司Logo">

python 代码:

python 复制代码
page.get_by_title("关闭弹窗").click()
logo = page.get_by_title("公司Logo")

8. get_by_alt_text() -- 图片的 alt 文本

HTML 示例:

html 复制代码
<img src="avatar.jpg" alt="用户头像">
<img src="banner.png" alt="宣传横幅">

python 代码:

python 复制代码
page.get_by_alt_text("用户头像").click()
banner = page.get_by_alt_text("宣传横幅")

9. 链式过滤 -- 在已定位元素中缩小范围

HTML 示例:

html 复制代码
<ul>
  <li><input type="checkbox"> 选项A</li>
  <li><input type="checkbox"> 选项B</li>
  <li><input type="checkbox" checked> 选项C</li>
</ul>

python 代码:

python 复制代码
# 获取所有 li,再筛选出包含已勾选 checkbox 的
checked_li = page.locator("li").filter(has=page.locator("input:checked"))
print(checked_li.inner_text())  # 输出 "选项C"

# 筛选出文本包含"选项A"的 li
option_a = page.locator("li").filter(has_text="选项A")
option_a.locator("input").check()

10. 定位 iframe 中的元素

HTML 示例:

html 复制代码
<iframe id="loginFrame" src="/login.html">
  <html>
    <body>
      <input name="user" placeholder="用户名">
      <button>登录</button>
    </body>
  </html>
</iframe>

python 代码:

python 复制代码
# 方法一:通过 frame_locator(推荐)
frame = page.frame_locator("#loginFrame")
frame.get_by_placeholder("用户名").fill("admin")
frame.get_by_role("button", name="登录").click()

# 方法二:先获取 frame 对象
iframe = page.frame(name="loginFrame")  # 或 page.frame(url=r".*login.*")
iframe.get_by_placeholder("用户名").fill("admin")

综合实战:登录表单

HTML 综合示例:

html 复制代码
<form id="loginForm">
  <label for="username">用户名</label>
  <input type="text" id="username" placeholder="手机/邮箱">
  <label for="password">密码</label>
  <input type="password" id="password" placeholder="密码">
  <button type="submit" class="login-btn">登 录</button>
</form>

python 代码(多种定位方式均可):

python 复制代码
# 方式一:get_by_label + get_by_placeholder
page.get_by_label("用户名").fill("admin")
page.get_by_placeholder("密码").fill("123456")
page.get_by_role("button", name="登录").click()

# 方式二:CSS 选择器
page.locator("#username").fill("admin")
page.locator("#password").fill("123456")
page.locator(".login-btn").click()

# 方式三:XPath
page.locator("xpath=//input[@id='username']").fill("admin")
page.locator("xpath=//button[contains(text(),'登录')]").click()
相关推荐
公爵爱学习2 小时前
无人机定点飞行-介绍
开发语言·图像处理·python·学习·线性回归·无人机
stillstream_ink2 小时前
OpenCart UI 自动化测试实战:POM 四层架构 + 失败自动截图 + 飞书通知
python·测试
databook2 小时前
Beta 分布:如何用“成功”和“失败”来预测下次尝试
python·数据挖掘·数据分析
zhanghaha13142 小时前
Python进阶教程:27_subprocess 模块 零基础超详细教程
开发语言·python
兄弟加油,别颓废了。2 小时前
bugku题目
开发语言·前端·python
新网企兴2 小时前
2026西安GEO推广选哪家?新网企兴帮您精准获客
人工智能·python
2601_962297482 小时前
一、Python GUI 的十字路口:免费凑活还是付费破局
python·gui·tkinter·customtkinter·bravurasdk
Wang's Blog3 小时前
Vibe Coding一人即团队系列59:基于PPTmaster与Claude Desktop的本地可编辑PPT自动化生成方案
运维·自动化·powerpoint
万年咸鱼3 小时前
Java BufferedInputStream 详解:原理、用法与实战
java·开发语言·python
my05923 小时前
跳出单一信息工具局限:奥米豆构建认知与心智并行的学习范式
大数据·人工智能·python·学习