PythonPlaywright语法知识详解(推荐)

作者:

文章目录
  • Playwright 是一个强大的浏览器自动化框架,支持 Chromium、Firefox 和 WebKit。以下是 Playwright for Python 的全面语法详解。
  • 目录
    • Playwright for Python 语法详解
      • 安装与设置
        • 1. 安装 Playwright
        • 2. 初始化项目
      • 基础语法结构
        • 1. 同步与异步模式
        • 2. 浏览器启动选项
      • 页面导航与操作
        • 1. 页面导航
        • 2. 等待策略
      • 元素定位与交互
        • 1. 元素选择器
        • 2. 元素交互方法
        • 3. 元素状态检查
      • 高级交互技术
        • 1. 键盘操作
        • 2. 鼠标操作
        • 3. 触摸屏模拟
      • 页面与框架管理
        • 1. 多页面处理
        • 2. 框架处理
        • 3. 页面上下文
      • 网络请求处理
        • 1. 请求拦截与修改
        • 2. 请求监控
        • 3. API请求直接调用
      • 断言与验证
        • 1. 内置断言
        • 2. 等待断言
      • 截图与PDF生成
        • 1. 截图功能
        • 2. PDF生成
      • 高级功能
        • 1. 设备模拟
        • 2. 地理位置与权限
        • 3. Cookie与存储
      • 测试框架集成
        • 1. 与Pytest集成
        • 2. 测试最佳实践
      • 调试与故障排除
        • 1. 调试技巧
        • 2. 选择器调试
      • 性能优化
        • 1. 浏览器上下文复用
        • 2. 并行执行
      • 总结
        • 相关文献

        Playwright 是一个强大的浏览器自动化框架,支持 Chromium、Firefox 和 WebKit。以下是 Playwright for Python 的全面语法详解。

        # 安装 Playwright Python 包
        pip install playwright
        # 安装浏览器二进制文件
        playwright install

        # 在项目目录中创建 requirements.txt
        echo "playwright" > requirements.txt
        # 创建基本的测试结构
        mkdir tests
        touch tests/test_example.py

        from playwright.sync_api import sync_playwright
        def run_sync():
            with sync_playwright() as p:
                browser = p.chromium.launch(headless=False)
                page = browser.new_page()
                page.goto('https://example.com')
                browser.close()
        run_sync()
        import asyncio
        from playwright.async_api import async_playwright
        async def run_async():
            async with async_playwright() as p:
                browser = await p.chromium.launch(headless=False)
                page = await browser.new_page()
                await page.goto('https://example.com')
                await browser.close()
        asyncio.run(run_async())

        # 各种浏览器启动选项
        browser = p.chromium.launch(
            headless=False,           # 显示浏览器界面
            slow_mo=100,             # 操作间延迟(毫秒)
            args=['--start-maximized'],  # 浏览器参数
            executable_path='/path/to/chrome',  # 指定浏览器路径
            timeout=30000,            # 超时时间
            devtools=True,            # 打开开发者工具
            proxy={
                'server': 'http://proxy.example.com:8080',
                'username': 'user',
                'password': 'pass'
            }
        )

        # 基本导航
        page.goto('https://example.com')
        # 带选项的导航
        page.goto('https://example.com', 
            timeout=30000,           # 超时时间
            wait_until='networkidle', # 等待条件:'load'|'domcontentloaded'|'networkidle'
            referer='https://google.com' # 设置referer
        )
        # 导航事件处理
        page.on('load', lambda: print('Page loaded!'))
        # 前进和后退
        page.go_back()
        page.go_forward()
        # 重新加载
        page.reload()

        # 等待元素出现
        page.wait_for_selector('#element-id', timeout=10000)
        # 等待特定条件
        page.wait_for_function('document.querySelector(".content").innerText.includes("Hello")')
        # 等待超时
        page.wait_for_timeout(3000)  # 等待3秒
        # 等待导航完成
        with page.expect_navigation():
            page.click('a#submit')
        # 等待弹出窗口
        with page.expect_popup() as popup_info:
            page.click('a[target="_blank"]')
        popup = popup_info.value

        # CSS选择器
        page.click('button.submit')
        page.fill('input#username', 'myuser')
        # XPath选择器
        page.click('//button[text()="Submit"]')
        # 文本选择器
        page.click('text=Login')
        page.click('text="Click here"')  # 精确匹配
        # 组合选择器
        page.click('div.container >> text=Submit')
        # 根据属性选择
        page.click('[data-testid="submit-button"]')
        # 根据可见性选择
        page.click('button:visible')
        # 根据状态选择
        page.click('button:enabled')
        page.click('input:checked')

        # 点击操作
        page.click('button')
        page.dblclick('button')
        page.click('button', button='right')  # 右键点击
        page.click('button', modifiers=['Shift'])  # 带修饰键点击
        # 输入操作
        page.fill('input#name', 'John Doe')
        page.type('input#name', 'Hello World', delay=100)  # 模拟按键延迟
        # 选择操作
        page.select_option('select#colors', 'red')
        page.select_option('select#colors', index=1)  # 按索引选择
        page.select_option('select#colors', value=['red', 'blue'])  # 多选
        # 复选框和单选按钮
        page.check('input#agree')
        page.uncheck('input#subscribe')
        # 文件上传
        page.set_input_files('input[type=file]', 'path/to/file.txt')
        page.set_input_files('input[type=file]', ['file1.txt', 'file2.txt'])  # 多文件
        # 聚焦和模糊
        page.focus('input#search')
        page.blur('input#search')
        # 悬停
        page.hover('div.menu-item')
        # 拖放
        page.drag_and_drop('#source', '#target')

        # 检查元素存在
        if page.query_selector('div.error'):
            print('Error element exists')
        # 检查元素可见性
        is_visible = page.is_visible('div.popup')
        is_hidden = page.is_hidden('div.loading')
        # 检查元素状态
        is_enabled = page.is_enabled('button.submit')
        is_checked = page.is_checked('input#agree')
        is_editable = page.is_editable('input#name')
        # 获取元素属性
        value = page.get_attribute('img#logo', 'src')
        class_name = page.get_attribute('div.container', 'class')
        # 获取元素文本
        text = page.text_content('div.message')
        inner_text = page.inner_text('div.message')
        # 获取元素HTML
        html = page.inner_html('div.container')
        # 获取输入值
        input_value = page.input_value('input#email')

        # 键盘输入
        page.keyboard.type('Hello World!')
        page.keyboard.press('Enter')
        page.keyboard.down('Shift')
        page.keyboard.up('Shift')
        # 快捷键
        page.keyboard.press('Control+A')  # 全选
        page.keyboard.press('Control+C')  # 复制
        page.keyboard.press('Control+V')  # 粘贴
        # 特殊键
        page.keyboard.press('ArrowLeft')
        page.keyboard.press('Tab')
        page.keyboard.press('Escape')

        # 获取元素位置
        bounding_box = page.query_selector('button').bounding_box()
        # 精确鼠标控制
        page.mouse.move(bounding_box['x'] + bounding_box['width']/2, 
                        bounding_box['y'] + bounding_box['height']/2)
        page.mouse.click(bounding_box['x'] + bounding_box['width']/2, 
                         bounding_box['y'] + bounding_box['height']/2)
        # 鼠标拖拽
        page.mouse.down()
        page.mouse.move(100, 100)
        page.mouse.up()

        # 触摸操作
        page.touchscreen.tap(100, 100)
        # 多点触控
        page.touchscreen.tap_point(100, 100)
        page.touchscreen.tap_point(200, 200)

        # 获取所有页面
        all_pages = context.pages
        # 创建新页面
        new_page = context.new_page()
        # 等待新页面
        with context.expect_page() as new_page_info:
            page.click('a[target="_blank"]')
        new_page = new_page_info.value
        # 切换到特定页面
        context.pages[1].bring_to_front()

        # 获取框架
        frame = page.frame(name='frame-name')
        frame = page.frame(url=r'.*login.*')
        # 框架内操作
        frame.click('button.submit')
        frame.fill('input#username', 'user')
        # 遍历所有框架
        for frame in page.frames:
            print(frame.name)

        # 执行JavaScript
        page.evaluate('document.title')
        result = page.evaluate('([x, y]) => x + y', [1, 2])
        # 注入JavaScript
        page.add_script_tag(url='https://code.jquery.com/jquery.js')
        page.add_script_tag(content='console.log("Hello");')
        # 注入样式
        page.add_style_tag(url='https://cdn.example.com/style.css')
        page.add_style_tag(content='body { background: red; }')
        # 设置页面内容
        page.set_content('<html><body><h1>Hello</h1></body></html>')

        # 路由拦截
        def handle_route(route):
            if 'api.example.com' in route.request.url:
                route.fulfill(
                    status=200,
                    content_type='application/json',
                    body='{"success": true}'
                )
            else:
                route.continue_()
        page.route('**/*', handle_route)
        # 特定模式拦截
        page.route('**/*.jpg', lambda route: route.abort())
        page.route('**/api/*', handle_route)
        # 修改请求头
        page.route('**/*', lambda route: route.continue_(headers={**route.request.headers, 'x-custom': 'value'}))

        # 请求事件处理
        def log_request(request):
            print(f"Request: {request.method} {request.url}")
        def log_response(response):
            print(f"Response: {response.status} {response.url}")
        page.on('request', log_request)
        page.on('response', log_response)
        # 等待请求完成
        with page.expect_response('https://example.com/api/data') as response_info:
            page.click('button#load-data')
        response = response_info.value
        # 等待多个请求
        with page.expect_response(lambda response: response.url.startswith('https://api')) as response_info:
            page.click('button#fetch')

        # 使用Playwright发起API请求
        response = page.request.get('https://api.example.com/data')
        print(response.json())
        # 带参数的请求
        response = page.request.post(
            'https://api.example.com/login',
            data={'username': 'user', 'password': 'pass'},
            headers={'Content-Type': 'application/json'}
        )

        # 页面标题断言
        assert page.title() == 'Expected Title'
        # URL断言
        assert page.url == 'https://example.com'
        # 元素可见性断言
        assert page.is_visible('div.success')
        # 文本内容断言
        assert 'Welcome' in page.text_content('body')

        # 等待元素出现并断言
        page.wait_for_selector('div.success', state='visible')
        assert page.text_content('div.success') == 'Operation successful'
        # 等待文本出现
        page.wait_for_selector('text=Welcome back')
        # 等待函数条件
        page.wait_for_function('() => document.querySelectorAll(".item").length > 5')

        # 页面截图
        page.screenshot(path='screenshot.png')
        # 元素截图
        page.locator('div.chart').screenshot(path='chart.png')
        # 截图选项
        page.screenshot(
            path='fullpage.png',
            full_page=True,           # 截取完整页面
            type='jpeg',              # 图片类型:'png'|'jpeg'
            quality=80,               # JPEG质量(0-100)
            omit_background=True,     # 隐藏默认背景
            timeout=10000             # 超时时间
        )

        # 生成PDF
        page.pdf(
            path='page.pdf',
            scale=0.8,                # 缩放比例
            format='A4',              # 纸张格式
            margin={'top': '1cm', 'bottom': '1cm'},  # 边距
            print_background=True,    # 打印背景
            landscape=False           # 横向/纵向
        )
        

        # 模拟移动设备
        from playwright.sync_api import sync_playwright
        def test_mobile():
            with sync_playwright() as p:
                # 获取设备描述符
                iPhone = p.devices['iPhone 12 Pro']
                # 使用设备模拟创建上下文
                browser = p.chromium.launch()
                context = browser.new_context(**iPhone)
                page = context.new_page()
                page.goto('https://example.com')
                # 移动端测试代码...
                browser.close()

        # 模拟地理位置
        context = browser.new_context(
            geolocation={'longitude': 116.397128, 'latitude': 39.916697},
            permissions=['geolocation']
        )
        # 模拟权限
        context = browser.new_context(
            permissions=['notifications', 'microphone']
        )

        # 设置Cookie
        context.add_cookies([{
            'name': 'session',
            'value': 'abc123',
            'url': 'https://example.com',
            'domain': 'example.com',
            'path': '/',
            'httpOnly': True,
            'secure': True,
            'expires': int(time.time()) + 3600  # 1小时后过期
        }])
        # 获取Cookie
        cookies = context.cookies()

        # conftest.py
        import pytest
        from playwright.sync_api import sync_playwright
        @pytest.fixture(scope='session')
        def browser():
            with sync_playwright() as p:
                browser = p.chromium.launch(headless=False)
                yield browser
                browser.close()
        @pytest.fixture
        def page(browser):
            context = browser.new_context()
            page = context.new_page()
            yield page
            context.close()
        # test_example.py
        def test_login(page):
            page.goto('https://example.com/login')
            page.fill('input#username', 'testuser')
            page.fill('input#password', 'password')
            page.click('button#submit')
            assert page.url == 'https://example.com/dashboard'

        # 页面对象模型
        class LoginPage:
            def __init__(self, page):
                self.page = page
                self.username_input = page.locator('input#username')
                self.password_input = page.locator('input#password')
                self.submit_button = page.locator('button#submit')
            def navigate(self):
                self.page.goto('https://example.com/login')
            def login(self, username, password):
                self.username_input.fill(username)
                self.password_input.fill(password)
                self.submit_button.click()
        # 使用页面对象
        def test_login(page):
            login_page = LoginPage(page)
            login_page.navigate()
            login_page.login('testuser', 'password')
            assert page.url == 'https://example.com/dashboard'

        # 启用调试模式
        browser = p.chromium.launch(headless=False, devtools=True)
        # 暂停执行
        page.pause()
        # 慢速模式
        browser = p.chromium.launch(headless=False, slow_mo=1000)
        # 记录控制台输出
        page.on('console', lambda msg: print(f'CONSOLE: {msg.text}'))
        # 记录页面错误
        page.on('pageerror', lambda err: print(f'PAGE ERROR: {err}'))
        # 记录请求失败
        page.on('requestfailed', lambda req: print(f'REQUEST FAILED: {req.url} {req.failure}'))

        # 高亮匹配元素
        page.locator('button').highlight()
        # 评估选择器
        count = page.locator('button').count()
        print(f'Found {count} buttons')
        # 调试选择器
        try:
            page.wait_for_selector('button:visible', timeout=5000)
        except:
            print('Button not found within 5 seconds')

        # 复用浏览器上下文
        context = browser.new_context()
        # 在不同测试中复用
        def test_1(context):
            page = context.new_page()
            # 测试代码...
        def test_2(context):
            page = context.new_page()
            # 测试代码...
        # 清理上下文
        context.clear_cookies()
        context.clear_permissions()

        # 使用多线程并行测试
        import concurrent.futures
        def run_test(test_func, browser_type):
            with sync_playwright() as p:
                browser = getattr(p, browser_type).launch()
                context = browser.new_context()
                page = context.new_page()
                test_func(page)
                browser.close()
        with concurrent.futures.ThreadPoolExecutor() as executor:
            futures = []
            for _ in range(3):
                futures.append(executor.submit(run_test, test_function, 'chromium'))
            for future in concurrent.futures.as_completed(futures):
                future.result()

        Playwright for Python 提供了强大而灵活的浏览器自动化能力。通过掌握上述语法和技巧,您可以:

        1. 创建可靠的浏览器自动化脚本
        2. 实现复杂的用户交互模拟
        3. 处理各种网络条件和异常情况
        4. 集成到现有的测试框架中
        5. 优化脚本性能和稳定性

        Playwright 的持续更新和活跃社区确保了其功能的不断改进和扩展,使其成为现代Web自动化测试的首选工具之一。

        Playwright for Python 推荐项目结构
        【Python知识】使用 Playwright for Python 从零开始搭建自动化测试方案
        【Python知识】Playwright for Python 脚本录制指南

        到此这篇关于Python Playwright 语法知识详解的文章就介绍到这了,更多相关Python Playwright 语法内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

        您可能感兴趣的文章:

        • python playwright解决iframe上下文定位功能完整方案
        • 从入门到进阶讲解Python自动化Playwright实战指南
        • Python自动化神器Playwright的用法详解
        • Python Playwright进行常见的页面交互操作
        • Python中Playwright模块进行自动化测试的实现
        • python+playwright 元素操作示例代码
        • Python Playwright安装和基本使用问题记录
        • Python Playwright 文本框操作技巧
        • Python中Playwright的常用操作方法分享

        站内搜索