Simulator Browser RPA Example
这是一个仿真浏览器 RPA 的可复制参考实现:在可控 sandbox 页面上,通过 async Playwright 完成门户门闩、两步登录、表单填写、PIN 弹窗、结果解析。
本示例抽象自已跑通的「工行批量提交类」浏览器自动化 skill 的工程范式,但已去业务化——不包含真实银行/真实资金语义,也不是 Amazon 或任何生产技能的复制。
适合什么场景
- 自有 行业仿真系统 /
sandbox.jc2009.com/ 本地sandbox/demo_app.html - 需要 浏览器 RPA 做端到端演示或回归
- 表单较复杂:门户 HITL、多步登录、Tab 切换、动态增行、PIN 弹窗、成功页解析
- 需要 adapter 分层:
mock(CI)与simulator_rpa(半集成)可切换
不适合什么场景
- 真实第三方网站 + 高风控 + 人工验证码 → 优先看
../real_browser_rpa/README.md - 目标系统有稳定 官方 API → 不要硬写浏览器 RPA
- 不要把本示例的业务字段、selector、sandbox URL 原样复制到你的 skill
目录结构
simulator_browser_rpa/
├── README.md
├── sandbox/
│ └── demo_app.html # 本地仿真页面(门户门闩 + 批量提交教学 DOM)
├── scripts/
│ ├── service/
│ │ ├── browser_session.py # async 启动 persistent context(不含 goto)
│ │ ├── account_client.py # account-manager subprocess(对齐 real_browser_rpa)
│ │ ├── simulator_playwright.py # RPA 主流程(厚)
│ │ ├── task_service.py # async 编排层
│ │ └── adapter/
│ │ ├── base.py # BatchItem / BatchSubmitResult 契约
│ │ ├── mock.py # mock/unit 档
│ │ ├── simulator_rpa.py # 薄 adapter:pick / lease / 委托 RPA
│ │ └── __init__.py # select_adapter
│ └── util/
│ ├── constants.py
│ └── logging.py
└── tests/
├── test_adapter_dispatch.py
├── test_no_rpa_helpers_import.py
├── test_simulator_rpa_unit.py
└── test_stop_reason.py
文件职责
| 文件 | 职责 |
|---|---|
browser_session.py |
async 系统 Chrome/Edge + launch args;不在此 goto |
account_client.py |
唯一 account-manager subprocess 封装(pick_web_account / release_lease) |
simulator_playwright.py |
门户轮询、登录、批量表单、PIN、解析 batch_id、截图 |
adapter/simulator_rpa.py |
薄 adapter:pick 账号、lease、委托 RPA、finally release_lease |
adapter/mock.py |
不启浏览器,供 unit/mock/CI |
task_service.py |
async 校验输入 → 选 adapter → await submit_batch |
sandbox/demo_app.html |
可控 DOM;含可选门户门闩 + 原批量提交流程 |
核心流程
await run_batch_submit(target, items)校验参数select_adapter()按OPENCLAW_TEST_TARGET选择 mock 或 simulator RPAsimulator_rpa档:SimulatorBrowserRpaAdapter.submit_batch内pick_web_account(sim_batch)→submit_batch_rpa→release_lease- RPA:门户门闩(若可见则 HITL 轮询)→ 登录两步 → 批量页 → 填表 → 提交 → PIN → 解析
batch_id - 失败截图(有
artifacts_dir时)→ 返回BatchSubmitResult
两档仿真目标
| 档位 | 目标 | 说明 |
|---|---|---|
| 本地教学 | sandbox/demo_app.html(file://) |
结构教学 + mock 单测默认 |
| 线上联调 | https://sandbox.jc2009.com/... |
设 SIMULATOR_BASE_URL + account-manager sim_batch 账号 |
联调时账号 url 用行业根路径,不要写 /login 子路径;auth_strategy=per_session_manual。
account-manager 注册示例(泛化)
python .../account-manager/scripts/main.py account add-web \
--platform sim_batch \
--login-id demo001 \
--url file:///.../demo_app.html \
--environment simulator \
--auth-strategy per_session_manual
线上 sandbox 时将 --url 换为 https://sandbox.jc2009.com/... 占位路径(按团队部署填写)。
PIN/密码演示值:RPA 从 account 的 login_id 取账号;password / token_pin 允许从 account 字段或环境变量 SIMULATOR_PASSWORD / SIMULATOR_TOKEN_PIN 回退;验证码固定演示值 0000(仅 sandbox 用)。
Copy map(复制到新技能 scripts/)
| 来源(examples) | 目标(新技能) | 说明 |
|---|---|---|
browser_session.py |
scripts/service/browser_session.py |
async;URL 仅 page.goto,不进 launch args |
account_client.py |
scripts/service/account_client.py |
subprocess,对齐 real_browser_rpa |
simulator_playwright.py |
scripts/service/<platform>_playwright.py |
RPA 主流程(厚) |
adapter/ |
scripts/service/<domain>_adapter/ |
薄 simulator_rpa + mock |
task_service.py |
scripts/service/task_service.py |
async 编排 |
util/constants.py |
scripts/util/constants.py |
须替换 TARGET_PLATFORM 等业务常量 |
tests/ |
tests/ |
可按需复制 dispatch / unit / 禁止 import 守护 |
sandbox/demo_app.html |
— | 仅仿真测试,不进入生产 skill |
明确禁止
- 不要
import account-manager内部模块(rpa_helpers、inject_account_manager_scripts_path、get_account_credential) - 不要 sync Playwright 用于完整 RPA 主路径
- 不要在
task_service.py/ RPA 主流程里散落 account-manager subprocess - 不要在技能侧执行
playwright install/pip install playwright - 不要把 URL 放进
launch_persistent_context(args=[...]) - 不要 vendor
scripts/jiangchang_skill_core/ - 不要照抄 slug、logger 名、演示账号到生产 skill
旧版
pick_simulator_account()/SimulatorAccount/set_credentials()已废弃;账号统一由 account-manager 下发。
联调检查表
- 数据目录
.env中OPENCLAW_TEST_TARGET=simulator_rpa(非 mock) - account-manager:
platform ensure+ 账号active+ 有profile_dir - 目标 sandbox UI 已部署(跨团队)
- 失败先查
rpa-artifacts/截图,再查 Chrome profile 缓存(可用--user-data-dir手工打开清站点数据) - 默认
tests/run_tests.py/ 本 examplepytest仍全部通过(mock 离线)
依赖说明
- Python 3.10+
- Python 包
playwright:由宿主共享 runtime 提供;技能侧不要pip install playwright - 默认使用系统 Chrome/Edge;技能侧不要
playwright install jiangchang_skill_core.runtime_env.find_chrome_executable(可选)
环境变量(示例)
| 变量 | 说明 |
|---|---|
OPENCLAW_TEST_TARGET |
mock/unit → Mock;simulator_rpa → 仿真 RPA |
SIMULATOR_BASE_URL |
仿真页 URL;默认本地 demo_app.html 的 file URI |
SIMULATOR_PASSWORD / SIMULATOR_TOKEN_PIN |
演示密码/PIN 回退(账号字段优先) |
PORTAL_LOGIN_WAIT_SEC |
门户 HITL 超时(默认 120) |
OPENCLAW_BROWSER_HEADLESS |
0 默认有头;1 无头(CI 可用) |
运行测试
cd examples/simulator_browser_rpa
python -m pytest tests/ -v
测试为 mock/纯函数,不启动真实浏览器。
当前状态
- async Playwright + 薄 adapter +
simulator_playwright.py工程范式已对齐real_browser_rpa。 - 未接入完整 CLI、数据库与 entitlement。