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

#24 Agent 的浏览器自动化:Playwright、Selenium 与网页交互

从一次凌晨三点的事故说起去年冬天我负责的一个自动化脚本在凌晨三点突然崩了。日志里只有一行ElementClickInterceptedException。点一个“确认”按钮被一个弹窗遮住了。Selenium 的WebDriverWait等了十秒弹窗刚好在点击前0.5秒消失——经典的竞态条件。更糟的是这个脚本跑在无头模式下我连截图都没开。那天晚上我意识到浏览器自动化不是“写个脚本让它跑”那么简单。当你的 Agent 需要像人一样操作网页——填表单、抓数据、做断言——你面对的不是一个静态 DOM而是一个活生生的、会异步渲染、会弹广告、会突然卡住的浏览器。这篇文章不讲理论只讲我在生产环境里踩过的坑以及 Playwright 和 Selenium 到底该怎么选、怎么用。选型别只看 Star 数先说结论2026 年新项目无脑选 Playwright。不是 Selenium 不好是 Playwright 解决了太多 Selenium 时代需要自己手搓的痛点。Selenium 的架构决定了它是个“遥控器”——你通过 WebDriver 协议告诉浏览器做什么浏览器做完再告诉你。这个模型本身没问题但跨进程通信的延迟、不同浏览器驱动的兼容性、以及那些诡异的StaleElementReferenceException会让你在调试时想砸键盘。Playwright 走的是 CDPChrome DevTools Protocol通道相当于直接跟浏览器内核对话。这意味着等待网络空闲、等待元素可见、等待请求完成——这些在 Selenium 里需要自己写轮询的逻辑Playwright 内置了。自动等待。这是 Playwright 最值钱的设计。你写page.click(#submit)它不会立刻点而是等元素稳定、可见、不被遮挡、没有动画——然后才点。Selenium 的ElementClickInterceptedException在 Playwright 里几乎绝迹。多浏览器支持。Chromium、Firefox、WebKit 一套 API不用像 Selenium 那样为每个浏览器装不同的 driver。但 Selenium 也有它的生态优势老项目、遗留系统、某些只支持 Selenium 的云测试平台。如果你维护的是一个跑了五年的自动化框架迁移成本可能高于收益。Playwright 实战让 Agent 像人一样操作网页安装与启动# 别用 pip install playwright 就完事还要装浏览器pip install playwright playwright install chromium# 这里踩过坑只装库不装浏览器运行时报错启动浏览器时我习惯这样写fromplaywright.sync_apiimportsync_playwrightwithsync_playwright()asp:browserp.chromium.launch(headlessFalse,slow_mo500)# slow_mo 是神器调试时加500ms延迟看得清每一步pagebrowser.new_page()page.goto(https://example.com)slow_mo这个参数调试阶段一定要开。它让每一步操作之间插入固定延迟不是用来解决竞态的是用来让你肉眼能跟上脚本节奏的。生产环境关掉。等待别再用 time.sleep()新手最爱写time.sleep(3)这是最粗暴也最不可靠的方式。网络慢一秒脚本就崩网络快一秒白白浪费两秒。Playwright 的等待策略# 等待元素可见page.wait_for_selector(#result,statevisible,timeout10000)# 等待网络空闲适合页面加载完后有异步请求的场景page.wait_for_load_state(networkidle)# 等待自定义条件page.wait_for_function(() document.title 完成)这里有个坑networkidle不是万能的。有些页面会持续发送心跳请求导致networkidle永远等不到。这时候用domcontentloaded加一个合理的超时。元素定位XPath 还是 CSS我个人的经验能用 CSS 选择器就别用 XPath。CSS 选择器更简洁、性能更好、可读性更强。但有些场景 XPath 无可替代——比如根据文本内容定位# CSS 做不到根据文本找按钮page.click(text提交订单)# Playwright 内置的文本选择器比 XPath 好写# 或者用 XPath 定位包含特定文本的元素page.locator(//button[contains(text(), 确认)]).click()Playwright 的text选择器是个好东西它自动处理了文本匹配的模糊性。但注意如果页面上有两个“提交订单”它会报错说找到了多个元素。这时候用first、last或nth来限定page.locator(text提交订单).first.click()表单填写模拟真实输入很多自动化脚本填表单时直接fill()但有些前端框架比如 React会监听input事件fill()可能触发不了。这时候用type()模拟逐字输入# 别这样写page.fill(#username, admin)# 这样写更安全page.type(#username,admin,delay50)# delay 模拟打字间隔50ms 一个字符delay参数在对付那些有防机器人检测的页面时特别有用。有些网站会检测输入速度如果瞬间填完就判定为脚本。处理弹窗和对话框# 监听对话框自动确认page.on(dialog,lambdadialog:dialog.accept())# 或者处理特定对话框page.on(dialog,lambdadialog:print(f对话框内容:{dialog.message}))这里踩过坑page.on注册的监听器是全局的如果页面弹出多个对话框监听器会依次触发。但如果你在某个操作之后才注册监听器之前的对话框就没人处理脚本会卡住。所以最好在goto之前就注册好。截图和录屏调试的救命稻草# 截图page.screenshot(pathdebug.png,full_pageTrue)# 录屏Chromium onlycontextbrowser.new_context(record_video_dirvideos/)pagecontext.new_page()# ... 操作 ...context.close()# 关闭 context 才会保存视频生产环境里我习惯在每个关键步骤后截图并保存到带时间戳的文件里。出问题时翻截图比翻日志快十倍。Selenium 的遗留战场虽然我推荐 Playwright但 Selenium 在某些场景下依然有它的位置。什么时候不得不用 Selenium老项目维护你接手的自动化框架是用 Selenium 写的重写成本太高。特定浏览器支持某些企业内网只能用 IE 或旧版 EdgePlaywright 不支持。云测试平台BrowserStack、Sauce Labs 对 Selenium 的支持更成熟。Selenium 的坑与填坑fromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasEC driverwebdriver.Chrome()waitWebDriverWait(driver,10)# 经典写法等元素可点击elementwait.until(EC.element_to_be_clickable((By.ID,submit)))element.click()这个写法看起来没问题但实际运行中element_to_be_clickable只检查元素是否可见和启用不检查是否被其他元素遮挡。所以ElementClickInterceptedException依然会出现。我的解决方案自己写一个等待条件用 JavaScript 检查元素是否被遮挡defis_element_clickable(driver,locator):elementdriver.find_element(*locator)# 别这样写直接用 element.click() 会抛异常# 用 JS 检查returndriver.execute_script( var rect arguments[0].getBoundingClientRect(); var x rect.left rect.width/2; var y rect.top rect.height/2; var topElement document.elementFromPoint(x, y); return arguments[0].contains(topElement) || arguments[0] topElement; ,element)wait.until(lambdad:is_element_clickable(d,(By.ID,submit)))这个脚本检查点击坐标处最上层的元素是不是目标元素本身或其子元素。如果是说明没被遮挡。Selenium 的隐式等待 vs 显式等待# 隐式等待全局设置所有 find_element 都等driver.implicitly_wait(10)# 显式等待只针对特定元素wait.until(EC.presence_of_element_located((By.ID,result)))别混用。隐式等待和显式等待混用会导致不可预测的等待时间。我见过一个项目隐式等待设了 10 秒显式等待又设了 10 秒结果某些元素等了 20 秒才超时。要么全用显式要么全用隐式——我选显式因为更可控。Agent 与浏览器的交互模式当你的 Agent 需要操作浏览器时不是简单地“打开网页-点击-获取数据”。Agent 需要理解网页内容、做出决策、执行操作、验证结果。这涉及到几个关键点上下文管理Agent 每次操作都应该知道当前页面状态。我习惯用一个BrowserContext类来封装classBrowserContext:def__init__(self):self.pageNoneself.history[]# 操作历史self.screenshots[]# 截图记录defnavigate(self,url):self.page.goto(url)self.history.append(f导航到:{url})self.screenshots.append(self.page.screenshot())defclick(self,selector):self.page.click(selector)self.history.append(f点击:{selector})self.screenshots.append(self.page.screenshot())这样 Agent 可以回溯操作历史甚至在出错时回滚到某个状态。错误恢复网页自动化最烦人的就是“预期之外的状态”。弹窗、网络超时、元素加载失败——Agent 需要能处理这些异常。defsafe_click(page,selector,retries3):foriinrange(retries):try:page.click(selector,timeout5000)returnTrueexceptExceptionase:print(f第{i1}次点击失败:{e})ifiretries-1:page.wait_for_timeout(1000)# 等一秒再重试returnFalse这个简单的重试机制能解决 80% 的偶发问题。剩下的 20% 需要更复杂的策略——比如刷新页面、切换标签页、或者直接放弃当前操作。数据提取与验证Agent 操作网页的最终目的是获取数据或完成某个任务。提取数据时别只依赖一种方式# 先尝试结构化提取datapage.evaluate( () { const rows document.querySelectorAll(table tr); return Array.from(rows).map(row { const cells row.querySelectorAll(td); return Array.from(cells).map(cell cell.textContent.trim()); }); } )# 如果结构化提取失败用文本匹配ifnotdata:textpage.text_content(body)# 用正则或 LLM 提取这里有个经验能用 JS 提取就别用 Python 解析。在浏览器端执行 JS 提取数据比把整个 HTML 传给 Python 再解析快一个数量级。性能优化别让浏览器成为瓶颈无头模式生产环境一定要用无头模式。Playwright 默认就是无头但 Selenium 需要显式设置# Playwrightbrowserp.chromium.launch(headlessTrue)# Seleniumoptionswebdriver.ChromeOptions()options.add_argument(--headless)driverwebdriver.Chrome(optionsoptions)复用浏览器实例每次启动浏览器都很慢。如果 Agent 需要频繁操作复用浏览器实例# Playwright 的 browser context 可以隔离会话contextbrowser.new_context()page1context.new_page()page2context.new_page()# 同一个 context 共享 cookies 和存储# 不同 context 完全隔离context2browser.new_context()资源释放# 别忘记关闭page.close()browser.close()忘记关闭浏览器会导致内存泄漏。在长时间运行的 Agent 里我习惯用try...finally确保资源释放或者用上下文管理器。个人经验别把自动化当黑盒写浏览器自动化脚本最忌讳的就是“写完了就不管了”。网页是会变的——前端重构、第三方库升级、甚至只是某个 CDN 挂了你的脚本就可能崩。我的建议每个关键操作后截图。截图不占多少空间但出问题时能帮你快速定位是哪个步骤出了问题。记录操作日志。不只是“点击了按钮”还要记录点击前后的页面状态、元素属性、网络请求。定期运行测试。哪怕只是每周跑一次也能提前发现页面变化。不要过度依赖等待时间。time.sleep(5)这种写法迟早会坑你。用 Playwright 的自动等待或者自己写基于条件的等待。考虑用 LLM 辅助定位元素。当页面结构频繁变化时用 LLM 根据视觉或语义描述来定位元素比硬编码选择器更鲁棒。但这又是另一个话题了。最后说一句浏览器自动化不是银弹。如果你的目标网站有强反爬机制比如验证码、行为检测、IP 频率限制自动化脚本可能跑不过十分钟。这时候要考虑的是“能不能换个方式获取数据”——比如找 API、买数据、或者跟网站所有者合作。技术解决不了所有问题但能解决大部分。剩下的靠经验和运气。

相关文章:

#24 Agent 的浏览器自动化:Playwright、Selenium 与网页交互

从一次凌晨三点的事故说起 去年冬天,我负责的一个自动化脚本在凌晨三点突然崩了。日志里只有一行:ElementClickInterceptedException。点一个“确认”按钮,被一个弹窗遮住了。Selenium 的 WebDriverWait 等了十秒,弹窗刚好在点击前…...

免费文本挖掘神器KH Coder:三步掌握多语言内容分析技巧

免费文本挖掘神器KH Coder:三步掌握多语言内容分析技巧 【免费下载链接】khcoder KH Coder: for Quantitative Content Analysis or Text Mining 项目地址: https://gitcode.com/gh_mirrors/kh/khcoder 面对海量文本数据不知从何入手?想从用户评论…...

CANN具身智能优化样例

CANN Recipes for Embodied Intelligence 【免费下载链接】cann-recipes-embodied-intelligence 本项目针对具身智能业务中的典型模型、加速算法,提供基于CANN平台的优化样例 项目地址: https://gitcode.com/cann/cann-recipes-embodied-intelligence &#…...

如何10分钟快速搭建Sunshine游戏串流服务器:完整实战指南

如何10分钟快速搭建Sunshine游戏串流服务器:完整实战指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine是一款开源的自托管游戏串流服务器,专为M…...

抖音批量下载工具:5分钟搞定无水印内容保存

抖音批量下载工具:5分钟搞定无水印内容保存 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖音批…...

解锁全平台直播录制:DouyinLiveRecorder让你永不错过精彩瞬间

解锁全平台直播录制:DouyinLiveRecorder让你永不错过精彩瞬间 【免费下载链接】DouyinLiveRecorder 可循环值守和多人录制的直播录制软件,支持抖音、TikTok、Youtube、快手、虎牙、斗鱼、B站、小红书、pandatv、sooplive、flextv、popkontv、twitcasting…...

企业级即时通讯「删除消息」:六个场景叠加之后,复杂性超出你的想象

本文不是一上来就讲方案,而是带你还原真实的业务场景,看清楚复杂性是如何一层一层叠加上来的。每加一个场景,原来的解法就出现新的漏洞,直到六个场景同时存在,你才会明白为什么"删除一条消息"在企业级系统里…...

bili2text:如何用3个步骤将B站视频转换为可搜索的文本知识库?

bili2text:如何用3个步骤将B站视频转换为可搜索的文本知识库? 【免费下载链接】bili2text Bilibili视频转文字,一步到位,输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 在信息过载的数字时代&a…...

TranslucentTB - Windows任务栏透明化技术配置手册

TranslucentTB - Windows任务栏透明化技术配置手册 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB TranslucentTB是一款专为Windows 10/1…...

Taotoken模型广场如何帮助开发者快速对比与选择合适模型

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Taotoken模型广场如何帮助开发者快速对比与选择合适模型 当开发者需要为大语言模型应用选择基础模型时,常常面临一个现…...

解决Wireshark安装 无法显示USB接口

密评实施过程中,会使用到Wireshark抓取智能密码钥匙的通信流量,但是某些情况下安装Wireshark之后,无法找到USB的捕获接口,重启Wireshark和电脑后还是无法正常显示。如下图。解决办法如下:将“USBPcapCMD.exe”复制到“…...

3D高斯泼溅优化:多项式核函数与高效剔除算法

1. 3D高斯泼溅技术背景与挑战在实时神经渲染领域,3D高斯泼溅(3D Gaussian Splatting, 3DGS)已成为近年来最具突破性的技术之一。这项技术通过将场景表示为大量各向异性高斯基元的集合,实现了高质量的实时渲染效果。每个高斯基元包含位置(μ)、协方差矩阵…...

基于GSAP与线性插值实现丝滑自定义光标动画

1. 项目概述:一个丝滑的现代自定义光标如果你厌倦了浏览器那个千篇一律的箭头指针,想为你的个人作品集、创意网站或者某个酷炫的着陆页注入一点灵动的生命力,那么这个名为“Cuberto Cursor”的项目绝对值得你花时间研究。它不是一个简单的图片…...

如何5分钟搞定抖音无水印视频下载:douyin-downloader完整指南

如何5分钟搞定抖音无水印视频下载:douyin-downloader完整指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallbac…...

Zotero中文文献识别难题终结者:Jasminum插件深度解析

Zotero中文文献识别难题终结者:Jasminum插件深度解析 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件,用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum 告别乱码与信息缺…...

Blender MMD Tools终极指南:高效导入导出MMD模型与动作数据的完整解决方案

Blender MMD Tools终极指南:高效导入导出MMD模型与动作数据的完整解决方案 【免费下载链接】blender_mmd_tools MMD Tools is a blender addon for importing/exporting Models and Motions of MikuMikuDance. 项目地址: https://gitcode.com/gh_mirrors/bl/blend…...

当你的智能体需要处理高并发请求时如何保障 API 稳定性

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 当你的智能体需要处理高并发请求时如何保障 API 稳定性 在智能体应用的实际部署中,用户量的增长或特定时段的高并发请求…...

期末复习方法:从知识树到 AI 闪卡,一套更适合大学生的资料整理法

期末复习最常见的误区,是把“资料看完”当成“知识掌握”。很多学生会把课件、教材、PDF、课堂笔记全部打开,从第一页看到最后一页。看时觉得都懂,合上资料却想不起来;刷题时看到熟悉概念,还是不知道该从哪里入手。这不…...

Arm Neoverse V3AE性能监控架构与PMU寄存器详解

1. Arm Neoverse V3AE性能监控架构深度解析在处理器微架构设计中,性能监控单元(PMU)如同汽车的仪表盘,为开发人员提供观察硬件行为的直接窗口。Arm Neoverse V3AE作为面向基础设施的高性能核心,其PMU实现包含一组精密的…...

增量备份为什么还是这么慢?KingbaseES块级永久增量备份给出答案!

🔥承渊政道:个人主页 ❄️个人专栏: 《C语言基础语法知识》 《数据结构与算法》 《C知识内容》 《Linux系统知识》 《算法刷题指南》 《测评文章活动推广》 《大模型语言路线学习》 ✨逆境不吐心中苦,顺境不忘来时路!✨ 🎬 博主简介: 增量备…...

单例模式:C++实现与多线程安全

1. 核心定义与作用(精准版)定义单例模式是一种创建型设计模式,确保一个类有且仅有一个实例,并向整个系统提供唯一的全局访问点。核心作用控制实例数量:严格保证类在程序生命周期内只有一个对象全局访问:无需…...

C++虚函数机制深度解析:从原理到实战

1. 核心概念与多态实现多态的定义:多态是指“以一个接口,多种实现”的能力。在 C 中,通过在基类中使用 virtual 关键字声明函数,可以实现动态绑定(Dynamic Binding),即在运行时根据对象的实际类…...

Sunshine游戏串流完全指南:打造你的私人游戏云服务

Sunshine游戏串流完全指南:打造你的私人游戏云服务 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否梦想着在任何设备上都能流畅地玩PC游戏?Sunshine正…...

工业物联网实战:从预测性维护到系统优化,制造业数字化转型核心解析

1. 制造业的“静默革命”:当产线开始“思考”如果你在制造业干了十年以上,最近几年可能会有一个越来越强烈的感觉:车间里的机器好像“活”过来了。这不再是科幻电影的桥段,而是一场正在发生的、静默但深刻的革命。过去&#xff0c…...

N_m3u8DL-RE如何深度解析加密流媒体:架构设计与实战优化指南

N_m3u8DL-RE如何深度解析加密流媒体:架构设计与实战优化指南 【免费下载链接】N_m3u8DL-RE Cross-Platform, modern and powerful stream downloader for MPD/M3U8/ISM. English/简体中文/繁體中文. 项目地址: https://gitcode.com/GitHub_Trending/nm3/N_m3u8DL…...

2026中国DevOps平台选型全景洞察:技术适配与效能跃升的深层思考

在中国企业数字化转型浪潮中,DevOps平台作为技术基础设施的核心组件,其选型决策正经历从单纯功能对比向多维度综合评估的转变。2026年,这一选择不再是简单的工具采购,而是关乎企业技术战略、业务发展和合规安全的关键决策。通过对…...

CANN/oam-tools安全声明

安全声明 【免费下载链接】oam-tools 本项目为开发者提供故障定位工具,包含故障信息收集,软硬件信息展示,AI core error报错分析等能力,提升故障问题定位效率,文档可在昇腾社区搜索“故障处理简介”(选择社…...

Gitee与OpenSCA的深度整合:构建企业级开源治理新范式

在数字化转型浪潮中,开源技术已成为企业创新的重要驱动力。然而,伴随开源组件广泛应用而来的安全风险与合规挑战也日益严峻。Gitee作为国内领先的代码托管平台,选择与OpenSCA深度集成,打造了一套完整的开源治理解决方案&#xff0…...

NeuroRebuild 动态孪生,虚实同步秒级应急推演

NeuroRebuild 动态孪生,虚实同步秒级应急推演前言危化园区危险源密集、事故蔓延快、应急处置窗口期极短,传统静态BIM、倾斜摄影孪生模型固化滞后,无法跟随现场实景实时变化,灾害推演失真滞后、应急决策被动迟缓,难以适…...

3步掌握开源硬件性能优化工具:解锁你的设备隐藏潜力 [特殊字符]

3步掌握开源硬件性能优化工具:解锁你的设备隐藏潜力 😊 【免费下载链接】Universal-x86-Tuning-Utility Unlock the full potential of your Intel/AMD based device. 项目地址: https://gitcode.com/gh_mirrors/un/Universal-x86-Tuning-Utility …...