Playwright Python 教程:网页自动化

1. 常用工具简介及对比

主流网页自动化工具对比

工具 支持语言 浏览器支持 特点 适用场景
Playwright Python, JS, .NET Chromium, Firefox, WebKit 跨浏览器、速度快、API简洁 自动化测试、爬虫、网页操作
Selenium 多语言 所有主流浏览器 历史悠久、社区大 传统自动化测试、兼容性测试
Puppeteer JavaScript Chromium Chrome官方工具、性能好 Chrome相关开发、爬虫
Cypress JavaScript Chromium, Firefox 专注于测试、内置断言库 前端测试

Playwright优势

  • 支持所有现代浏览器

  • 自动等待机制完善

  • 可以拦截修改网络请求

  • 提供设备模拟功能

  • 支持移动端网页测试

2. 安装及自动生成代码

安装步骤

复制代码
# 安装Python包
pip install playwright

# 安装浏览器二进制文件
playwright install

自动生成代码

Playwright提供代码生成工具,可以录制操作并生成代码:

复制代码
# 启动代码生成器
playwright codegen https://example.com

这会打开浏览器窗口和代码编辑器,你的操作会被实时转换为代码。

3. 基本思路及对象介绍

Playwright核心对象

  1. Browser:对应一个浏览器实例

  2. BrowserContext:独立的会话上下文(类似隐身模式)

  3. Page:单个标签页或弹出窗口

  4. Frame:页面中的iframe

  5. Locator:元素定位器

基本工作流程

  1. 启动浏览器

  2. 创建页面

  3. 导航到目标URL

  4. 定位页面元素

  5. 执行操作

  6. 提取数据

  7. 关闭浏览器

4. 打开浏览器

基本启动方式

复制代码
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    # 启动Chromium浏览器(显示界面)
    browser = p.chromium.launch(headless=False)
    
    # 创建新页面
    page = browser.new_page()
    
    # 在这里添加操作代码
    
    # 关闭浏览器
    browser.close()

不同浏览器启动

复制代码
# Firefox
browser = p.firefox.launch()

# WebKit (Safari的渲染引擎)
browser = p.webkit.launch()

浏览器配置选项

复制代码
browser = p.chromium.launch(
    headless=False,  # 显示浏览器窗口
    slow_mo=1000,    # 操作间延迟(毫秒),方便观察
    args=["--start-maximized"],  # 启动参数
    channel="chrome"  # 使用Chrome而非Chromium
)

5. 访问、等待、定位

访问页面

复制代码
# 基本访问
page.goto("https://example.com")

# 带选项的访问
page.goto("https://example.com", timeout=10000, wait_until="networkidle")

等待策略

复制代码
# 等待元素出现
page.wait_for_selector(".result")

# 等待导航完成
page.click("a.link")
page.wait_for_url("**/target-page")

# 等待函数返回True
page.wait_for_function("document.readyState === 'complete'")

# 隐式等待(Playwright自动处理)

元素定位

推荐使用新的定位器API:

复制代码
# 通过文本定位
page.get_by_text("Submit").click()

# 通过角色定位
page.get_by_role("button", name="Sign in").click()

# 通过标签文本定位
page.get_by_label("Username").fill("admin")

# 通过占位文本定位
page.get_by_placeholder("Enter your email").fill("test@example.com")

# 传统CSS/XPath选择器
page.locator("button#submit").click()
page.locator("xpath=//button[@id='submit']").click()

6. 动作

基本交互

复制代码
# 点击
page.get_by_text("Click me").click()
page.get_by_role("button").click(button="right")  # 右键点击

# 输入
page.get_by_label("Username").fill("admin")
page.get_by_label("Password").fill("password")

# 键盘操作
page.get_by_label("Search").press("Enter")

# 鼠标移动
page.get_by_text("Menu").hover()

# 拖放
page.locator("#item").drag_to(page.locator("#target"))

表单操作

复制代码
# 选择单选按钮
page.get_by_label("Agree").check()

# 选择复选框
page.get_by_label("Subscribe").set_checked(True)

# 选择下拉选项
page.get_by_label("Country").select_option("China")

# 上传文件
page.get_by_label("Upload file").set_input_files("myfile.pdf")

# 日期选择
page.get_by_label("Birthday").fill("1990-01-01")

7. 内容解析

获取文本内容

复制代码
# 获取单个元素文本
title = page.locator("h1").text_content()

# 获取多个元素文本
items = page.locator(".item").all()
for item in items:
    print(item.text_content())

获取属性

复制代码
# 获取属性值
href = page.locator("a").get_attribute("href")

# 获取输入框值
value = page.locator("input").input_value()

获取HTML和截图

复制代码
# 获取整个页面HTML
html = page.content()

# 获取元素内部HTML
inner_html = page.locator("div.container").inner_html()

# 截图
page.screenshot(path="screenshot.png")

# 元素截图
page.locator(".header").screenshot(path="header.png")

执行JavaScript获取数据

复制代码
# 执行JavaScript获取数据
data = page.evaluate("""() => {
    return {
        title: document.title,
        width: window.innerWidth
    }
}""")
print(data["title"])

8. 案例

案例1:自动登录并截图

复制代码
from playwright.sync_api import sync_playwright

def auto_login():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        
        # 访问登录页
        page.goto("https://example.com/login")
        
        # 填写登录表单
        page.get_by_label("Username").fill("testuser")
        page.get_by_label("Password").fill("password123")
        page.get_by_role("button", name="Login").click()
        
        # 等待登录成功
        page.wait_for_url("**/dashboard")
        
        # 截图保存
        page.screenshot(path="dashboard.png")
        
        # 获取欢迎信息
        welcome = page.get_by_text("Welcome,").text_content()
        print(welcome)
        
        browser.close()

auto_login()

案例2:爬取商品列表

复制代码
from playwright.sync_api import sync_playwright
import csv

def scrape_products():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto("https://example.com/products")
        
        products = []
        
        # 获取所有商品元素
        items = page.locator(".product-item").all()
        for item in items:
            product = {
                "name": item.locator(".product-name").text_content(),
                "price": item.locator(".price").text_content(),
                "link": item.locator("a").get_attribute("href")
            }
            products.append(product)
        
        # 保存到CSV
        with open("products.csv", "w", newline="", encoding="utf-8") as f:
            writer = csv.DictWriter(f, fieldnames=["name", "price", "link"])
            writer.writeheader()
            writer.writerows(products)
        
        browser.close()

scrape_products()

案例3:处理动态加载内容

复制代码
from playwright.sync_api import sync_playwright
import time

def scrape_infinite_scroll():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto("https://example.com/infinite-scroll")
        
        # 获取初始项目数
        items = page.locator(".item")
        last_count = items.count()
        
        while True:
            # 滚动到底部
            page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
            
            # 等待新内容加载
            time.sleep(2)  # 简单等待,实际项目应该用wait_for_selector
            
            # 检查是否加载了新内容
            new_count = items.count()
            if new_count == last_count:
                break  # 没有新内容了
            last_count = new_count
        
        # 提取所有内容
        all_items = items.all()
        for item in all_items:
            print(item.text_content())
        
        browser.close()

scrape_infinite_scroll()

案例4:下载文件

复制代码
from playwright.sync_api import sync_playwright

def download_file():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        
        # 监听下载事件
        with page.expect_download() as download_info:
            page.goto("https://example.com/download")
            page.click("#download-button")
        
        download = download_info.value
        print(f"Downloading: {download.url}")
        
        # 保存文件
        path = download.path()
        download.save_as("downloaded_file.pdf")
        
        print(f"File saved to: {path}")
        browser.close()

download_file()

这些案例展示了Playwright在网页自动化中的常见应用场景。根据实际需求,你可以组合这些基本操作来实现更复杂的自动化任务。

相关推荐
csbysj20204 小时前
XSLT Apply:深入解析XSLT在XML转换中的应用
开发语言
不会kao代码的小王4 小时前
突破机房围墙:openEuler设备的公网管理实战指南
开发语言·数据库·笔记
CodeCraft Studio4 小时前
CAD文件处理控件Aspose.CAD教程:在 Python 中将 SVG 转换为 PDF
开发语言·python·pdf·svg·cad·aspose·aspose.cad
mortimer5 小时前
从预处理到合成:基于pySide6的视频翻译多线程流水线架构详解
python·github
消失的旧时光-19435 小时前
人脸跟随 ( Channel 实现(缓存5条数据 + 2度过滤 + 平滑移动))
android·java·开发语言·kotlin
默默coding的程序猿5 小时前
1.单例模式有哪几种常见的实现方式?
java·开发语言·spring boot·spring·单例模式·设计模式·idea
喜欢吃豆5 小时前
从潜在空间到实际应用:Embedding模型架构与训练范式的综合解析
python·自然语言处理·架构·大模型·微调·embedding
AndrewHZ5 小时前
【图像处理基石】暗光增强算法入门:从原理到实战(Python+OpenCV)
图像处理·python·opencv·算法·计算机视觉·cv·暗光增强
MOON404☾5 小时前
Rust程序语言设计(5-8)
开发语言·后端·rust
纪伊路上盛名在6 小时前
python5.1 数据类dataclass
python·面向对象编程·oop