当前位置: 首页 > article >正文

Playwright 浏览器自动化完全指南:从入门到实战

目录一、什么是 Playwright二、Playwright vs Selenium为什么选择 Playwright三、支持的语言与浏览器四、核心架构与执行流程五、环境安装与验证六、第一个程序打开网页并截图七、常用操作速查八、元素定位详解九、自动等待机制深度解析十、浏览器上下文与页面管理十一、常见场景实战十二、Codegen代码录制神器十三、调试与排查技巧十四、Playwright 能做什么十五、最佳实践与避坑指南十六、总结与学习路线一、什么是 Playwright1.1 定义Playwright 是一个开源的浏览器自动化框架由 Microsoft 开发并维护。它提供了一套统一的 API可以用代码控制 Chromium、Firefox 和 WebKit 三大浏览器引擎完成包括打开网页、点击、输入、数据抓取、截图、文件上传等在内的几乎所有浏览器操作。1.2 一句话理解Playwright 用代码驱动浏览器完成一切网页操作1.3 核心能力一览打开网页 ──→ 点击 / 输入 ──→ 数据抓取 ──→ 截图 / 录屏 ──→ 自动化测试 │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ goto() click() / text_content() screenshot() assert / fill() inner_text() video() expect()1.4 发展历程2020 年 1 月Microsoft 正式开源 Playwright首个版本支持 JavaScript/TypeScript2020 年中陆续发布 Python、Java、.NET 版本2021 年Playwright TestNode.js 测试运行器成熟社区快速壮大2022-2023 年在全球开发者调查中Playwright 使用率持续攀升逐步成为最受推荐的浏览器自动化工具之一2024-2025 年持续迭代更新生态日趋完善支持组件测试、UI 模式、全局设置等特性二、Playwright vs Selenium为什么选择 Playwright2.1 全方位对比维度SeleniumPlaywright诞生时间2004 年2020 年维护方Selenium 社区Microsoft浏览器驱动需要单独安装 WebDriver如 chromedriver内置浏览器二进制无需额外驱动自动等待需手动编写显式等待WebDriverWait原生内置所有操作自动等待定位器find_element 系列基于 WebDriver 协议Locator API支持链式、自动重试并行执行需要额外配置Grid、pytest-xdist 等原生支持并行浏览器上下文天然隔离调试工具依赖第三方工具内置 Trace Viewer、Codegen、UI 模式移动模拟Appium独立项目内置设备描述符可直接模拟网络拦截需要额外工具如 mitmproxy原生支持 route() 拦截请求/响应学习曲线资料丰富但 API 略显繁琐API 现代简洁上手更快社区生态极为成熟第三方库丰富快速成长中官方文档质量高2.2 结论Selenium传统经典方案生态成熟适合已有项目维护 Playwright现代首选方案自动等待强、定位器智能、调试高效适合新项目2.3 如何选择如果你是一个全新项目且团队没有历史包袱 →优先选择 Playwright如果你的项目已经大量使用 Selenium迁移成本高 → 可以继续使用 Selenium如果你需要高质量的 E2E 测试和CI/CD 集成→强烈推荐 Playwright如果你需要爬虫 / 数据采集→ Playwright 的网络拦截和自动等待更省心三、支持的语言与浏览器3.1 支持的编程语言Playwright ├── Python ← 本文重点 ├── JavaScript / TypeScript ├── Java └── .NET (C#)四套语言的 API 设计高度一致核心概念完全通用掌握一门后迁移到其他语言的成本很低。3.2 支持的浏览器Playwright 支持的浏览器引擎 ├── Chromium Chrome、Edge、Opera 等 ├── Firefox └── WebKit Safari 的内核注意Playwright 不使用系统已安装的浏览器而是自带经过适配的浏览器二进制文件确保了行为的一致性和可靠性。四、核心架构与执行流程4.1 整体架构用户代码Python / JS / Java / .NET │ ▼ Playwright API 层 │ ▼ Browser Server浏览器进程管理 │ ▼ ┌─────────┬──────────┬──────────┐ ▼ ▼ ▼ ▼ Chromium Firefox WebKit Edge(Chromium)4.2 核心对象关系Playwright 最顶层入口负责启动浏览器实例 │ ▼ Browser 一个浏览器实例如一个 Chromium 进程 │ ▼ BrowserContext 浏览器上下文相当于一个隐身会话隔离 Cookie、LocalStorage │ 一个 Browser 可以创建多个 Context天然实现并行隔离 ▼ Page 一个标签页 / 页面是实际操作的主要对象 │ ▼ Locator 元素定位器用于查找页面元素并执行操作4.3 核心执行流程五步法启动浏览器 ──→ 打开页面 ──→ 定位元素 ──→ 执行动作 ──→ 获取结果 │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ launch() goto() locator() click() / text_content() new_page() wait_for() get_by_*() fill() screenshot()理解这五步是掌握 Playwright 的关键所有自动化场景都是这五步的组合与扩展。五、环境安装与验证5.1 系统要求Python 3.8 及以上版本推荐 3.10Windows、macOS、Linux 均支持建议 4GB 以上内存浏览器较占资源5.2 安装步骤第一步安装 Playwright Python 包pip install playwright第二步安装浏览器二进制文件playwright install此命令会自动下载 Chromium、Firefox、WebKit 三大浏览器的适配版本存储在本地缓存目录中。如果只需要 Chromium可以指定playwright install chromium第三步可选安装系统依赖Linux 服务器环境playwright install-deps该命令会安装浏览器运行所需的系统级依赖库如 libglib2.0、libnss3 等在 Linux 服务器或 Docker 环境中通常需要执行。5.3 验证安装from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch() page browser.new_page() page.goto(https://example.com) print(页面标题, page.title()) browser.close()如果输出了页面标题说明安装成功。5.4 国内加速建议如果下载浏览器二进制时速度过慢可设置镜像源# 设置 Playwright 镜像Linux / macOS export PLAYWRIGHT_DOWNLOAD_HOSThttps://npmmirror.com/mirrors/playwright # Windows PowerShell $env:PLAYWRIGHT_DOWNLOAD_HOSThttps://npmmirror.com/mirrors/playwright # 然后重新安装 playwright install六、第一个程序打开网页并截图6.1 代码示例from playwright.sync_api import sync_playwright with sync_playwright() as p: # 启动 Chromium 浏览器headlessFalse 表示有界面方便观察 browser p.chromium.launch(headlessFalse) # 创建一个新的页面 page browser.new_page() # 导航到目标网址 page.goto(https://playwright.dev/) # 打印页面标题 print(f页面标题{page.title()}) # 截取整页截图并保存 page.screenshot(pathplaywright_homepage.png, full_pageTrue) print(截图已保存) # 关闭浏览器 browser.close()6.2 代码解析sync_playwright() 获取 Playwright 实例上下文管理器 └─ p.chromium.launch() 启动 Chromium 浏览器 └─ browser.new_page() 创建空白标签页 └─ page.goto(url) 导航到目标网址 └─ page.screenshot() 截图保存 └─ browser.close() 关闭浏览器释放资源6.3 headless 模式说明# 有界面模式调试时使用可以看到浏览器操作过程 browser p.chromium.launch(headlessFalse) # 无界面模式正式运行时使用速度快、资源省 browser p.chromium.launch(headlessTrue)6.4 异步版本Playwright 同时支持同步和异步两种 API。在高并发场景下推荐使用异步版本import asyncio from playwright.async_api import async_playwright async def main(): async with async_playwright() as p: browser await p.chromium.launch(headlessFalse) page await browser.new_page() await page.goto(https://playwright.dev/) print(f页面标题{await page.title()}) await page.screenshot(pathasync_screenshot.png) await browser.close() asyncio.run(main())本文后续示例以同步 API 为主异步版本只需在方法前加await即可逻辑完全一致。七、常用操作速查7.1 导航操作# 打开网页 page.goto(https://www.baidu.com) # 刷新页面 page.reload() # 后退 / 前进 page.go_back() page.go_forward() # 等待特定 URL 出现支持通配符 page.wait_for_url(**/dashboard)7.2 点击操作# 普通点击 page.locator(text登录).click() # 双击 page.locator(text标题).dblclick() # 右键点击 page.locator(.item).click(buttonright) # 按住 Shift 点击 page.locator(a).click(modifiers[Shift]) # 强制点击即使元素被遮挡也尝试点击 page.locator(#btn).click(forceTrue)7.3 输入操作# 清空并输入文本 page.locator(#username).fill(admin) # 逐字符输入模拟真实打字适合有输入事件监听的场景 page.locator(#search).press_sequentially(Playwright, delay100) # 按键操作 page.locator(input).press(Enter) page.locator(input).press(Controla) # 全选 # 输入文件 page.locator(input[typefile]).set_input_files(test.pdf)7.4 获取数据# 获取元素文本内容 text page.locator(h1).text_content() # 获取元素内部文本不含子元素标签 inner page.locator(.content).inner_text() # 获取属性值 href page.locator(a).get_attribute(href) # 获取输入框的值 value page.locator(input).input_value() # 获取页面标题 title page.title() # 获取当前 URL url page.url7.5 截图与录屏# 元素截图 page.locator(#chart).screenshot(pathchart.png) # 整页截图包含滚动区域 page.screenshot(pathfull.png, full_pageTrue) # 截取指定区域 page.screenshot(pathclip.png, clip{x: 0, y: 0, width: 800, height: 600})录屏功能需在创建 BrowserContext 时启用context browser.new_context( record_video_dirvideos/, record_video_size{width: 1280, height: 720} ) page context.new_page() page.goto(https://example.com) context.close() # 关闭上下文时视频自动保存7.6 等待操作# 等待元素出现 page.locator(#result).wait_for(timeout10000) # 超时 10 秒 # 等待元素消失 page.locator(.loading).wait_for(statehidden) # 等待特定网络请求完成 with page.expect_response(**/api/data) as response_info: page.click(#load-data) response response_info.value八、元素定位详解元素定位是 Playwright 最核心的能力定位选对了后续的点击、输入、断言都能水到渠成。8.1 定位方式全景元素定位方式 │ ├── 推荐方式语义化稳定抗页面变化 │ ├── get_by_role() 按 ARIA 角色 名称定位 │ ├── get_by_text() 按可见文本定位 │ ├── get_by_label() 按表单 label 定位 │ ├── get_by_placeholder() 按 placeholder 定位 │ ├── get_by_alt_text() 按图片 alt 属性定位 │ ├── get_by_test_id() 按># 按按钮角色 名称 page.get_by_role(button, name登录).click() # 按链接角色 page.get_by_role(link, name首页).click() # 按文本框角色 page.get_by_role(textbox, name用户名).fill(admin) # 按复选框 page.get_by_role(checkbox, name记住我).check() # 按标题heading page.get_by_role(heading, name欢迎).click()get_by_role基于 WAI-ARIA 无障碍标准定位语义明确、稳定性高是 Playwright 官方最推荐的方式。2get_by_text — 按文本定位# 精确匹配 page.get_by_text(登录, exactTrue).click() # 模糊匹配默认 page.get_by_text(登录).click() # 正则匹配 page.get_by_text(re.compile(r第\d页)).click()3get_by_label — 按表单标签定位# 根据 label forusername用户名/label 定位输入框 page.get_by_label(用户名).fill(admin) page.get_by_label(密码).fill(123456)4get_by_placeholder — 按占位文本定位page.get_by_placeholder(请输入用户名).fill(admin) page.get_by_placeholder(请输入密码).fill(secret)5get_by_test_id — 测试专用属性HTML 中添加data-testid属性button># ID 定位 page.locator(#username).fill(admin) # 类名定位 page.locator(.btn-primary).click() # 属性定位 page.locator([typesubmit]).click() # 组合定位 page.locator(div.container button.submit).click() # 伪类定位 page.locator(button:first-child).click() page.locator(li:nth-child(3)).click()8.4 XPath 定位# 文本匹配 page.locator(//button[text()提交]).click() # 包含某属性 page.locator(//input[placeholder用户名]).fill(admin) # 模糊匹配文本 page.locator(//div[contains(text(), 加载更多)]).click() # 轴定位父节点、兄弟节点等 page.locator(//label[text()用户名]/following-sibling::input).fill(admin)8.5 链式定位与过滤# 链式缩小范围 page.locator(div.card).locator(button).click() # 按文本过滤 page.locator(li).filter(has_textPython).click() # 按子元素过滤 page.locator(div.row).filter(haspage.locator(text详情)).click() # 按索引选取第2个匹配元素 page.locator(div.item).nth(1).click() # 第一个 / 最后一个 page.locator(li).first.click() page.locator(li).last.click() # 获取匹配数量 count page.locator(div.item).count()8.6 定位优先级建议最稳定 最灵活 │ │ ▼ ▼ get_by_test_id → get_by_role → get_by_label → get_by_text → CSS → XPath 写自动化测试优先 get_by_test_id / get_by_role 写爬虫/采集常用 CSS / XPath九、自动等待机制深度解析9.1 什么是自动等待Playwright 的每一个操作click、fill、text_content 等在执行前都会自动进行一系列检查确保元素处于可操作状态后才执行动作。这是 Playwright 相比 Selenium 的核心优势之一。9.2 自动等待的检查项当你执行page.locator(button).click()时Playwright 会在后台自动1. 等待元素出现在 DOM 中 │ ▼ 2. 等待元素可见非 display:none / visibility:hidden │ ▼ 3. 等待元素稳定不在动画中位置不持续变化 │ ▼ 4. 等待元素可接收事件不被其他元素遮挡 │ ▼ 5. 等待元素可交互不是 disabled 状态 │ ▼ 6. 执行 click()每一步检查都有默认超时时间默认 30 秒超时后抛出 TimeoutError。9.3 对比传统方式Selenium 的写法需要手动等待from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 需要手动编写显式等待 wait WebDriverWait(driver, 10) element wait.until(EC.element_to_be_clickable((By.ID, submit))) element.click()Playwright 的写法自动等待# 一行搞定自动等待元素可点击 page.locator(#submit).click()9.4 少用 sleep多用自动等待# ❌ 不推荐硬编码等待 import time time.sleep(5) page.locator(#result).click() # ✅ 推荐利用自动等待 page.locator(#result).click() # ✅ 确实需要等待特定条件时使用 Playwright 的等待 API page.wait_for_selector(#result, statevisible) page.wait_for_url(**/dashboard) page.wait_for_load_state(networkidle) page.wait_for_function(document.querySelector(#result) ! null)9.5 load_state 说明# 等待 DOM 加载完成默认行为通常够用 page.goto(https://example.com, wait_untildomcontentloaded) # 等待所有资源图片、CSS、JS加载完成 page.goto(https://example.com, wait_untilload) # 等待网络空闲没有超过 0.5 秒的网络请求适合 SPA 应用 page.goto(https://example.com, wait_untilnetworkidle)十、浏览器上下文与页面管理10.1 BrowserContext 的作用BrowserContext 是 Playwright 中一个非常重要的概念它相当于一个独立的浏览器会话Browser浏览器实例 │ ├── BrowserContext A ← Cookie、LocalStorage、权限设置完全独立 │ ├── Page 1标签页 │ └── Page 2标签页 │ └── BrowserContext B ← 与 Context A 完全隔离 └── Page 1标签页10.2 多上下文场景from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch() # 创建两个独立的上下文模拟两个独立用户 context_a browser.new_context() context_b browser.new_context() page_a context_a.new_page() page_b context_b.new_page() # 两个页面的登录状态互不影响 page_a.goto(https://example.com/login) page_b.goto(https://example.com/login) # ... 分别操作 context_a.close() context_b.close() browser.close()10.3 设备模拟# 使用内置的设备描述符模拟 iPhone 13 iphone p.devices[iPhone 13] context browser.new_context(**iphone) page context.new_page() page.goto(https://example.com)10.4 设置视窗大小与地理位置context browser.new_context( viewport{width: 1920, height: 1080}, localezh-CN, timezone_idAsia/Shanghai, geolocation{longitude: 116.397128, latitude: 39.916527}, permissions[geolocation], color_schemedark )十一、常见场景实战11.1 登录场景from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch(headlessFalse) page browser.new_page() page.goto(https://example.com/login) # 方式一直接选择器 page.fill(#username, admin) page.fill(#password, 123456) page.click(button[typesubmit]) # 方式二推荐定位方式 # page.get_by_label(用户名).fill(admin) # page.get_by_label(密码).fill(123456) # page.get_by_role(button, name登录).click() # 等待登录成功跳转 page.wait_for_url(**/dashboard) print(登录成功当前页面, page.url) browser.close()11.2 保存与复用登录状态from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch(headlessFalse) # 第一次手动登录并保存状态 context browser.new_context() page context.new_page() page.goto(https://example.com/login) page.get_by_label(用户名).fill(admin) page.get_by_label(密码).fill(123456) page.get_by_role(button, name登录).click() page.wait_for_url(**/dashboard) # 保存登录状态到文件 context.storage_state(pathauth_state.json) print(登录状态已保存) context.close() # 后续直接加载状态无需重复登录 context browser.new_context(storage_stateauth_state.json) page context.new_page() page.goto(https://example.com/dashboard) print(已使用保存的状态直接进入后台, page.title()) context.close() browser.close()11.3 文件上传# 单文件上传 page.locator(input[typefile]).set_input_files(test.pdf) # 多文件上传 page.locator(input[typefile]).set_input_files([a.png, b.png, c.png]) # 取消已选文件 page.locator(input[typefile]).set_input_files([])11.4 弹窗Dialog处理# 方式一自动接受所有弹窗 page.on(dialog, lambda dialog: dialog.accept()) # 方式二根据弹窗类型分别处理 def handle_dialog(dialog): if dialog.type confirm: print(f确认弹窗{dialog.message}) dialog.accept() # 点击确认 # dialog.dismiss() # 点击取消 elif dialog.type alert: print(f提示弹窗{dialog.message}) dialog.accept() page.on(dialog, handle_dialog) page.click(#delete-btn) # 触发弹窗11.5 多标签页处理with sync_playwright() as p: browser p.chromium.launch(headlessFalse) page browser.new_page() page.goto(https://example.com) # 点击会打开新标签页的链接时捕获新页面 with page.expect_popup() as popup_info: page.get_by_text(详情).click() new_page popup_info.value print(新标签页标题, new_page.title()) # 在新标签页上操作 new_page.locator(#content).click() new_page.close() browser.close()11.6 网络请求拦截def handle_route(route): 拦截 API 请求可以修改请求或返回模拟数据 if /api/user in route.request.url: # 返回模拟数据 route.fulfill( status200, content_typeapplication/json, body{name: 测试用户, role: admin} ) else: # 放行其他请求 route.continue_() page.route(**/api/**, handle_route) page.goto(https://example.com)11.7 执行 JavaScript# 在页面中执行 JavaScript title page.evaluate(document.title) print(title) # 传递参数给 JS result page.evaluate(([a, b]) a b, [3, 5]) print(result) # 8 # 获取复杂的页面数据 data page.evaluate( () { const items document.querySelectorAll(.product); return Array.from(items).map(item ({ name: item.querySelector(.title).textContent, price: item.querySelector(.price).textContent })); } )11.8 滚动操作# 滚动到元素位置 page.locator(#footer).scroll_into_view_if_needed() # 使用鼠标滚轮 page.mouse.wheel(0, 500) # 向下滚动 500 像素 # 通过 JS 滚动到页面底部 page.evaluate(window.scrollTo(0, document.body.scrollHeight))11.9 iframe 操作# 通过选择器定位 iframe frame page.frame_locator(iframe#editor) # 在 iframe 中操作元素 frame.locator(button.save).click() frame.locator(input.title).fill(文档标题)十二、Codegen代码录制神器12.1 什么是 CodegenCodegen 是 Playwright 内置的代码录制工具。它会打开一个浏览器窗口并录制你的所有操作点击、输入、导航等实时生成对应的 Playwright 代码。12.2 启动方式# 基本启动 playwright codegen https://example.com # 指定输出语言Python playwright codegen --target python https://example.com # 指定输出文件 playwright codegen --output my_script.py https://example.com # 模拟移动设备 playwright codegen --device iPhone 13 https://example.com # 保存登录状态 playwright codegen --save-storageauth.json https://example.com12.3 Codegen 的价值快速上手复杂页面 ──→ 不用手动研究 DOM 结构 自动生成定位代码 ──→ 自动推荐最优定位方式 实时预览操作效果 ──→ 边操作边看代码生成 降低学习门槛 ──→ 新手也能快速写出自动化脚本12.4 使用建议对于不熟悉的页面先用 Codegen 录制一遍了解操作流程和元素结构录制的代码通常需要手动优化去除冗余步骤、改用更稳定的定位器Codegen 是学习工具不建议直接用于生产环境十三、调试与排查技巧13.1 Trace ViewerTrace Viewer 是 Playwright 内置的可视化调试工具可以回放测试执行的完整过程。context browser.new_context() context.tracing.start(screenshotsTrue, snapshotsTrue, sourcesTrue) page context.new_page() page.goto(https://example.com) # ... 操作代码 ... context.tracing.stop(pathtrace.zip)查看 traceplaywright show-trace trace.zipTrace Viewer 会展示每一步操作的截图、DOM 快照、网络请求和控制台日志是排查问题的利器。13.2 headed 模式 slow_mo# slow_mo 会降低每个操作的速度单位毫秒方便观察执行过程 browser p.chromium.launch( headlessFalse, slow_mo500 # 每步间隔 500 毫秒 )13.3 截图排查# 在关键步骤后截图帮助定位问题 page.goto(https://example.com/login) page.screenshot(pathstep1_login_page.png) page.get_by_label(用户名).fill(admin) page.screenshot(pathstep2_filled.png) page.get_by_role(button, name登录).click() page.screenshot(pathstep3_after_login.png)13.4 控制台日志# 监听控制台输出 page.on(console, lambda msg: print(fConsole [{msg.type}]: {msg.text})) # 监听页面错误 page.on(pageerror, lambda err: print(fPage Error: {err})) # 监听请求失败 page.on(requestfailed, lambda req: print(fRequest Failed: {req.url} - {req.failure}))十四、Playwright 能做什么14.1 应用场景全景Playwright 应用场景 │ ├── 自动化测试 │ ├── E2E端到端测试 │ ├── 回归测试 │ ├── 跨浏览器兼容性测试 │ └── 视觉回归测试配合截图对比 │ ├── 网页自动化 │ ├── 表单自动填写 │ ├── 内容自动发布 │ ├── 定时任务执行 │ └── 流程审批自动化 │ ├── 数据采集 │ ├── 商品信息采集 │ ├── 社交媒体内容采集 │ ├── 公开数据集构建 │ └── 价格监控 │ ├── 办公自动化 │ ├── 报表自动生成 │ ├── 后台系统批量操作 │ └── 数据导出与归档 │ └── AI 浏览器 ├── AI Agent 的浏览器交互层 ├── 智能表单填写 └── 自动化信息检索14.2 与 pytest 集成测试场景Playwright 官方提供了 pytest 插件可直接使用 pytest 框架组织测试pip install pytest-playwright# test_login.py import pytest from playwright.sync_api import Page, expect def test_login_success(page: Page): page.goto(https://example.com/login) page.get_by_label(用户名).fill(admin) page.get_by_label(密码).fill(123456) page.get_by_role(button, name登录).click() # 使用 Playwright 的断言自带等待和重试 expect(page).to_have_url(**/dashboard) expect(page.get_by_text(欢迎回来)).to_be_visible() def test_search(page: Page): page.goto(https://example.com) page.get_by_placeholder(搜索).fill(Playwright) page.get_by_placeholder(搜索).press(Enter) expect(page.locator(.search-result)).to_have_count(greater_than0)运行pytest test_login.py --browser chromium14.3 连接远程浏览器# 连接到已运行的浏览器实例通过 CDP browser p.chromium.connect_over_cdp(http://localhost:9222) # 连接到 Playwright Server browser p.chromium.connect(ws://remote-server:3000/)十五、最佳实践与避坑指南15.1 定位策略✅ 推荐 └─ 优先使用 get_by_role / get_by_test_id / get_by_label 这些方式语义清晰、抗页面变化能力强 ❌ 避免 └─ 避免使用脆弱的定位方式如绝对 XPath、索引定位 页面结构一旦变化就会导致脚本失败15.2 等待策略✅ 推荐 └─ 依赖 Playwright 的自动等待机制 只在必要时使用 wait_for_selector / wait_for_url / wait_for_load_state ❌ 避免 └─ 避免使用 time.sleep() 硬编码等待 既不稳定又浪费时间15.3 资源管理✅ 推荐 └─ 使用 with 语句上下文管理器管理 Playwright 和 Browser 的生命周期 操作完成后及时 close() ❌ 避免 └─ 避免忘记关闭浏览器实例 长时间运行可能导致内存泄漏15.4 测试组织✅ 推荐 └─ 每个测试用例使用独立的 BrowserContext 确保测试之间互不影响 利用 pytest fixtures 管理 setup / teardown ❌ 避免 └─ 避免测试用例之间共享登录状态或页面数据15.5 常见错误排查错误原因解决方案TimeoutError: locator.click元素未找到或不可交互检查定位器是否正确元素是否在 iframe 中Target page, context or browser has been closed操作的对象已被关闭检查代码逻辑避免提前关闭net::ERR_CONNECTION_REFUSED网络不通或地址错误确认目标 URL 是否可达Element is not visible元素存在但不可见可能需要先滚动到元素位置或展开折叠区域十六、总结与学习路线16.1 核心要点回顾Playwright 的本质 └─ 用代码控制浏览器完成一切网页操作 核心优势 ├── 自动等待 ──→ 稳定可靠告别 sleep ├── 智能定位 ──→ get_by_role 等语义化 API好用且抗变化 ├── 跨浏览器 ──→ Chromium / Firefox / WebKit 一套代码全覆盖 ├── Codegen ──→ 录制生成代码高效上手复杂页面 ├── Trace ──→ 可视化调试问题排查效率极高 └── Context ──→ 浏览器上下文隔离天然支持并行与多用户场景16.2 学习路线建议第一阶段入门 │ 安装环境 → 第一个程序 → 理解核心五步流程 │ 第二阶段基础 │ 掌握常用操作 → 熟练元素定位 → 理解自动等待 │ 第三阶段进阶 │ 网络拦截 → 多上下文管理 → iframe / 多标签页 → 保存状态 │ 第四阶段实战 │ 独立完成一个自动化项目如数据采集 / 自动化测试 │ 第五阶段高阶 pytest 集成 → CI/CD 集成 → 性能优化 → AI Agent 集成16.3 官方资源官方文档https://playwright.dev/python/GitHub 仓库https://github.com/microsoft/playwrightAPI 参考https://playwright.dev/python/docs/api/class-pagePlaywright 是现代浏览器自动化的首选工具。掌握它你就拥有了解决一切网页操作问题的能力。从今天开始用代码驱动浏览器让重复劳动交给自动化。

相关文章:

Playwright 浏览器自动化完全指南:从入门到实战

目录 一、什么是 Playwright二、Playwright vs Selenium:为什么选择 Playwright三、支持的语言与浏览器四、核心架构与执行流程五、环境安装与验证六、第一个程序:打开网页并截图七、常用操作速查八、元素定位详解九、自动等待机制深度解析十、浏览器上…...

深度 | 昇腾NPU MoE算子实现:从TopKGating到Expert并行,稀疏激活的硬件适配

引言 MoE(Mixture of Experts,混合专家)是大模型近年来最重要的架构演进之一。GPT-4、Mixtral-87B、Qwen1.5-MoE——几乎所有宣称"超大规模"的新模型都在用 MoE。核心逻辑很简单:用多个独立的"专家"网络替代…...

从零到亿级调用量:电商客服Agent重构实录(含对话状态机+意图跳转图+人工接管SLA协议)

更多请点击: https://codechina.net 第一章:从零到亿级调用量:电商客服Agent重构实录(含对话状态机意图跳转图人工接管SLA协议) 面对日均峰值超1.2亿次的客服请求,原有基于规则匹配的客服Bot在大促期间频繁…...

从电路振荡到种群竞争:常系数线性微分方程组在建模中的实战指南

从电路振荡到种群竞争:常系数线性微分方程组在建模中的实战指南微分方程是描述动态系统的数学语言,而常系数线性微分方程组则是其中最具工程实用价值的一类。不同于纯数学视角下的求解技巧,本文将带你穿越两个经典场景——电子工程中的RLC振荡…...

用Python处理DREAMER脑电数据集:从.mat文件到.npy文件的完整实战教程

用Python处理DREAMER脑电数据集:从.mat文件到.npy文件的完整实战教程在情感计算与神经科学交叉领域,DREAMER数据集因其同时包含脑电信号(EEG)和情感评分而备受研究者青睐。但原始数据以.mat格式存储,这种MATLAB专属格式…...

《Java 基础必学:ArrayList、HashMap 和泛型详解》

一、引言 1.为什么这些是 Java 基础的重点? ArrayList、HashMap 和泛型是Java集合框架的核心组成部分,广泛应用于实际开发中。 ArrayList:基于动态数组实现,支持快速随机访问,适合频繁查询和遍历的场景。HashMap&…...

数据标注中的权力博弈与主观性:从规则制定到模型偏见的全链路解析

1. 项目概述:当数据标注不再是“客观”的技术活“数据标注”,在很多人眼里,可能就是一个坐在电脑前,对着图片画框、打标签的“体力活”或“技术活”。它听起来中立、客观,是人工智能模型训练前一道标准化的工序。然而&…...

市面上靠谱的ERP/MES/定制开发/APP开发/软件开发公司

在数字化浪潮下,80%的实体企业都想通过ERP、MES或定制软件实现降本增效,但选对服务商比“买系统”更重要——用模板化系统的企业,70%会因为流程适配差、运维跟不上而半途而废;找外包开发的企业,又面临“开发完就甩手”…...

从需求到交付:深度拆解企业级软件定制开发的标准化流程

一、 引言:数字化转型的“标准化”与“定制化”博弈(内容概要:简述当前企业在选购通用SaaS软件与定制软件时的痛点。指出通用软件往往“大而全但难用”,而定制开发的核心在于精准契合业务场景。)二、 定制开发的四大核…...

RuoYi接口调试:Postman作为Spring Boot权限系统可信信使

1. 为什么RuoYi项目里Postman不是“配角”,而是调试生命线在RuoYi开发实战中,很多人把Postman当成一个“临时工具”——写完接口顺手点一下,成功了就扔一边,失败了就切回IDE疯狂加日志、重启服务、反复试错。我带过三届实习生&…...

同事还在手动整理文件,我已经让 Open Claw 全自动搞定了|Windows 一键部署

⚡OpenClaw 一键安装包|一键部署,告别复杂环境配置⚡ 适配系统 Windows10/11 64 位 当前版本 2.7.5 版本(虾壳云版) 核心优势 全程可视化操作,无需命令行、无需手动配置 Python/Node.js,内置所有运行…...

虚幻引擎Pak文件可视化分析工具原理与实践

1. 为什么一个Pak文件查看器值得花两周重写三遍?虚幻引擎项目打包后生成的.pak文件,对绝大多数开发者来说就是个“黑盒”——你清楚它装着所有资源:贴图、音频、蓝图、关卡数据,甚至UAsset序列化后的二进制结构;但你完…...

1000个文件重命名,1秒完成!批量文件重命名软件

前言: 大家好,这里是惠众资料库, 在日常办公、资料归档、素材整理、摄影剪辑等各类场景中,用户会积累大量图片、文档、视频、音频、文件夹等各类文件。为了实现文件分类规整、统一命名规范、方便快速检索调用,文件重命…...

计算机视觉与贝叶斯优化驱动的粉末饮料智能制备系统

1. 项目概述:从“冲一杯”到“冲好一杯”的自动化跃迁“机器人结合计算机视觉与贝叶斯优化实现粉末饮料制备自动化”,这个标题听起来有点学术,但说白了,我们做的就是把冲奶粉、泡蛋白粉、调咖啡这类“凭感觉”的手工活&#xff0c…...

【Lovable高阶开发者私藏技巧】:绕过平台限制实现自定义CSS/JS注入与第三方SDK深度对接

更多请点击: https://kaifayun.com 第一章:Lovable无代码开发教程 Lovable 是一款面向业务人员与轻量级开发者的可视化应用构建平台,它通过拖拽式界面、逻辑编排画布和内置数据连接器,将复杂功能封装为可复用的模块。无需编写传统…...

鸿蒙electron跨端框架PC导出管家实战:把交付前的检查、复制和导出做成一个工坊

前言 欢迎加入鸿蒙PC开发者社区,共同打造开发者工具生态:鸿蒙PC开发者社区 :https://harmonypc.csdn.net/ 项目开源地址:https://AtomGit.com/lqjmac/ele-daochuguanjia 我做 导出管家 时最先确认的,不是颜色和布局…...

Hexo 排坑记:删除所有文章后首页无法访问(Cannot GET)

背景 最近在使用 Hexo Butterfly 主题搭建个人博客时,遇到一个奇怪的问题:我把 source/_posts 下的所有文章都删掉后,重新生成并启动本地服务器,访问 http://localhost:4000 竟然直接显示 Cannot GET /,首页完全打不开…...

前端实习面试手写题分享

在寻找前端实习的过程中,我们会发现,面试除了考察算法题之外,手写题同样也是高频考点。尤其是在准备中大厂前端面试时,手写能力几乎是必不可少的一部分。这篇文章将围绕几道经典高频手写题展开,包括手写深拷贝、实现寄…...

2026年5月4日 OCS技术方案路线选择与优劣深度调研报告

OCS技术方案路线选择与优劣深度调研报告 核心结论 光电路交换(OCS)正从Google的"独家方案"演变为AI算力网络的通用基础设施。Google TPU v8i采用的Boardfly架构首次将OCS引入大规模MoE推理场景,标志着OCS应用从训练侧向推理侧的跨…...

别再死记ResNet结构了!用Python手搓一个ResUnet,从代码里真正搞懂残差连接

从零实现ResUnet:用Python代码彻底理解残差连接的本质在计算机视觉领域,图像分割一直是极具挑战性的任务之一。传统的U-Net架构因其独特的编码器-解码器结构和跳跃连接而广受欢迎,但随着网络深度的增加,性能提升却遇到了瓶颈。这时…...

从纸质报表到Excel:PaddleOCR+Python自动化识别复杂表格(附完整代码)

金融表格自动化革命:用PaddleOCRPython实现纸质报表秒转Excel每次月末结算时,财务部的张经理总要面对堆积如山的纸质报表——供应商对账单、银行流水单、税务申报表,这些表格往往带有手写注释、合并单元格和模糊印章。传统的人工录入不仅耗时…...

保姆级教程:用Arbe或大陆4D毫米波雷达点云数据,手把手实现Freespace检测(附Python伪代码)

毫米波雷达点云实战:从数据到可行驶区域的完整工程指南在自动驾驶感知系统中,可行驶区域检测(Freespace)直接决定了车辆路径规划的可行空间边界。相比激光雷达和摄像头方案,4D毫米波雷达凭借全天候工作能力、成本优势和…...

别再为医学影像格式发愁了!3D Slicer 5.x 保姆级数据导入与格式转换指南

医学影像处理实战:3D Slicer 5.x全格式兼容指南与高效工作流医学影像研究的第一步往往就卡在数据导入环节——当你从医院PACS系统拿到DICOM序列,从合作方收到NRRD压缩包,或是下载公开数据集的NIFTI文件时,3D Slicer中那些灰色的&q…...

AI赋能科学教育:个性化学习与交互式模拟的技术实践

1. 项目概述:当AI遇见科学课堂作为一名在教育科技领域摸爬滚打了十多年的从业者,我亲眼见证了从幻灯片到在线视频,再到如今AI技术涌入课堂的整个历程。最近,我和团队深度参与了一个名为“AI赋能科学教育”的项目,这不仅…...

储能 PACK 与 BMS:怎么识别有真实出货的系统集成厂,避开组装贴牌

储能赛道的门槛看起来不高:买一批电芯,叫几家代工厂组装成 PACK,挂上自己的品牌,就能对外声称是"储能系统集成商"。这条路在 2021 年到 2024 年的行业高速期被走通过无数次。于是,有真实产线、真实并网项目、…...

神经纹理:让3D世界“活”起来的AI魔法,一篇讲透!

神经纹理:让3D世界“活”起来的AI魔法,一篇讲透! 引言:从“贴图”到“思考”的纹理革命 想象一下,一个虚拟角色不仅能动,其皮肤还能随着情绪微微泛红、在阳光下呈现真实的汗渍光泽——这不再是电影特效的…...

找工厂客户,天下工厂和企查查、天眼查这类平台哪个数据更靠谱?

做B2B销售或供应链采购的人,多半都碰过这样的困境:打开某个平台搜一个行业,出来几百条结果,逐条看下去才发现——这家是贸易公司,那家是空壳主体,还有一堆个体工商户,真正能对接生产的工厂没几个…...

C语言数组:从基础到实践

一、什么是数组数组就是相同类型数据的集合,这些数据在内存中连续存放,数组里的每个位置叫元素,用下标来访问。特别注意:数组的下标从0开始。以下代码就是一个简单的数组应用:二、数组的基本操作2.1 定义与初始化输出结…...

孩子学英语怎么选择

需要一点点建议哦...

rk3566 配置HDMI的屏的流程

一、确认硬件与固件硬件:RK3566 板载 Micro HDMI → 接 HDMI 显示器(用转接头 / 线)。固件:优先用官方带 HDMI 配置的镜像(如 hdmi 专用 img),避免默认关闭 HDMI 的版本。二、设备树&#xff08…...