安装playwright

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple playwright
playwright install

案例代码1
通过执行命令录取百度高级搜索生成脚本,调整脚本进行百度高级搜索

import re
import time
from playwright.sync_api import Playwright, sync_playwright, expect


def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://www.baidu.com/")
    page.locator("#s-usersetting-top").hover()
    page.get_by_role("link", name="高级搜索").click()
    page.locator("#adv_keyword").click()
    page.locator("#adv_keyword").fill("playwright")
    page.get_by_text("时间不限").click()
    page.get_by_text("一月内").click()
    page.locator("input[name=\"q6\"]").click()
    page.locator("input[name=\"q6\"]").fill("zhihu.com")
    with page.expect_popup() as page1_info:
        page.get_by_role("button", name="高级搜索").click()
    page1 = page1_info.value

    time.sleep(20)

    page1.close()
    page.close()

    # ---------------------
    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)

# playwright codegen -o mytest_bd.py --target python -b chromium

案例代码2
通过命令生成获取天气脚本

import re
import time

from playwright.sync_api import Playwright, sync_playwright, expect


def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://www.weather.com.cn/")
    page.locator("#txtZip").click()
    page.locator("#txtZip").fill("虢镇")
    with page.expect_popup() as page1_info:
        page.get_by_text("虢镇街道-陈仓-陕西").click()
    page1 = page1_info.value
    page1.get_by_role("link", name="7天").click()

    time.sleep(20)

    page1.close()
    page.close()

    # ---------------------
    context.close()
    browser.close()


with sync_playwright() as playwright:
    run(playwright)

# playwright codegen -o mytest_tq.py --target python -b chromium

☆☆☆案例3
写一个html通过playwright进行测试
html代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Playwright 功能演示页面</title>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        :root {
            --primary: #4361ee;
            --secondary: #3f37c9;
            --success: #4cc9f0;
            --danger: #f72585;
            --warning: #ffaa00;
            --dark: #212529;
            --light: #f8f9fa;
            --gray: #6c757d;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Roboto', sans-serif;
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            color: var(--dark);
            line-height: 1.6;
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }

        header {
            text-align: center;
            padding: 30px 0;
            margin-bottom: 30px;
            background: rgba(255, 255, 255, 0.9);
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
        }

        h1 {
            color: var(--primary);
            font-size: 2.8rem;
            margin-bottom: 10px;
        }

        .subtitle {
            color: var(--gray);
            font-size: 1.2rem;
            max-width: 800px;
            margin: 0 auto;
        }

        .features-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
            gap: 25px;
            margin-bottom: 40px;
        }

        .feature-card {
            background: white;
            border-radius: 15px;
            overflow: hidden;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
            transition: transform 0.3s ease, box-shadow 0.3s ease;
        }

        .feature-card:hover {
            transform: translateY(-10px);
            box-shadow: 0 15px 30px rgba(0, 0, 0, 0.15);
        }

        .card-header {
            background: linear-gradient(to right, var(--primary), var(--secondary));
            color: white;
            padding: 20px;
            display: flex;
            align-items: center;
            gap: 15px;
        }

        .card-header i {
            font-size: 1.8rem;
        }

        .card-body {
            padding: 25px;
        }

        .card-title {
            font-size: 1.5rem;
            margin-bottom: 15px;
            color: var(--dark);
        }

        .form-group {
            margin-bottom: 20px;
        }

        label {
            display: block;
            margin-bottom: 8px;
            font-weight: 500;
            color: var(--gray);
        }

        input, select, textarea {
            width: 100%;
            padding: 12px 15px;
            border: 2px solid #e0e0e0;
            border-radius: 8px;
            font-size: 1rem;
            transition: border-color 0.3s;
        }

        input:focus, select:focus, textarea:focus {
            border-color: var(--primary);
            outline: none;
        }

        .btn {
            display: inline-block;
            padding: 12px 25px;
            background: var(--primary);
            color: white;
            border: none;
            border-radius: 8px;
            font-size: 1rem;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s ease;
            text-align: center;
        }

        .btn:hover {
            background: var(--secondary);
            transform: translateY(-3px);
            box-shadow: 0 5px 15px rgba(67, 97, 238, 0.3);
        }

        .btn-danger {
            background: var(--danger);
        }

        .btn-danger:hover {
            background: #d1146a;
        }

        .btn-success {
            background: var(--success);
        }

        .btn-success:hover {
            background: #2fbde5;
        }

        .result-box {
            margin-top: 20px;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
            border-left: 4px solid var(--primary);
            min-height: 50px;
            font-family: monospace;
        }

        .checkbox-group, .radio-group {
            display: flex;
            gap: 15px;
            margin-top: 10px;
        }

        .checkbox-item, .radio-item {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .drag-container {
            display: flex;
            gap: 20px;
            margin: 20px 0;
        }

        .drag-source {
            padding: 30px;
            background: var(--primary);
            color: white;
            border-radius: 8px;
            text-align: center;
            cursor: grab;
        }

        .drag-target {
            padding: 30px;
            background: #e9ecef;
            border: 2px dashed var(--gray);
            border-radius: 8px;
            text-align: center;
            flex-grow: 1;
        }

        .hover-box {
            padding: 25px;
            background: var(--warning);
            color: white;
            border-radius: 8px;
            text-align: center;
            margin: 20px 0;
            transition: all 0.3s ease;
        }

        .hover-box:hover {
            background: #ff9900;
            transform: scale(1.05);
        }

        .modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.7);
            z-index: 1000;
            align-items: center;
            justify-content: center;
        }

        .modal-content {
            background: white;
            padding: 30px;
            border-radius: 15px;
            max-width: 500px;
            width: 90%;
            position: relative;
        }

        .close-modal {
            position: absolute;
            top: 15px;
            right: 15px;
            font-size: 1.5rem;
            cursor: pointer;
            color: var(--gray);
        }

        .tabs {
            display: flex;
            border-bottom: 1px solid #dee2e6;
            margin-bottom: 20px;
        }

        .tab {
            padding: 12px 25px;
            cursor: pointer;
            background: #f8f9fa;
            border: 1px solid transparent;
            border-top-left-radius: 8px;
            border-top-right-radius: 8px;
        }

        .tab.active {
            background: white;
            border-color: #dee2e6;
            border-bottom-color: white;
            font-weight: 500;
        }

        .tab-content {
            display: none;
            padding: 20px;
            border: 1px solid #dee2e6;
            border-top: none;
            border-radius: 0 0 8px 8px;
        }

        .tab-content.active {
            display: block;
        }

        footer {
            text-align: center;
            padding: 30px 0;
            color: var(--gray);
            font-size: 0.9rem;
        }

        .highlight {
            background: rgba(67, 97, 238, 0.1);
            padding: 3px 6px;
            border-radius: 4px;
            font-weight: 500;
        }

        @media (max-width: 768px) {
            .features-grid {
                grid-template-columns: 1fr;
            }

            .drag-container {
                flex-direction: column;
            }
        }
    </style>
</head>
<body>
<div class="container">
    <header>
        <h1><i class="fas fa-robot"></i> Playwright 功能演示页面</h1>
        <p class="subtitle">此页面包含多种交互元素,用于演示 Playwright
            的各种自动化功能,包括表单操作、元素定位、事件处理、文件上传等</p>
    </header>

    <div class="features-grid">
        <!-- 表单操作 -->
        <div class="feature-card">
            <div class="card-header">
                <i class="fas fa-edit"></i>
                <h2>表单操作</h2>
            </div>
            <div class="card-body">
                <div class="form-group">
                    <label for="username">用户名</label>
                    <input type="text" id="username" placeholder="输入用户名">
                </div>

                <div class="form-group">
                    <label for="email">电子邮箱</label>
                    <input type="email" id="email" placeholder="输入邮箱地址">
                </div>

                <div class="form-group">
                    <label for="password">密码</label>
                    <input type="password" id="password" placeholder="输入密码">
                </div>

                <div class="form-group">
                    <label for="bio">个人简介</label>
                    <textarea id="bio" rows="3" placeholder="输入个人简介"></textarea>
                </div>

                <div class="form-group">
                    <label for="country">国家</label>
                    <select id="country">
                        <option value="">选择国家</option>
                        <option value="us">美国</option>
                        <option value="cn">中国</option>
                        <option value="jp">日本</option>
                        <option value="uk">英国</option>
                    </select>
                </div>

                <button id="submit-form" class="btn">提交表单</button>

                <div class="result-box" id="form-result"></div>
            </div>
        </div>

        <!-- 选择框和按钮 -->
        <div class="feature-card">
            <div class="card-header">
                <i class="fas fa-check-square"></i>
                <h2>选择框与按钮</h2>
            </div>
            <div class="card-body">
                <div class="form-group">
                    <label>选择技术</label>
                    <div class="checkbox-group">
                        <div class="checkbox-item">
                            <input type="checkbox" id="playwright" value="playwright">
                            <label for="playwright">Playwright</label>
                        </div>
                        <div class="checkbox-item">
                            <input type="checkbox" id="selenium" value="selenium">
                            <label for="selenium">Selenium</label>
                        </div>
                        <div class="checkbox-item">
                            <input type="checkbox" id="cypress" value="cypress">
                            <label for="cypress">Cypress</label>
                        </div>
                    </div>
                </div>

                <div class="form-group">
                    <label>选择语言</label>
                    <div class="radio-group">
                        <div class="radio-item">
                            <input type="radio" id="python" name="language" value="python">
                            <label for="python">Python</label>
                        </div>
                        <div class="radio-item">
                            <input type="radio" id="javascript" name="language" value="javascript">
                            <label for="javascript">JavaScript</label>
                        </div>
                        <div class="radio-item">
                            <input type="radio" id="java" name="language" value="java">
                            <label for="java">Java</label>
                        </div>
                    </div>
                </div>

                <div class="form-group">
                    <label>按钮操作</label>
                    <div style="display: flex; gap: 15px; margin-top: 15px;">
                        <button id="alert-btn" class="btn btn-danger">触发警告框</button>
                        <button id="confirm-btn" class="btn btn-success">触发确认框</button>
                    </div>
                </div>

                <div class="result-box" id="selection-result"></div>
            </div>
        </div>

        <!-- 拖放与悬停 -->
        <div class="feature-card">
            <div class="card-header">
                <i class="fas fa-hand-pointer"></i>
                <h2>拖放与悬停</h2>
            </div>
            <div class="card-body">
                <h3 class="card-title">拖放操作</h3>
                <div class="drag-container">
                    <div class="drag-source" id="drag-source" draggable="true">
                        <i class="fas fa-grip-lines fa-2x"></i>
                        <p>拖拽我</p>
                    </div>
                    <div class="drag-target" id="drag-target">
                        <p>拖放到此处</p>
                    </div>
                </div>

                <h3 class="card-title" style="margin-top: 30px;">鼠标悬停</h3>
                <div class="hover-box" id="hover-area">
                    <i class="fas fa-mouse-pointer fa-3x"></i>
                    <p>将鼠标悬停在此处</p>
                    <p id="hover-text">悬停状态: 未激活</p>
                </div>

                <div class="result-box" id="drag-result">拖放结果将显示在这里</div>
            </div>
        </div>

        <!-- 文件上传与下载 -->
        <div class="feature-card">
            <div class="card-header">
                <i class="fas fa-file-upload"></i>
                <h2>文件操作</h2>
            </div>
            <div class="card-body">
                <div class="form-group">
                    <label for="file-upload">上传文件</label>
                    <input type="file" id="file-upload">
                </div>

                <div class="result-box" id="upload-result">选择文件后,文件名将显示在这里</div>

                <div style="margin-top: 30px; padding: 20px; background: #e7f4ff; border-radius: 10px;">
                    <h3 class="card-title">下载示例</h3>
                    <p>点击下方按钮下载示例文件:</p>
                    <button id="download-btn" class="btn" style="margin-top: 15px;">
                        <i class="fas fa-download"></i> 下载示例文件
                    </button>
                </div>
            </div>
        </div>

        <!-- 模态框与导航 -->
        <div class="feature-card">
            <div class="card-header">
                <i class="fas fa-window-maximize"></i>
                <h2>模态框与导航</h2>
            </div>
            <div class="card-body">
                <button id="open-modal" class="btn" style="margin-bottom: 20px;">
                    <i class="fas fa-external-link-alt"></i> 打开模态框
                </button>

                <div class="tabs">
                    <div class="tab active" data-tab="tab1">标签页 1</div>
                    <div class="tab" data-tab="tab2">标签页 2</div>
                    <div class="tab" data-tab="tab3">标签页 3</div>
                </div>

                <div class="tab-content active" id="tab1">
                    <h3>标签页 1 内容</h3>
                    <p>这是第一个标签页的内容。Playwright 可以处理标签页的切换操作。</p>
                </div>

                <div class="tab-content" id="tab2">
                    <h3>标签页 2 内容</h3>
                    <p>这是第二个标签页的内容。通过 Playwright 可以轻松定位和操作标签页。</p>
                </div>

                <div class="tab-content" id="tab3">
                    <h3>标签页 3 内容</h3>
                    <p>这是第三个标签页的内容。自动化测试中标签页切换是常见场景。</p>
                </div>

                <div style="margin-top: 30px;">
                    <h3 class="card-title">导航链接</h3>
                    <div style="display: flex; gap: 15px; flex-wrap: wrap; margin-top: 15px;">
                        <a href="#" class="btn" id="external-link">外部链接</a>
                        <a href="#" class="btn" id="new-tab-link">新标签页打开</a>
                    </div>
                </div>
            </div>
        </div>

        <!-- 动态内容 -->
        <div class="feature-card">
            <div class="card-header">
                <i class="fas fa-sync-alt"></i>
                <h2>动态内容加载</h2>
            </div>
            <div class="card-body">
                <button id="load-content" class="btn" style="margin-bottom: 20px;">
                    <i class="fas fa-redo"></i> 加载动态内容
                </button>

                <div class="result-box" id="dynamic-content">
                    点击按钮加载内容...
                </div>

                <div style="margin-top: 30px;">
                    <h3 class="card-title">AJAX 数据加载</h3>
                    <button id="load-data" class="btn">
                        <i class="fas fa-database"></i> 加载用户数据
                    </button>
                    <div id="user-data"
                         style="margin-top: 20px; padding: 15px; background: #f8f9fa; border-radius: 8px;"></div>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- 模态框 -->
<div class="modal" id="demo-modal">
    <div class="modal-content">
        <span class="close-modal" id="close-modal">&times;</span>
        <h2>Playwright 模态框演示</h2>
        <p>这是一个模态框示例。Playwright 可以处理模态框的打开和关闭操作。</p>
        <p>尝试在模态框中操作元素:</p>

        <div class="form-group" style="margin: 20px 0;">
            <input type="text" id="modal-input" placeholder="在模态框中输入文本">
        </div>

        <button id="modal-action" class="btn">模态框操作</button>
    </div>
</div>

<footer>
    <p>设计用于 Playwright 自动化测试演示 | 包含表单、选择框、按钮、拖放、悬停、文件操作、模态框、导航等交互元素</p>
    <p>使用 <span class="highlight">page.fill()</span>, <span class="highlight">page.click()</span>, <span
            class="highlight">page.selectOption()</span>, <span class="highlight">page.dragAndDrop()</span> 等方法操作这些元素
    </p>
</footer>

<script>
    // 表单提交
    document.getElementById('submit-form').addEventListener('click', function () {
        const username = document.getElementById('username').value;
        const email = document.getElementById('email').value;
        const country = document.getElementById('country').value;

        if (username && email && country) {
            document.getElementById('form-result').textContent =
                `表单提交成功! 用户名: ${username}, 邮箱: ${email}, 国家: ${country}`;
        } else {
            document.getElementById('form-result').textContent = '请填写所有必填字段!';
        }
    });

    // 选择框状态显示
    const checkboxes = document.querySelectorAll('input[type="checkbox"]');
    const radios = document.querySelectorAll('input[type="radio"]');

    function updateSelectionResult() {
        const selectedTech = Array.from(checkboxes)
            .filter(cb => cb.checked)
            .map(cb => cb.nextElementSibling.textContent)
            .join(', ');

        const selectedLang = Array.from(radios)
            .filter(radio => radio.checked)
            .map(radio => radio.nextElementSibling.textContent)
            .join(', ');

        let result = '';
        if (selectedTech) result += `选择的技术: ${selectedTech}\n`;
        if (selectedLang) result += `选择的语言: ${selectedLang}`;

        document.getElementById('selection-result').textContent = result || '未选择任何选项';
    }

    checkboxes.forEach(cb => cb.addEventListener('change', updateSelectionResult));
    radios.forEach(radio => radio.addEventListener('change', updateSelectionResult));

    // 按钮操作
    document.getElementById('alert-btn').addEventListener('click', function () {
        alert('这是一个警告对话框! Playwright 可以处理这类弹窗。');
    });

    document.getElementById('confirm-btn').addEventListener('click', function () {
        const confirmed = confirm('这是一个确认对话框。你确定要继续吗?');
        document.getElementById('selection-result').textContent =
            confirmed ? '用户点击了确定' : '用户点击了取消';
    });

    // 拖放功能
    const dragSource = document.getElementById('drag-source');
    const dragTarget = document.getElementById('drag-target');

    dragSource.addEventListener('dragstart', function (e) {
        e.dataTransfer.setData('text/plain', '拖放内容');
    });

    dragTarget.addEventListener('dragover', function (e) {
        e.preventDefault();
        this.style.borderColor = '#4361ee';
        this.style.backgroundColor = '#d7e3fc';
    });

    dragTarget.addEventListener('dragleave', function () {
        this.style.borderColor = '#6c757d';
        this.style.backgroundColor = '';
    });

    dragTarget.addEventListener('drop', function (e) {
        e.preventDefault();
        const data = e.dataTransfer.getData('text/plain');
        this.innerHTML = `<p>拖放成功! 内容: "${data}"</p>`;
        this.style.borderColor = '#28a745';
        this.style.backgroundColor = '#d4edda';
        document.getElementById('drag-result').textContent = '拖放操作完成!';
    });

    // 鼠标悬停
    const hoverArea = document.getElementById('hover-area');
    const hoverText = document.getElementById('hover-text');

    hoverArea.addEventListener('mouseenter', function () {
        hoverText.textContent = '悬停状态: 激活';
        this.style.backgroundColor = '#ff9900';
    });

    hoverArea.addEventListener('mouseleave', function () {
        hoverText.textContent = '悬停状态: 未激活';
        this.style.backgroundColor = '#ffaa00';
    });

    // 文件上传
    document.getElementById('file-upload').addEventListener('change', function (e) {
        if (this.files.length > 0) {
            document.getElementById('upload-result').textContent =
                `已选择文件: ${this.files[0].name}`;
        } else {
            document.getElementById('upload-result').textContent = '未选择文件';
        }
    });

    // 下载按钮
    document.getElementById('download-btn').addEventListener('click', function () {
        alert('在真实场景中,这将触发文件下载。Playwright 可以处理文件下载操作。');
    });

    // 模态框
    const modal = document.getElementById('demo-modal');
    const openModalBtn = document.getElementById('open-modal');
    const closeModalBtn = document.getElementById('close-modal');

    openModalBtn.addEventListener('click', function () {
        modal.style.display = 'flex';
    });

    closeModalBtn.addEventListener('click', function () {
        modal.style.display = 'none';
    });

    window.addEventListener('click', function (e) {
        if (e.target === modal) {
            modal.style.display = 'none';
        }
    });

    // 标签页
    const tabs = document.querySelectorAll('.tab');
    tabs.forEach(tab => {
        tab.addEventListener('click', function () {
            // 移除所有active类
            tabs.forEach(t => t.classList.remove('active'));
            document.querySelectorAll('.tab-content').forEach(tc => tc.classList.remove('active'));

            // 添加active类到当前标签
            this.classList.add('active');
            const tabId = this.getAttribute('data-tab');
            document.getElementById(tabId).classList.add('active');
        });
    });

    // 动态内容加载
    document.getElementById('load-content').addEventListener('click', function () {
        const dynamicContent = document.getElementById('dynamic-content');
        dynamicContent.innerHTML = `
                <p>动态加载的内容 (${new Date().toLocaleTimeString()})</p>
                <p>Playwright 可以等待动态内容加载完成后再进行操作。</p>
                <ul>
                    <li>项目 1</li>
                    <li>项目 2</li>
                    <li>项目 3</li>
                </ul>
            `;
    });

    // 加载用户数据
    document.getElementById('load-data').addEventListener('click', function () {
        const userDataDiv = document.getElementById('user-data');
        userDataDiv.innerHTML = '<p>加载中...</p>';

        // 模拟 AJAX 请求延迟
        setTimeout(() => {
            userDataDiv.innerHTML = `
                    <h4>用户数据</h4>
                    <table style="width: 100%; border-collapse: collapse;">
                        <tr style="background-color: #f1f1f1;">
                            <th style="padding: 8px; text-align: left;">ID</th>
                            <th style="padding: 8px; text-align: left;">姓名</th>
                            <th style="padding: 8px; text-align: left;">邮箱</th>
                        </tr>
                        <tr>
                            <td style="padding: 8px; border-bottom: 1px solid #ddd;">1</td>
                            <td style="padding: 8px; border-bottom: 1px solid #ddd;">张三</td>
                            <td style="padding: 8px; border-bottom: 1px solid #ddd;">zhangsan@example.com</td>
                        </tr>
                        <tr>
                            <td style="padding: 8px; border-bottom: 1px solid #ddd;">2</td>
                            <td style="padding: 8px; border-bottom: 1px solid #ddd;">李四</td>
                            <td style="padding: 8px; border-bottom: 1px solid #ddd;">lisi@example.com</td>
                        </tr>
                        <tr>
                            <td style="padding: 8px;">3</td>
                            <td style="padding: 8px;">王五</td>
                            <td style="padding: 8px;">wangwu@example.com</td>
                        </tr>
                    </table>
                `;
        }, 1500);
    });

    // 初始化
    updateSelectionResult();
</script>
</body>
</html>

Python代码

import time

from playwright.sync_api import sync_playwright


def run(playwright):
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context(viewport={'width': 1920, 'height': 1080})
    page = context.new_page()

    page.goto("file:///D:/Project/2025/py-ml/005playwright_extend/index.html")

    # 1. 表单操作
    page.fill("#username", "testuser")
    page.fill("#email", "test@example.com")
    page.fill("#password", "securepassword123")
    page.select_option("#country", "cn")
    page.click("#submit-form")
    time.sleep(2)

    # 2. 选择框操作
    page.check("#playwright")
    page.check("#selenium")
    page.click("#python")
    time.sleep(2)

    # 3. 按钮操作
    page.on("dialog", lambda dialog: dialog.accept())
    page.click("#alert-btn")
    page.click("#confirm-btn")
    time.sleep(2)

    # 4. 拖放操作
    page.drag_and_drop("#drag-source", "#drag-target")
    time.sleep(2)

    # 5. 文件上传
    page.set_input_files("#file-upload", "testfile.txt")
    time.sleep(2)

    # 6. 模态框操作
    page.click("#open-modal")
    page.fill("#modal-input", "Playwright test")
    page.click("#close-modal")
    time.sleep(2)

    # 7. 标签页操作
    page.click("text=标签页 2")
    time.sleep(2)

    # 8. 动态内容加载
    page.click("#load-content")
    page.click("#load-data")
    page.wait_for_selector("#user-data table")
    time.sleep(2)

    # 截图保存 类名 container
    el = page.locator("div.container")
    el.screenshot(path="playwright_demo_result.png")

    # 获取页面html保存到save.html中
    with open("save.html", "w", encoding="utf-8") as f:
        f.write(page.content())

    time.sleep(20)

    browser.close()


with sync_playwright() as playwright:
    run(playwright)

在这里插入图片描述
案例4自己本地项目,登录进去进入指定页面点击导出保存文件

from playwright.sync_api import sync_playwright
import os


def run():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)

        # 创建浏览器上下文并启用下载
        download_path = os.path.abspath("my_downloads")  # 设定你的下载目录
        os.makedirs(download_path, exist_ok=True)  # 确保目录存在
        context = browser.new_context(accept_downloads=True)

        page = context.new_page()
        page.goto("http://192.168.90.36:90/")
        page.screenshot(path="r_1.png")

        # 等待登录框可见,填写登录信息
        page.locator('div.loginBox').wait_for(state='visible')
        page.fill('input.input-text.size-L.username', 'admin')
        page.fill('input.input-text.size-L.password', '123456')
        page.screenshot(path="r_2.png")

        # 点击登录按钮
        page.locator('input.btn.btn-success.radius.size-L.login').click()

        # 等待 iframe 加载完成
        page.locator('div#iframe_box').wait_for(state='visible')
        page.screenshot(path="r_3.png")

        # 跳转到目标页面
        page.goto("http://192.168.90.36:90/yhq_exception/yhq27")

        # 等待导出按钮加载完成
        page.locator('button.btn.btn-primary.size-MINI').filter(has_text='导出').wait_for(state='visible')
        page.screenshot(path="r_4.png")

        # 使用 expect_download 监听下载
        with page.expect_download() as download_info:
            page.locator('button.btn.btn-primary.size-MINI').filter(has_text='导出').click()

        # 获取下载的文件
        download = download_info.value
        download_path = os.path.join('my_downloads', download.suggested_filename)

        # 将文件保存到指定的路径
        download.save_as(download_path)
        print(f"Downloaded file saved at: {download_path}")

        # 等待文件下载完成
        # page.wait_for_timeout(60000)

        browser.close()


if __name__ == '__main__':
    run()
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐