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

相关推荐
我爱一条柴ya15 分钟前
【AI大模型】LLM模型架构深度解析:BERT vs. GPT vs. T5
人工智能·python·ai·ai编程
G_whang2 小时前
jenkins自动化部署前端vue+docker项目
前端·自动化·jenkins
胡西风_foxww3 小时前
Java的extends通配符
java·开发语言·通配符·extends
胡萝卜的兔3 小时前
golang -gorm 增删改查操作,事务操作
开发语言·后端·golang
屁股割了还要学3 小时前
快速过一遍Python基础语法
开发语言·python·学习·青少年编程
武当豆豆5 小时前
C++编程学习阶段性总结
开发语言·c++
学不动CV了5 小时前
C语言32个关键字
c语言·开发语言·arm开发·单片机·算法
你怎么知道我是队长6 小时前
python-enumrate函数
开发语言·chrome·python
小屁孩大帅-杨一凡6 小时前
如何解决ThreadLocal内存泄漏问题?
java·开发语言·jvm·算法