news 2026/10/11 13:55:43

rea实战:用脚本自动化浏览器重复操作,打造高效流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
rea实战:用脚本自动化浏览器重复操作,打造高效流程

首先要跟看到这个标题的朋友解释一下:我平时写自动化脚本,经常要给临时项目起个随手能打的代号,rea就是从里面蹦出来的三个字母。它的全称被我私下写成 Repeat Everything Automatically——听起来有点中二,实际上做的事情特别接地气:把那些每天都要在浏览器里重复点的按钮、重复填的表单、重复下载的报表,交给一段脚本去跑。

这个项目解决的痛点很明确:你以为点几下鼠标不算累,但当这种“点几下”每天要出现十几次甚至几十次,而且必须保持顺序不错、速度不慢的时候,人就会开始出错、烦躁、摸鱼。而脚本不会。它适合谁?适合所有工作里被网页后台折磨的人,比如运营、财务、人事、客服、数据分析岗,也适合想用浏览器自动化做点效率工具的开发者。读完这篇文章,你不需要完全掌握编程,只要照着抄,就能跑通第一个属于你自己的自动操作流程。

1. 为什么我会把一个自动化工具叫 rea

1.1 一个反复出现的真实痛点

我第一次萌生写 rea 的念头,是因为某一个普通周四下午。

当时我在处理一个每周都要重复的任务:登录某个后台 → 进列表页 → 设置筛选条件 → 点查询 → 勾选所有结果 → 点批量导出 → 等文件生成 → 下载 → 重命名。整套操作大概需要八到十分钟,如果中途网络卡一下,或者某一步点早了,就得重来。连续做了两个月之后,我发现自己看到那个列表页都想绕路走。

更让人烦躁的是,这种流程一旦涉及“必须按顺序执行”,人工操作就天然不可靠。你可能在等待下载时切到别的窗口,回来忘了刚才点没点;也可能因为多选了一个不该选的对象,导致整份报表需要重新生成。这类问题不是靠“细心”能解决的,因为人的注意力本身就是稀缺资源。

所以我把自己的需求拆了一下:第一步,把固定操作录下来;第二步,把重复流程参数化,比如日期、关键词、筛选条件;第三步,让脚本按步骤执行,并把每一步的结果记录下来。这就是 rea 最初的雏形。

1.2 为什么不自接用现成的自动化平台

有人可能会问,市面上不是有很多 RPA(机器人流程自动化)工具吗?下载一个、拖拽流程、运行,不也能做到类似效果?确实可以,但我在实际对比之后还是决定自建。

原因有三点。一是成本,很多 RPA 工具按控制端数量或运行次数收费,个人或小团队用起来不划算,而自己用开源浏览器自动化库写脚本,跑多少遍都不额外收费。二是灵活度,RPA 工具的可视化编排对于简单流程很好用,但一旦要写条件分支、循环嵌套、错误重试,反而要绕很多弯,不如代码直接。三是调试体验,脚本出问题的时候,代码方式可以打日志、截图、查看调用栈,而可视化平台往往只给你一个“执行失败”的提示,排查起来非常抓狂。

当然,我并不是说自建一定适合所有人。完全没有代码基础的话,直接学 HTML 结构、选择器、等待条件,门槛确实比拖拽高。但如果你恰好懂一点编程,或者愿意花两天时间补个基础,那 t自建脚本得到的控制力是 RPA 工具很难给的。

另外还有一个很实际的理由:很多后台系统的界面长年不变,但又有大量重复操作。这种场景用代码写一次,几年都能一直复用,边际成本几乎为零。

1.3 rea 的三大模块:录制、回放、校验

我最早想做成“录制”工具,后来发现纯录制并不可靠,因为真实页面存在各种变化。最后把 rea 拆成了三个功能模块:

  • 回放核心:负责按顺序执行每一条操作指令,打开页面、输入内容、点击按钮、等待结果。
  • 配置驱动:操作过程不硬编码在脚本里,而是抽成一个步骤清单,用 JSON 或简单数组描述,方便修改和扩展。
  • 结果校验:每一步执行后都要确认页面真的发生了变化,比如某个元素出现、某段文本更新、下载任务完成,而不是“点击成功”就算完事。

这三个模块听起来简单,却是处理复杂网页的关键。录制只解决“第一步怎么开始”,真正让脚本能长期稳定运行,靠的是校验。没有校验的自动化脚本,就像闭着眼睛走路,运气好能到终点,运气不好直接撞墙。

2. 核心技术点拆解:让脚本像真人一样“找得到、等得起、信得过”

2.1 元素定位:三重武器和一条优先级铁律

一个网页自动化脚本运行失败,十有八九是元素定位出了问题。页面上那个按钮明明在那里,但脚本就是找不到,或者找到了多个。

我常用的定位方式有三种。第一种是 CSS 选择器,比如input[name="keyword"]、.btn-primary,胜在简洁,适合有明显特征的元素。第二种是可见文本,比如button:has-text("查询"),适合按钮上的文字会变化、但核心功能不变的场景。第三种是 XPath,比如//div[@class="result" and contains(text(),"明细")],适合页面结构复杂、没有额外标记的情况。

这三者不是平等关系,我总结出一条优先级铁律:能加>[ { "id": "open_page", "type": "goto", "url": "https://example.com/admin/list", "waitUntil": "domcontentloaded" }, { "id": "fill_keyword", "type": "fill", "selector": "input[name='keyword']", "value": "{{keyword}}" }, { "id": "click_search", "type": "click", "selector": "button:has-text('查询')" }, { "id": "wait_result", "type": "waitFor", "selector": ".result-item", "timeout": 10000 } ]

这个设计最大的好处是,用户不需要了解代码细节,也能通过改配置来调整流程。{{keyword}}是一种占位符,运行时从外部参数或环境变量中取值。这样一来,同样的流程,今天跑关键词 A,明天跑关键词 B,脚本主体一行不用改。

做一个好的配置驱动结构,关注点不是怎么写配置文件,而是怎么把“易变的部分”和“稳定的部分”分开。易变的部分包括:页面地址、搜索关键词、导出文件格式、日期范围。稳定的部分包括:固定表单结构、操作顺序、校验条件。把它们分开,脚本才能长期省心。

3. 从零跑通第一个 rea 脚本

3.1 准备环境和安装依赖

我一般用 Node.js 生态来写这类脚本,因为浏览器自动化库对它支持最好,安装起来也快。如果你对 Python 更熟,也可以用对应版本,思路完全一样。

安装步骤同样简单,开一个终端,依次执行:

npm init -y npm install playwright npx playwright install chromium

第一条命令初始化项目,第二条安装浏览器自动化库,第三条下载一个可独立运行的浏览器内核。很多人会漏掉第三条,导致运行时报“找不到浏览器”,所以这里先打个预防针。

顺便说一句,安装过程可能需要一点磁盘空间,浏览器内核大概几百 MB。如果你在公司内网,网络受限,可以找运维开下载白名单。这个环节最不起眼,却是新手第一个容易卡住的地方。

3.2 最小脚本:登录、查询、导出

跑通一个最小的 rea 脚本,我拿“登录后查询并导出报表”来演示。别看流程简单,它已经覆盖了日常自动化的高频操作:填表、点击、等待、下载。

先看代码:

const { chromium } = require('playwright'); (async () => { const browser = await chromium.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://example.com/login', { waitUntil: 'domcontentloaded' }); await page.fill('#username', process.env.REA_USER || 'demo'); await page.fill('#password', process.env.REA_PASS || 'changeme'); await page.click('button[type="submit"]'); await page.waitForURL('**/dashboard'); await page.fill('input[name="keyword"]', '2025-01'); await page.click('button:has-text("查询")'); await page.waitForSelector('.result-item'); const downloadPromise = page.waitForEvent('download'); await page.click('a.btn-export'); const download = await downloadPromise; await download.saveAs('./reports/report-' + new Date().toISOString().slice(0, 10) + '.xlsx'); await browser.close(); })();

这段代码的逻辑很直白:打开登录页、填账号密码、点登录、等跳转、填查询条件、点查询、等结果出现、触发下载、保存文件。里面几乎每一行都有对应目的,没有冗余。

你可能注意到我用了process.env.REA_USER,这是从环境变量读取账号信息,避免把敏感内容写死在代码里。如果你只是本地测试,也可以直接写变量值,但上传代码库时要小心。

3.3 常用加固:登录态复用、失败重试、截图日志

基础脚本能跑通之后,你需要考虑的不是“怎么跑一次”,而是“怎么跑一千次”。我强烈建议优先做三件事。

第一,登录态复用。很多后台系统登录一次后,会话能维持一段时间。每次脚本启动都重新走一遍登录流程,既慢又容易触发安全策略。更好的做法是,第一次登录成功后,把会话状态保存下来,后续运行直接加载:

// 保存会话 await context.storageState({ path: 'auth.json' }); // 下次直接使用 const context = await browser.newContext({ storageState: 'auth.json' }); const page = await context.newPage();

这里有一点要注意:不同浏览器的 storageState 格式基本是标准 JSON,可以跨脚本复用。如果遇到登录状态过期,顶多重新登录一次,再刷新保存文件便好。

第二,失败重试。网络抖动、后台偶发报错,都会导致脚本中断。我通常给每个关键步骤包一个重试包装器,失败后等两秒,最多重试三次。重试时最好换一种等待策略,而不是无脑重复同样操作。

第三,截图和日志。这是很多新手最容易忽略的。在每一步关键动作之后截图存盘,甚至直接用 trace 录制功能,事后排查的效率高得多。脚本运行完自动生成一个带时间戳的目录,里面放着截图、日志、下载记录,比任何“到底哪里错了”的脑内复盘都管用。

3.4 处理 iframe 和动态弹窗这两个糟心问题

实际项目中,我碰到最多的两个“非标准场景”是 iframe 和动态弹窗。

iframe 可以理解成页面里嵌了一个独立的子页面。直接在外层页面定位 iframe 里的元素,十有八九找不到,因为脚本默认只在主文档里搜索。处理方式是先切换到对应框架,再在里面操作:

const frame = page.frame({ url: /\/admin\/approve\// }); await frame.locator('input[name="approveComment"]').fill('已通过'); await frame.locator('button:has-text("确认")').click();

动态弹窗则是另一个常见坑。有些弹窗不是一开始就在页面里的,而是等几秒后才出现,直接点击大概率会落空。我的建议是,弹窗类的点击前先等待它出现,并且优先使用“可见状态”而非“存在状态”,因为有时候元素在 DOM 里存在,但被 CSS 隐藏着,点了和没点一样。

这些细节看上去琐碎,却是决定脚本“是玩具还是工具”的分水岭。能处理这些真实页面问题,等于真正掌握了 rea 的精髓。

4. 常见问题与排查技巧

4.1 运行时报错的排查速查表

我把这段时间踩过的坑汇总成一张速查表,基本覆盖了新手最常见的上报错类型。每次脚本异常时,先别急着改代码,对应下面的情况逐条排查。

错误表现最常见原因处理方向
找不到元素页面还在加载 / 选择器变了 / 层级不对加显式等待;换>
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/11 13:54:48

Unity系统字体动态加载:TextMeshPro生僻字与多语言渲染方案

简介:UnityNativeOSFont 是一套面向 Unity 开发者的开源工具,用于在运行时获取操作系统本地字体并接入 TextMeshPro 动态字体渲染,解决 TMP 默认字体库无法覆盖各平台系统字体、需手动导入字体文件的问题。它通过 C# 脚本读取系统字体列表并转…

作者头像 李华
网站建设 2026/10/11 13:54:30

企业年会大屏互动系统实战:WebSocket高并发弹幕与摇一摇

简介:这是一套面向企业年会策划人员、活动执行团队及现场技术支持的LED大屏互动解决方案,针对年会现场气氛调动难、互动形式单一的问题,整合了抽奖、游戏与签到等环节。压缩包共约2000个文件,整体255.57MB,以png图片素…

作者头像 李华
网站建设 2026/10/11 13:51:42

WOA-CNN在通信辐射源识别中的超参数优化实践

简介:本资源面向通信工程、信号处理及人工智能方向的科研人员与高年级本科生,提供一种基于鲸鱼优化算法(WOA)提升卷积神经网络(CNN)分类性能的完整MATLAB实现方案,聚焦通信辐射源个体识别这一典…

作者头像 李华
网站建设 2026/10/11 13:47:55

YOLOv5摔倒检测落地实战:从高分模型到养老院真实部署

简介:本资源是一套基于YOLOv5实现的摔倒检测与跌倒识别高分项目,面向深度学习初学者及计算机视觉实践者,聚焦于老年人看护、智能监控等实际安防场景中的行为异常识别需求。压缩包共193个文件,含75张标注图像(jpg/jpeg&…

作者头像 李华
网站建设 2026/10/11 13:47:54

TensorRT部署SAM分割模型:C++推理管线与性能优化实践

简介:面向需要将 Segment Anything Model 落地到 NVIDIA GPU 的算法工程师与 C 开发人员,这套资源完整给出 TensorRT 部署 SAM 分割模型的工程代码与分步部署流程。内容覆盖模型转换、层融合、内核自动调优、推理执行等关键环节,适合已有 PyT…

作者头像 李华

关于博客

这是一个专注于编程技术分享的极简博客,旨在为开发者提供高质量的技术文章和教程。

订阅更新

输入您的邮箱,获取最新文章更新。

© 2025 极简编程博客. 保留所有权利.