Playwright Python 教程:网页自动化

发布于:2025-07-13 ⋅ 阅读:(14) ⋅ 点赞:(0)

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在网页自动化中的常见应用场景。根据实际需求,你可以组合这些基本操作来实现更复杂的自动化任务。


网站公告

今日签到

点亮在社区的每一天
去签到