网络爬虫Playwright Python 教程:从入门到实战

这是一份专为移动端阅读优化的 Playwright Python 教程,语言通俗、步骤清晰、示例完整。全程用同步模式演示(新手友好),关键处会标注异步写法差异。

一、准备工作:安装与环境配置

1. 安装核心包

打开命令行,执行以下命令:

bash

复制代码
pip install playwright  # 安装Playwright库
playwright install      # 自动安装Chromium、Firefox、WebKit浏览器

2. 验证安装

创建test_install.py文件,运行以下代码:

python

复制代码
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)  # 启动Chrome浏览器(显示界面)
    page = browser.new_page()                    # 新建标签页
    page.goto("https://www.baidu.com")           # 访问百度
    print("页面标题:", page.title())             # 打印标题
    browser.close()                              # 关闭浏览器

运行后能看到浏览器打开并显示百度页面,说明安装成功。

二、核心概念:Playwright 基础架构

Playwright 有四个核心对象,你必须牢记:

  1. Playwright 实例:入口点,控制所有浏览器
  2. Browser:浏览器实例(如 Chrome、Firefox)
  3. Context:浏览器上下文(相当于无痕窗口,可多个并行)
  4. Page:单个标签页(核心操作对象)

标准写法模板(记住这个格式):

python

复制代码
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    # 1. 启动浏览器(headless=False显示界面)
    browser = p.chromium.launch(headless=False, slow_mo=1000)  # slow_mo:慢动作,方便观察
    
    # 2. 创建上下文(可选,用于多用户场景)
    context = browser.new_context()
    
    # 3. 新建页面
    page = context.new_page()
    
    # 4. 页面操作(核心代码写这里)
    page.goto("https://example.com")
    
    # 5. 关闭资源(with语句自动处理,可不写)
    context.close()
    browser.close()

三、页面操作:基础功能全掌握

1. 页面导航与等待

python

复制代码
# 基础导航(自动等待页面加载完成)
page.goto("https://example.com", timeout=10000)  # 超时10秒

# 前进/后退/刷新
page.go_back()
page.go_forward()
page.reload()

# 获取页面信息
print("URL:", page.url)           # 当前网址
print("标题:", page.title())      # 页面标题
print("内容:", page.content())    # 完整HTML内容

2. 截图与 PDF 导出

python

复制代码
# 截取整个页面
page.screenshot(path="full_page.png", full_page=True)

# 截取特定元素
page.locator("h1").screenshot(path="element.png")

# 导出PDF(仅Chrome支持)
page.pdf(path="page.pdf", format="A4")

四、元素定位:精准找到页面元素

这是 Playwright 最强大的功能之一,推荐使用Locator API(自动等待元素加载)。

1. 推荐定位方式(按优先级排序)

方法 用途 示例
get_by_role 按角色定位(最推荐,符合无障碍标准) page.get_by_role ("button", name="搜索")
get_by_text 按文本内容定位 page.get_by_text ("登录")
get_by_label 按表单标签定位 page.get_by_label ("用户名")
get_by_placeholder 按输入框提示定位 page.get_by_placeholder ("请输入密码")
get_by_test_id 按测试 ID 定位(推荐开发添加) page.get_by_test_id("submit-btn")

2. 传统定位方式(兼容旧代码)

python

复制代码
# CSS选择器(最常用)
page.locator("input#kw")          # ID选择器
page.locator(".result-title")     # 类选择器
page.locator("div > a")           # 层级选择器

# XPath选择器(复杂场景)
page.locator("//input[@name='username']")

3. 定位示例

python

复制代码
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto("https://www.baidu.com")
    
    # 1. 按角色定位搜索框并输入内容
    search_box = page.get_by_role("textbox", name="百度搜索")
    search_box.fill("Playwright教程")  # 填充内容
    
    # 2. 按文本定位搜索按钮并点击
    search_btn = page.get_by_text("百度一下")
    search_btn.click()
    
    # 3. 等待结果加载并打印第一个结果标题
    page.wait_for_load_state("networkidle")  # 等待网络空闲
    first_result = page.locator(".result-op a:first-child")
    print("第一个结果:", first_result.text_content())
    
    browser.close()

五、交互操作:模拟用户行为

1. 输入操作

python

复制代码
# 填充内容(推荐,自动清空原有内容)
page.get_by_label("用户名").fill("test_user")

# 逐字输入(模拟真实打字,delay:毫秒间隔)
page.get_by_label("密码").type("secret123", delay=100)

# 清空输入框
page.get_by_label("搜索").clear()

2. 点击与选择

python

复制代码
# 普通点击
page.get_by_text("提交").click()

# 双击/右键点击
page.locator(".item").dblclick()
page.locator(".menu").click(button="right")

# 复选框/单选框
page.get_by_label("同意条款").check()
page.get_by_label("男").check()

# 下拉框选择
page.get_by_label("城市").select_option(value="beijing")  # 按值选择
page.get_by_label("城市").select_option(label="上海")     # 按文本选择
page.get_by_label("城市").select_option(index=3)          # 按索引选择

3. 键盘与鼠标操作

python

复制代码
# 键盘操作(按Enter键)
page.keyboard.press("Enter")

# 组合键(Ctrl+A全选,然后删除)
page.keyboard.press("Control+A")
page.keyboard.press("Backspace")

# 鼠标悬停
page.locator(".dropdown").hover()

# 拖拽操作(从元素A拖到元素B)
page.locator("#source").drag_to(page.locator("#target"))

4. 交互示例:模拟登录流程

python

复制代码
from playwright.sync_api import sync_playwright

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("用户名").fill("admin")
    page.get_by_label("密码").fill("123456")
    page.get_by_label("记住我").check()
    page.get_by_role("button", name="登录").click()
    
    # 验证登录成功
    page.wait_for_url("**/dashboard")  # 等待跳转到仪表盘
    print("登录成功!")
    
    browser.close()

六、等待机制:告别不稳定脚本

Playwright 最强大的特性之一:自动等待。所有操作前都会自动等待元素可见、可交互,无需手动添加 sleep。

1. 自动等待(默认启用)

python

复制代码
# 自动等待搜索框出现并可输入
page.get_by_label("搜索").fill("Playwright")

# 自动等待按钮可点击
page.get_by_text("搜索").click()

2. 显式等待(复杂场景)

python

复制代码
# 等待元素可见
page.locator(".success-message").wait_for(state="visible")

# 等待页面加载完成
page.wait_for_load_state("load")  # 基本加载完成
page.wait_for_load_state("networkidle")  # 网络空闲(推荐)

# 等待自定义条件
page.wait_for_function("() => document.title.includes('成功')")

七、高级功能:解锁更多可能性

1. 网络请求拦截与模拟

python

复制代码
from playwright.sync_api import sync_playwright

def handle_route(route):
    """拦截并修改网络请求"""
    if "api/data" in route.request.url:
        # 返回模拟数据
        route.fulfill(
            status=200,
            json={"name": "测试数据", "value": 123}
        )
    else:
        route.continue_()  # 其他请求正常放行

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    
    # 启用请求拦截
    page.route("**/*", handle_route)
    
    page.goto("https://example.com")
    browser.close()

2. 移动端模拟

python

复制代码
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    # 模拟iPhone 12
    iphone_12 = p.devices["iPhone 12"]
    context = p.chromium.launch_persistent_context(
        "",  # 本地目录,用于保存缓存
        **iphone_12,
        headless=False
    )
    page = context.new_page()
    page.goto("https://m.baidu.com")  # 访问移动端网站
    page.touchscreen.tap(50, 100)    # 模拟触屏点击
    context.close()

3. 执行 JavaScript 代码

python

python 复制代码
# 执行简单JS并获取结果
width = page.evaluate("() => window.innerWidth")
print("窗口宽度:", width)

# 传递参数给JS
result = page.evaluate("(a, b) => a + b", 10, 20)
print("计算结果:", result)

# 操作页面元素
page.evaluate("document.querySelector('h1').style.color = 'red'")

4. 处理弹窗与 iframe

python

复制代码
# 处理alert弹窗
page.on("dialog", lambda dialog: dialog.accept())  # 自动接受弹窗

# 处理iframe
frame = page.frame_locator("iframe[name='payment']")
frame.get_by_label("信用卡号").fill("4111 1111 1111 1111")

八、网络监听:实时捕获、分析接口数据

这是 Playwright 爬虫、接口调试、自动化测试 必备功能!作用:监控浏览器所有网络请求(接口、图片、JS 等),捕获请求 URL、参数、请求头、响应数据,无需抓包工具。

1. 基础监听:捕获所有网络请求

最简单用法,打印浏览器发出的所有请求信息

python

复制代码
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()

    # ========== 核心:注册网络监听 ==========
    # 监听请求发送
    def on_request(request):
        # 过滤:只打印接口请求,忽略图片/样式
        if request.resource_type in ["xhr", "fetch"]:
            print(f"请求地址:{request.url}")
            print(f"请求方式:{request.method}")
            print("-"*50)

    # 监听响应返回
    def on_response(response):
        if response.resource_type in ["xhr", "fetch"]:
            print(f"响应状态:{response.status} | 地址:{response.url}")

    # 绑定监听事件
    page.on("request", on_request)
    page.on("response", on_response)

    # 测试页面
    page.goto("https://www.baidu.com")
    page.get_by_role("textbox", name="百度搜索").fill("Playwright")
    page.get_by_text("百度一下").click()
    page.wait_for_timeout(3000)  # 等待请求完成

    browser.close()

2. 精准监听:提取接口 JSON 数据(实战首选)

直接获取接口返回的业务数据,爬虫 / 测试必用

python

复制代码
from playwright.sync_api import sync_playwright
import json

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()

    # 监听并解析接口响应数据
    def on_response(response):
        # 只监听百度搜索的接口
        if "suggestion" in response.url and response.status == 200:
            print("抓到目标接口!")
            # 获取JSON数据
            data = response.json()
            print("接口返回数据:", json.dumps(data, ensure_ascii=False))

    page.on("response", on_response)

    # 执行搜索
    page.goto("https://www.baidu.com")
    page.get_by_role("textbox", name="百度搜索").fill("网络监听")
    page.wait_for_timeout(3000)

    browser.close()

3. 监听请求参数(POST/GET 参数)

获取接口提交的参数,用于调试和复现请求

python

复制代码
def on_request(request):
    # 监听POST接口
    if request.method == "POST" and "api" in request.url:
        print("请求头:", request.headers)
        print("请求参数:", request.post_data)  # POST数据
        print("GET参数:", request.params)      # GET参数

page.on("request", on_request)

4. 监听 + 拦截:一站式控制网络

结合路由,既监听又修改请求(进阶)

python

复制代码
# 先监听,再拦截修改
def handle_route(route):
    print(f"拦截请求:{route.request.url}")
    route.continue_()

page.route("**/*", handle_route)

九、实战案例:百度搜索完整流程

以下是一个完整的自动化脚本,包含所有核心操作:

python

复制代码
from playwright.sync_api import sync_playwright, expect

def test_baidu_search():
    with sync_playwright() as p:
        # 1. 启动浏览器
        browser = p.chromium.launch(headless=False, slow_mo=500)
        page = browser.new_page()
        
        try:
            # 2. 访问百度
            page.goto("https://www.baidu.com", timeout=15000)
            expect(page).to_have_title("百度一下,你就知道")  # 断言标题
            
            # 3. 搜索Playwright
            search_box = page.get_by_role("textbox", name="百度搜索")
            search_box.fill("Playwright Python教程")
            page.get_by_text("百度一下").click()
            
            # 4. 等待结果并验证
            page.wait_for_load_state("networkidle")
            expect(page.locator(".result-op")).to_have_count(10)  # 断言有10个结果
            
            # 5. 点击第一个结果
            first_result = page.locator(".result-op a:first-child")
            first_result.click()
            
            # 6. 验证新页面
            page.wait_for_url("**/playwright/**")
            print("搜索并打开结果成功!")
            
        except Exception as e:
            print("出错了:", e)
            page.screenshot(path="error.png")  # 出错时截图
        finally:
            browser.close()

test_baidu_search()

十、异步编程:提升执行效率

Playwright 支持异步模式,适合同时处理多个页面:

python

复制代码
import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        await page.goto("https://example.com")
        print(await page.title())
        await browser.close()

asyncio.run(main())

十一、最佳实践:编写稳定可靠的脚本

  1. 优先使用 Locator API:自动等待,避免大部分超时问题
  2. 使用 role 定位器:比 CSS 选择器更稳定,不受页面结构变化影响
  3. 避免硬等待 :用wait_for代替time.sleep()
  4. 处理异常:使用 try-except 捕获错误并截图
  5. 复用浏览器上下文:多个测试用例共享一个 context,提升速度

常见问题解答

  1. Q:浏览器启动后立即关闭? A:确保使用with语句或显式调用browser.close(),不要在异步代码中混用同步方法。
  2. **Q:元素定位不到?**A:检查选择器是否正确,尝试使用更稳定的 role 定位器,或等待元素加载完成。
  3. Q:如何调试脚本? A:添加slow_mo=1000参数(慢动作),或使用page.pause()在指定位置暂停执行。

总结

  1. 网络监听核心:page.on("request") 监听请求、page.on("response") 监听响应
  2. 实战用法:过滤接口、提取 JSON 数据、获取请求参数
  3. 适用场景:爬虫抓数据、接口调试、自动化测试验证接口
相关推荐
啥咕啦呛2 小时前
跟着AI学Java第2天:Java基础语法巩固
java·python·算法
2301_764150562 小时前
C#怎么判断进程是否在运行_C#如何管理系统进程【必备】
jvm·数据库·python
摸鱼界在逃劳模2 小时前
Java的JDK下载与安装
java·开发语言
justjinji2 小时前
Django DRF权限怎么加_IsAuthenticated与自定义BasePermission
jvm·数据库·python
蓝色的杯子2 小时前
MCP 入门到实战指南
人工智能·python·mcp
a9511416422 小时前
解决 Bookmarklet 中 %0A 换行符导致的跨环境执行失败问题
jvm·数据库·python
解救女汉子2 小时前
MySQL存储过程运行出错怎么排查_使用DECLARE HANDLER捕获错误
jvm·数据库·python
迷藏4942 小时前
**发散创新:基于Python的情感计算实战——从文本到情绪的智能识别**在人工智能与人机交互日益融合的今天,**情感计算(A
java·人工智能·python·人机交互
qq_12084093712 小时前
Three.js 骨骼动画工程实战:AnimationMixer、剪辑与混合权重调参
开发语言·javascript·ecmascript