跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
Python大前端

Playwright 基础教程:元素拖拽、坐标获取与文本提取实战

Playwright 基础教程涵盖元素拖拽操作、元素坐标获取、网页源码抓取及元素文本提取等核心功能。通过演示 drag_and_drop 方法实现跨元素交互,利用 bounding_box 计算元素位置中心点。对比 selenium 说明 page.content() 获取源码方式,并详细解析 locator 提供的多种文本提取方法如 inner_text、text_content 的区别与应用场景,适用于自动化测试与爬虫开发场景。

人间失格发布于 2025/2/7更新于 2026/5/38 浏览
Playwright 基础教程:元素拖拽、坐标获取与文本提取实战

Playwright 基础教程:元素拖拽、坐标获取与文本提取实战

前言

Playwright 是微软开源的自动化测试工具,支持多种浏览器和语言。在 Web 自动化测试及爬虫开发中,我们经常需要处理复杂的用户交互,如拖拽操作,或者需要获取元素的精确位置信息以及页面内的文本数据。本文将详细介绍如何使用 Playwright 实现元素拖拽、计算元素坐标、获取网页源码以及提取元素内文本,并提供完整的代码示例。

环境准备与连接方式

在使用 Playwright 之前,确保已安装 Python 环境并安装了 playwright 库。可以通过以下命令安装依赖:

pip install playwright
playwright install

Playwright 提供了两种主要的浏览器连接模式:连接到已打开的浏览器或启动新的浏览器实例。

1. 连接已打开的浏览器

这种方式适用于调试场景,可以查看浏览器实际运行状态。通过 CDP (Chrome DevTools Protocol) 端口连接。

from playwright.sync_api import sync_playwright

class BrowserConnection:
    def __init__(self):
        self.playwright = sync_playwright().start()
        # 连接本地已启动的 Chrome 浏览器,默认端口为 9223
        browser = self.playwright.chromium.connect_over_cdp("http://127.0.0.1:9223")
        self.default_context = browser.contexts[0]
        self.page = self.default_context.pages[0]

2. 启动新浏览器实例

这是最常用的方式,适合自动化脚本执行。可以配置无头模式(headless)或可视化模式。

class NewBrowserSession:
    def __init__(self, url):
        playwright = sync_playwright().start()
        # headless=False 表示显示浏览器窗口,便于观察
        browser = playwright.chromium.launch(headless=False)
        context = browser.new_context()
        self.page = context.new_page()
        self.page.goto(url)

元素拖拽操作 (Drag and Drop)

拖拽是常见的用户交互行为,例如文件上传、排序列表等。Playwright 提供了 方法简化此过程。

drag_and_drop

官方文档说明

该方法将指定元素拖拽到目标元素。内部逻辑会先移动到源元素执行 mousedown,再移动到目标元素执行 mouseup。

基本用法

# 简单拖拽:从源选择器拖到目标选择器
page.drag_and_drop("#source", "#target")

# 精确控制位置:指定相对于元素左上角的偏移量
page.drag_and_drop(
    "#source",
    "#target",
    source_position={"x": 34, "y": 7},
    target_position={"x": 10, "y": 20}
)

测试案例

为了验证拖拽功能,我们可以创建一个简单的 HTML 页面进行测试。该页面包含一个可拖动的红色方块和一个绿色的放置区域。

HTML 结构示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Drag and Drop Test</title>
    <style>
        #dragElement {
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
            top: 0;
            left: 0;
            cursor: move;
        }
        #dropElement {
            width: 200px;
            height: 200px;
            background-color: green;
            margin: auto;
        }
    </style>
</head>
<body>
    <div id="bigdiv">
        <div id="dragElement"></div>
        <div id="dropElement"></div>
    </div>
    <script>
        const dragElement = document.getElementById('dragElement');
        let isDragging = false;
        let startOffset = {x: 0, y: 0};

        function startDrag(e) {
            isDragging = true;
            startOffset.x = e.clientX - dragElement.offsetLeft;
            startOffset.y = e.clientY - dragElement.offsetTop;
        }

        function endDrag() {
            isDragging = false;
        }

        function drag(e) {
            if (!isDragging) return;
            dragElement.style.left = e.clientX - startOffset.x + 'px';
            dragElement.style.top = e.clientY - startOffset.y + 'px';
        }

        dragElement.addEventListener('mousedown', startDrag);
        document.addEventListener('mouseup', endDrag);
        document.addEventListener('mousemove', drag);
    </script>
</body>
</html>

拖拽代码实现

假设上述 HTML 文件保存在本地路径,以下是使用 Playwright 执行拖拽的完整类定义。

from playwright.sync_api import sync_playwright
import os

class DragDropDemo:
    def __init__(self, file_path):
        self.playwright = sync_playwright().start()
        browser = self.playwright.chromium.launch(headless=False)
        context = browser.new_context()
        self.page = context.new_page()
        # 加载本地 HTML 文件
        self.page.goto(f"file://{os.path.abspath(file_path)}")

    def drag_and_drop_operate(self):
        # 将红色框拖入绿色框
        self.page.drag_and_drop(source="#dragElement", target="#dropElement")
        print("拖拽操作完成")

if __name__ == '__main__':
    # 请替换为实际的本地文件路径
    demo = DragDropDemo(r"D:/L_Learning/MyLearningCode/draganddrop.html")
    demo.drag_and_drop_operate()
    demo.playwright.stop()

注意事项: 在执行拖拽之前,请确保要拖动的元素和目标元素都已经加载完成。如果页面加载较慢,建议使用 wait_for_selector 等待元素出现。

元素坐标获取 (Bounding Box)

在某些自动化场景中,我们需要知道元素在页面上的精确位置,例如点击元素的中心点,或者根据坐标进行截图分析。

bounding_box 方法

bounding_box() 返回一个字典,包含元素的 x, y 坐标以及宽度和高度。

def get_bounding_box(page):
    locator = page.locator("#dragElement")
    # 等待元素可见
    locator.wait_for(state="visible")
    box = locator.bounding_box()
    print(box)  # 输出示例:{'x': 0, 'y': 0, 'width': 100, 'height': 100}
    return box

返回值说明:

  • x: 元素左上角距离视口左侧的距离。
  • y: 元素左上角距离视口顶部的距离。
  • width: 元素宽度。
  • height: 元素高度。

计算中心点

如果需要点击元素的中心,可以通过以下公式计算:

def calculate_center(box):
    center_x = box["x"] + box["width"] / 2
    center_y = box["y"] + box["height"] / 2
    return center_x, center_y

# 使用示例
center = calculate_center(get_bounding_box(page))
page.click(f"#{center[0]} #{center[1]}") # 注意:click 通常接受选择器,这里仅为坐标计算演示

在实际使用中,更推荐直接使用 locator.click(),它会自动定位到元素中心。但在某些复杂交互或自定义事件模拟中,手动计算坐标非常有用。

获取网页源码

Playwright 获取网页源代码的方式与 Selenium 类似,但 API 更加现代化。

对比 Selenium

  • Selenium: driver.page_source
  • Playwright: page.content()

代码示例

# 获取当前页面的完整 HTML 源码
page_source = page.content()

# 打印前 500 个字符以检查内容
print(page_source[:500])

应用场景: 对于爬虫开发者来说,获取源码后可以使用正则表达式或 BeautifulSoup 等库提取特定数据。这对于处理动态渲染较少的页面非常高效。

获取元素内文本

在表格数据抓取或表单验证中,提取元素内的文本是核心需求。Playwright 的 Locator 对象提供了多种方法来提取文本,不同的方法适用于不同的场景。

常用方法列表

  1. locator.all_inner_texts(): 返回列表,包含所有匹配元素的内部文本。
  2. locator.all_text_contents(): 返回列表,包含所有匹配元素的全文本内容(含子元素)。
  3. locator.inner_text(): 返回字符串,第一个匹配元素的内部文本。
  4. locator.text_content(): 返回字符串,第一个匹配元素及其所有子元素的全文本内容。
  5. locator.inner_html(): 返回字符串,第一个匹配元素的内部 HTML 代码。

详细区别解析

  • inner_text vs text_content:

    • inner_text() 类似于浏览器的 innerText,它会考虑 CSS 样式(例如隐藏的元素不会返回文本),并且去除多余的空白。
    • text_content() 类似于浏览器的 textContent,它会返回 DOM 树中的所有文本节点,包括隐藏的文本,且保留原始格式。
  • all_inner_texts vs all_text_contents:

    • 前者针对多个元素返回数组,后者同理。主要区别在于是否包含子元素文本的处理逻辑差异。

测试代码

使用之前的 HTML 结构进行测试:

def extract_element_text(page):
    locator = page.locator("#bigdiv")
    
    # 获取所有内部文本
    texts1 = locator.all_inner_texts()
    print(f"all_inner_texts type: {type(texts1)}, value: {texts1}")
    
    # 获取所有文本内容
    texts2 = locator.all_text_contents()
    print(f"all_text_contents type: {type(texts2)}, value: {texts2}")
    
    # 获取单个内部文本
    text3 = locator.inner_text()
    print(f"inner_text type: {type(text3)}, value: {text3}")
    
    # 获取单个文本内容
    text4 = locator.text_content()
    print(f"text_content type: {type(text4)}, value: {text4}")
    
    # 获取内部 HTML
    html5 = locator.inner_html()
    print(f"inner_html type: {type(html5)}, value: {html5[:100]}...")

最佳实践建议

  1. 等待策略:在提取文本前,务必确保元素已加载。推荐使用 locator.wait_for(state="visible")。
  2. 容错处理:如果元素可能不存在,应捕获异常或使用 locator.count() 判断。
  3. 性能优化:避免一次性提取过多无关文本,尽量缩小选择器范围。

常见问题与解决方案

问题 1:拖拽失败

原因:元素未加载完成或被遮挡。 解决:增加显式等待,使用 page.wait_for_load_state("networkidle")。

问题 2:文本提取为空

原因:使用了 text_content() 但元素被 CSS 隐藏。 解决:尝试改用 inner_text(),它会根据可视性过滤文本。

问题 3:坐标不准

原因:页面滚动导致视口变化。 解决:确保在固定视口下操作,或使用 scroll_into_view_if_needed() 方法。

总结

本文系统讲解了 Playwright 在 Web 自动化中的几个关键功能:

  1. 元素拖拽:利用 drag_and_drop 轻松模拟鼠标交互,支持自定义偏移量。
  2. 坐标获取:通过 bounding_box 获取元素几何信息,辅助精确定位。
  3. 源码获取:使用 page.content() 快速抓取页面 HTML,配合正则进行数据清洗。
  4. 文本提取:深入对比了 inner_text、text_content 等方法的差异,帮助开发者根据场景选择合适方案。

掌握这些技能将大大提升自动化测试脚本的稳定性和爬虫数据的获取效率。建议在实际项目中结合具体的业务逻辑,灵活运用这些 API 构建健壮的自动化流程。

目录

  1. Playwright 基础教程:元素拖拽、坐标获取与文本提取实战
  2. 前言
  3. 环境准备与连接方式
  4. 1. 连接已打开的浏览器
  5. 2. 启动新浏览器实例
  6. 元素拖拽操作 (Drag and Drop)
  7. 官方文档说明
  8. 基本用法
  9. 简单拖拽:从源选择器拖到目标选择器
  10. 精确控制位置:指定相对于元素左上角的偏移量
  11. 测试案例
  12. 拖拽代码实现
  13. 元素坐标获取 (Bounding Box)
  14. bounding_box 方法
  15. 计算中心点
  16. 使用示例
  17. 获取网页源码
  18. 对比 Selenium
  19. 代码示例
  20. 获取当前页面的完整 HTML 源码
  21. 打印前 500 个字符以检查内容
  22. 获取元素内文本
  23. 常用方法列表
  24. 详细区别解析
  25. 测试代码
  26. 最佳实践建议
  27. 常见问题与解决方案
  28. 问题 1:拖拽失败
  29. 问题 2:文本提取为空
  30. 问题 3:坐标不准
  31. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Coze AI 智能体开发入门:零代码搭建 AI 应用
  • 谷歌 SEO 合规指南:如何避免网站被惩罚
  • OpenClaw v2026.3.8 全平台部署与本地模型对接指南
  • AI 提示词的应用场景、编写技巧与防御策略
  • Ubuntu 部署 ToolJet 低代码平台及内网穿透远程访问
  • 使用 Webhook 向飞书自定义机器人发送消息
  • 2025年12月C++一级等级考试真题解析
  • Python 30 行实现公开接口数据本地化存储
  • Word MCP Server:实现 AI 对 Word 文档的创建、编辑与格式化操作
  • 链表核心算法实战解析
  • Windows Git Bash 下安装 tmux 实现 SSH 会话保持
  • QClaw 本地 AI Agent 工具使用指南与微信集成
  • QClaw 本地 AI 助手接入微信的使用指南
  • 鸿蒙电商购物车项目:用户管理、商品列表与购物车实现
  • 10 款高效降低 AIGC 生成痕迹工具评测
  • 多模态模型 Transfusion 与 Show-o 解析:Transformer 结合扩散与自回归生成
  • Flutter 三方库 xpath_selector 在鸿蒙系统的适配与使用指南
  • LangChain 大模型应用开发指南:从基础概念到实战实践
  • 基于 Dify 低代码平台开发 AI 应用:从入门到生产部署
  • 五分钟构建动态知识图谱:利用大模型提取实体关系与数据对话

相关免费在线工具

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online