三火 發表於 2025-6-25 06:02:00

【Playwright + Python】系列(十七)揭秘 Playwright 处理 Handles:开启高效自动化之门

<p>哈喽,大家好,我是六哥!今天来跟大家聊一聊Playwright 处理 Handles的方法,面向对象为功能测试及零基础小白,这里我尽量用大白话的方式举例讲解,力求所有人都能看懂,建议大家先收藏,以免后面找不到。😎</p>
<h2 id="一什么是handles">一、什么是Handles</h2>
<p>在 Playwright 中,<strong>Handles</strong> 是一种特殊的数据结构,用于在 Playwright 的进程与浏览器环境之间建立桥梁,使你能够从 Playwright 的环境中访问和操作浏览器内的对象。简单来说,<strong>Handles</strong> 让你能够“抓住”页面上的元素或 JavaScript 对象,并对其进行操作。</p>
<h2 id="二为什么需要-handles">二、为什么需要 Handles?</h2>
<p><strong>跨环境操作</strong>:由于 Playwright 运行在一个进程中,而浏览器中的 JavaScript 代码运行在另一个进程中,Handles 提供了一种机制,使得这两个环境之间的对象可以相互操作。</p>
<p><strong>保持对象引用</strong>:通过 Handles,你可以在 Playwright 中保留对浏览器内对象的引用,即使这些对象在浏览器环境中发生了变化,只要 Handles 没有被销毁,你依然可以通过它们访问到这些对象。</p>
<p><strong>延迟执行</strong>:使用 Handles 可以延迟执行某些操作,直到特定条件满足为止,例如等待某个元素出现在页面上。</p>
<h2 id="三两种主要类型的-handles">三、两种主要类型的 Handles</h2>
<h3 id="1jshandle">1、JSHandle</h3>
<p><strong>用途</strong>:引用页面中的任何 JavaScript 对象。</p>
<p><strong>特点</strong>:JSHandle 可以表示任何类型的 JavaScript 对象,比如数组、函数、DOM 元素等。它提供了一种方式,让你可以在 Playwright 的上下文中操作这些对象。</p>
<p><strong>生命周期</strong>:除非页面导航或显式地调用了 <code>dispose()</code> 方法,否则 JSHandle 会一直存在,防止对应的 JavaScript 对象被垃圾回收。</p>
<h3 id="2elementhandle">2、ElementHandle</h3>
<p><strong>用途</strong>:专门用于引用页面中的 DOM 元素,并且提供了额外的方法来对这些元素执行操作或断言其属性。</p>
<p><strong>特点</strong>:ElementHandle 继承自 JSHandle,因此具备所有 JSHandle 的功能。此外,它还提供了一些额外的方法,如点击、填写文本、获取元素的边界框等,这些方法可以直接作用于 DOM 元素上。</p>
<p><strong>生命周期</strong>:同 JSHandle 一样,除非页面导航或显式地调用了 <code>dispose()</code> 方法,否则 ElementHandle 会一直存在。</p>
<h2 id="四实际应用示例">四、实际应用示例</h2>
<p>假设我们要在百度页面上进行一些操作,我们可以使用 Handles 来实现:</p>
<h3 id="1获取-jshandle-示例">1、获取 JSHandle 示例</h3>
<p><strong>示例代码</strong></p>
<pre><code class="language-python">from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto("https://www.baidu.com")
    # 获取 window 对象的 JSHandle
    js_handle = page.evaluate_handle('window')
    # 使用 jsHandle 进行评估
    title = page.evaluate('window =&gt; window.document.title', js_handle)
    # 断言标题
    assert title == "百度一下,你就知道"
    print(f"Page Title: {title}")
</code></pre>
<h3 id="2获取-elementhandle-示例">2、获取 ElementHandle 示例</h3>
<p><strong>示例代码</strong></p>
<pre><code class="language-python">from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto("https://www.baidu.com")
   # 获取搜索框的 ElementHandle
    search_box_handle = page.wait_for_selector('#kw')
    # 断言搜索框的宽高
    bounding_box = search_box_handle.bounding_box()
    print(f"Search Box Bounding Box: {bounding_box}")
    # 断言搜索框的 maxlength 属性
    maxlength = search_box_handle.get_attribute('maxlength')
    assert maxlength == '255'
   
    browser.close()
</code></pre>
<h3 id="3将-handle-作为参数传递">3、将 Handle 作为参数传递</h3>
<p>当需要在页面上下文中操作由 Playwright 创建的对象时,可以将 Handle 传递给 <code>evaluate</code> 方法。</p>
<p><strong>示例代码</strong></p>
<pre><code class="language-python">from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto("https://www.baidu.com")
    # 创建新的数组并返回数组的 JSHandle
    my_array_handle = page.evaluate_handle("() =&gt; { return ; }")
    # 获取数组的长度
    length = page.evaluate("array =&gt; array.length", my_array_handle)
    print(f"Array Length: {length}")
    # 向数组添加新元素
    page.evaluate("(array, newElement) =&gt; array.push(newElement)", )
    # 再次获取数组的长度
    new_length = page.evaluate("array =&gt; array.length", my_array_handle)
    print(f"New Array Length: {new_length}")
    # 释放对象
    my_array_handle.dispose()
    browser.close()
</code></pre>
<h3 id="4-使用-locator-而不是-elementhandle">4. 使用 Locator 而不是 ElementHandle</h3>
<p>虽然 ElementHandle 仍然可用,但 Playwright 推荐使用 <strong>Locator</strong> 来执行用户动作和断言。这是因为 Locator 每次都会根据选择器重新定位页面上的元素,确保即使页面状态改变也能正确地找到元素。</p>
<p>示例</p>
<pre><code class="language-python">from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto("https://www.baidu.com")
   # 使用 Locator 定位搜索框
    search_box_locator = page.locator('#kw')
    # 输入搜索词
    search_box_locator.fill('Playwright')
    # 提交搜索
    page.locator('#su').click()
    # 验证搜索结果
    first_result = page.locator('h3 &gt; a').first
    print(first_result.text_content())
    browser.close()
</code></pre>
<h2 id="写在最后"><font style="color: rgba(28, 31, 35, 1)">写在最后</font></h2>
<p>以上代码展示了如何使用 Playwright 处理 Handles的使用方法。你可以根据自己的需求调整这些示例,感兴趣的同学可以自行动手尝试。 如需要全部源代码,公众号:软件测试君,请回复“<strong>Playwright学习</strong>”获取,无引号哦。<br>
最后,希望大家都能顺利掌握,一起进步。也欢迎分享给更多有需要的朋友哦!</p>
<p>若有收获,就点个赞吧</p>


</div>
<div id="MySignature" role="contentinfo">
    <p><span style="font-family: 微软雅黑; font-size: 22px; font-weight: normal; font-style: italic; text-decoration: none"><strong>优秀不够,你是否无可替代</strong></span></p>
<p><span style="font-family: 微软雅黑; font-size: 18px; font-weight: normal; font-style: italic; text-decoration: none"><strong>
软件测试交流QQ群:721256703,期待你的加入!!</strong></span></p>
<p><span style="font-family: 微软雅黑; font-size: 18px; font-weight: normal; font-style: italic; text-decoration: none"><strong>欢迎关注我的微信公众号:软件测试君 </strong></span></p>
<img src="https://www.cnblogs.com/images/cnblogs_com/longronglang/1061549/o_QQ%E6%88%AA%E5%9B%BE20190728134401.jpg" height="200" width="450"><br><br><br>
来源:https://www.cnblogs.com/longronglang/p/18947182
頁: [1]
查看完整版本: 【Playwright + Python】系列(十七)揭秘 Playwright 处理 Handles:开启高效自动化之门