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

相关推荐
至此流年莫相忘10 分钟前
设计模式:模板方法模式
java·开发语言·设计模式
demaichuandong30 分钟前
详细讲解锥齿轮丝杆升降机的加工制造工艺
人工智能·自动化·制造
土了个豆子的1 小时前
02.继承MonoBehaviour的单例模式基类
开发语言·visualstudio·单例模式·c#·里氏替换原则
疯狂的维修1 小时前
c#中public类比博图
c#·自动化
qq_172805591 小时前
Go 自建库的使用教程与测试
开发语言·后端·golang
久绊A1 小时前
Hydra-SSH 破解安全防范
开发语言·php
ZZHow10241 小时前
02OpenCV基本操作
python·opencv·计算机视觉
阿昭L1 小时前
c++中获取随机数
开发语言·c++
计算机学长felix1 小时前
基于Django的“酒店推荐系统”设计与开发(源码+数据库+文档+PPT)
数据库·python·mysql·django·vue
3壹1 小时前
数据结构精讲:栈与队列实战指南
c语言·开发语言·数据结构·c++·算法