Web 自动化
Tapilot Web 模块基于 Chrome DevTools Protocol (CDP),自动化任何网站。和移动端共用同一套 DSL / MCP / HTTP 接口,一套脚本三端通吃。
工作机制
DSL / MCP 调用
↓
Tapilot Web 模块 (apps/mcp-server/src/web.ts)
↓ CDP
Chrome / Chromium (headless 或可见)
↓
目标网页启动 Chrome 时 Tapilot 会:
- 从 PATH 找 Chrome(
chrome/google-chrome/Chromium/chromium) - 加参数
--remote-debugging-port=9222启动 - 通过
localhost:9222建立 CDP 连接
快速示例(DSL)
yaml
id: search-demo
platform: web
steps:
- openBrowser: { url: "https://www.bing.com", headless: false }
- webType: { selector: 'textarea[name="q"]', text: "Tapilot" }
- executeJs: "document.querySelector('form').submit()"
- waitFor: { pattern: "相关结果", timeoutMs: 15000 }
- webScreenshot: { name: search-result }
- closeBrowser跑:
bash
pnpm test-pack search-demo --device web完整 DSL actions(Web)
| Action | 示例 | 说明 |
|---|---|---|
openBrowser | openBrowser: { url, headless? } | 启动 Chrome 并(可选)导航 |
openUrl | openUrl: "https://..." | 已打开的浏览器里导航 |
webClick | webClick: { selector } 或 { text } | 按 CSS selector 或可见文字点击 |
webType | webType: { selector, text } | 清空并输入文字(触发 input/change 事件) |
webAssert | webAssert: { selector, text?, visible? } | 断言元素文字/可见 |
webWaitFor | webWaitFor: { selector, timeoutMs? } | 等元素出现 |
webScreenshot | webScreenshot: { name? } | 截当前标签页 |
executeJs | executeJs: "document.title" | 跑任意 JS,返回结果 |
closeBrowser | — | 关闭 |
读屏 / 轮询 / 变量也全支持:
yaml
- openBrowser: "https://example.com/login"
- webType: { selector: "#email", text: "${EMAIL}" }
- webClick: { text: 发送验证码 }
- waitFor: 验证码已发送
- readText: { regex: "验证码是\\s*(\\d{6})", into: CODE }
- webType: { selector: "#otp", text: "${CODE}" }
- webClick: { text: 登录 }MCP 工具
| Tool | 说明 |
|---|---|
web_list_tabs | 列出所有打开的标签页 |
web_navigate | 在指定 tab 导航 |
web_execute_js | 跑 JS,返回结果 |
web_get_dom | 获取页面 DOM(HTML 字符串) |
web_click | 按 selector 点击 |
和手机端共用 screenshot / tap / swipe 则走移动设备路径,Web 用上述专用 web_* tools。
HTTP REST API
都在 /web/* 路径下:
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /web/launch | 启动浏览器 {url?, headless?} |
| POST | /web/close | 关闭 |
| POST | /web/navigate | 导航 {url} |
| GET | /web/pages | 标签页列表 |
| POST | /web/click | {selector} 或 {text} |
| POST | /web/type | {selector, text} |
| GET | /web/screenshot | 返回 PNG |
| POST | /web/assert | {selector, text?, visible?} |
| POST | /web/wait-for | {selector, timeoutMs?} |
| POST | /web/evaluate | 跑 JS {code} |
| GET | /web/title | 当前标题 |
常见坑
富文本编辑器(ProseMirror / Quill / Draft.js)
普通 webType 对 contenteditable 不生效。用 executeJs:
yaml
- executeJs: |
const ed = document.querySelector('.ProseMirror');
ed.innerHTML = '<p>正文内容</p>';
ed.dispatchEvent(new Event('input', { bubbles: true }));文件上传
HTML <input type="file"> 不能 click 触发弹窗。目前 Tapilot 的 webClick 不直接支持,用 executeJs 配合 CDP 原生 API 或把文件 paste 进去。
登录态保持
不支持自动过扫码登录。最佳实践:
- 用真实 Chrome 手动登录一次(
google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/tapilot-profile) - 后续 Tapilot
openBrowser指定 user-data-dir 复用 cookie
iframe 跨帧操作
CDP 默认操作顶层 frame。如果目标在 iframe 里,用 executeJs 里 document.querySelector('iframe').contentDocument... 穿进去。
反自动化检测
大厂网站(淘宝、京东、微信公众号后台等)有一定反自动化:
navigator.webdriver被检测 → Chrome--disable-blink-features=AutomationControlled启动参数缓解- 行为太机械 → 加随机
wait/ 模拟真人点击节奏 - IP 异常 → 换正常住宅 IP
即使如此,被识别后果比微信 app 轻(一般是要求验证码,不是永封)。
适合的场景
| 场景 | 适合度 |
|---|---|
| 测试自家 Web 应用(SPA 回归、登录流程、表单填写) | ✅ 主场 |
| 数据录入 / 后台管理重复操作 | ✅ |
| 定时巡检生产 Web(cron + DSL) | ✅ |
| 爬取公开数据(无反爬) | 🟡 能,但 playwright/puppeteer 更专业 |
| 爬取反爬网站 / 批量账号矩阵 | ⛔ 不适合,换专业反反爬工具 |