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

相关推荐
chatexcel44 分钟前
元空AI+Clawdbot:7×24 AI办公智能体新形态详解(长期上下文/自动化任务/工具粘合)
运维·人工智能·自动化
青岑CTF1 小时前
攻防世界-Ics-05-胎教版wp
开发语言·安全·web安全·网络安全·php
Li emily1 小时前
如何通过外汇API平台快速实现实时数据接入?
开发语言·python·api·fastapi·美股
m0_561359671 小时前
掌握Python魔法方法(Magic Methods)
jvm·数据库·python
Ulyanov1 小时前
顶层设计——单脉冲雷达仿真器的灵魂蓝图
python·算法·pyside·仿真系统·单脉冲
APIshop1 小时前
Java 实战:调用 item_search_tmall 按关键词搜索天猫商品
java·开发语言·数据库
血小板要健康2 小时前
Java基础常见面试题复习合集1
java·开发语言·经验分享·笔记·面试·学习方法
淼淼7632 小时前
安装jdk1.8
java·开发语言
2401_838472512 小时前
使用Python进行图像识别:CNN卷积神经网络实战
jvm·数据库·python
PfCoder2 小时前
WinForm真入门(23)---PictureBox 控件详细用法
开发语言·windows·c#·winform