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核心对象
-
Browser:对应一个浏览器实例
-
BrowserContext:独立的会话上下文(类似隐身模式)
-
Page:单个标签页或弹出窗口
-
Frame:页面中的iframe
-
Locator:元素定位器
基本工作流程
-
启动浏览器
-
创建页面
-
导航到目标URL
-
定位页面元素
-
执行操作
-
提取数据
-
关闭浏览器
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在网页自动化中的常见应用场景。根据实际需求,你可以组合这些基本操作来实现更复杂的自动化任务。