2026-05-20 21:39:12 +08:00

240 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: netabrowser-cli
description: >
Neta 反风控+拟人化浏览器自动化 CLI。养号、电商自动化、AI 探索复杂网页时使用。
比 playwright-cli 更难被反风控识别fingerprint-chromium 内核 + patchright 反自动化 +
贝塞尔曲线鼠标轨迹。100 账号矩阵养号场景首选。所有操作通过 scripts/nb.sh
(或 nb.cmd调用不需要 HTTP/curl。
license: MIT
metadata:
version: "2.0"
category: browser-automation
---
# netabrowser-cli
通过 CLI wrapper 操作常驻浏览器 daemon。daemon 持有 chromium 实例 + 登录态 +
session profileCLI 是连 daemon 的薄客户端。AI 全程只用 `scripts/nb.sh <cmd>`
**永远不用 curl 或 HTTP**
## 快速验证环境
每次开始任务前先验证 daemon 是否启动:
```bash
bash scripts/nb.sh list
```
期望返回 `{ok: true, ...}` 或会话列表。如果连接失败 → backend 没启动,告知用户。
### Chromium 自动下载
`nb.sh` / `nb.cmd` 每次启动都会先跑 `scripts/ensure-chromium.cjs`
- `packages/netabrowser-cli/chromium/win64/chrome.exe` 已存在 → 秒过。
- 缺失 → 自动从默认 URL 下载 zip约 170MiB解压到 `packages/netabrowser-cli/chromium/win64/`,归一化为 397MB 的 Chromium 产物。
- 覆盖:
- `NETA_CHROMIUM_PATH` 指定已有 `chrome.exe` 绝对路径 → 直接复用,**不会自动下载到别处**(缺失时会报错提醒,避免误下)。
- `NETA_CHROMIUM_URL` 指定自定义 zip 下载地址(内网镜像/CDN
- 解压Windows 走 PowerShell `Expand-Archive`Linux/macOS 走 `unzip`(失败回落 `tar`)。
第一次执行任何 `nb` 命令时会看到 `[ensure-chromium] downloading ...` 日志,耐心等完即可。
---
## When to use vs playwright-cli vs patchwright-cli
| Skill | 适用场景 |
|---|---|
| **netabrowser-cli**(本)| 国内反风控严的站(小红书/抖音/淘宝/拼多多/微博)+ 多账号矩阵 + 养号 |
| **patchwright-cli** | 国外 Cloudflare/DataDome 等反爬保护 |
| **playwright-cli** | 测试、无反风控的站 |
**目标是中国电商/社交站点 → 用本 skill。**
---
## 拟人化 vs 效率的选择规则
**用户明确要求"拟人化"/"移动鼠标"/"模拟人工操作"时**:必须用 `snapshot → click/hover` 操作页面元素,不要用 `goto` 直跳 URL。拟人化的价值在于让反风控系统看到真实的鼠标轨迹和点击行为。
**用户只要求"查看/获取信息"没提拟人化时**:优先用 `goto` 直跳目标 URL更快更稳定。
**典型拟人化流程**(用户要求拟人操作时):
```bash
bash scripts/nb.sh open https://www.taobao.com --session=tb-main --headed
bash scripts/nb.sh snapshot --session=tb-main # 找到"已买到"的 ref
bash scripts/nb.sh hover e123 --session=tb-main # 拟人化 hover 触发下拉
bash scripts/nb.sh wait --session=tb-main --timeout=1000
bash scripts/nb.sh snapshot --session=tb-main # 重新 snapshot 找下拉项
bash scripts/nb.sh click e456 --session=tb-main # 拟人化点击
bash scripts/nb.sh wait --session=tb-main --load-state=networkidle
bash scripts/nb.sh snapshot --session=tb-main # 读取结果
```
**典型效率流程**(只要结果时):
```bash
bash scripts/nb.sh open https://www.taobao.com --session=tb-main --headed
bash scripts/nb.sh goto https://buyertrade.taobao.com/trade/itemlist/list_bought_items.htm --session=tb-main
bash scripts/nb.sh wait --session=tb-main --load-state=networkidle
bash scripts/nb.sh snapshot --session=tb-main
```
---
## 核心工作流
```
nb.sh open → 启动会话(同名 session 自动恢复登录态)
nb.sh snapshot → 拿 ARIA 树YAML 格式,含 ref
nb.sh click/fill/hover [ref] → 拟人化操作
nb.sh wait → 等元素/页面状态
nb.sh close → 关闭profile 持久化保留)
```
### 最简任务模板
```bash
# 1. 打开(同名 session 复用 profile登录态自动恢复
bash scripts/nb.sh open https://www.taobao.com --session=tb-main --headed
# 2. 看页面结构(输出是 ARIA YAML每个交互元素带 [ref=eN]
bash scripts/nb.sh snapshot --session=tb-main
# 3. 操作(用 snapshot 中的 ref
bash scripts/nb.sh click e123 --session=tb-main
bash scripts/nb.sh fill e45 "搜索关键词" --session=tb-main
bash scripts/nb.sh press Enter --session=tb-main
# 4. 等加载完
bash scripts/nb.sh wait --session=tb-main --load-state=networkidle
# 5. 完事关闭profile 留着下次复用)
bash scripts/nb.sh close --session=tb-main
```
---
## ⚠️ 关键陷阱(不读这段会浪费 token
### 1. 同名 sessionName 自动复用登录态
profile 目录在 `.netabrowser-data/profiles/<sessionName>/`cookie/localStorage 在 close 后保留。**每个账号固定一个 sessionName**(如 `taobao-main`),下次 open 自动恢复登录。**不要每次换 sessionName**——会重新登录。
### 2. 首页"立即登录"≠ 没登录
淘宝/拼多多/京东等 SPA 首页加载完后**异步**读 cookie 渲染用户名snapshot 拍得太早会看到"立即登录"。**正确判断方式:**
- snapshot 里有"已买到"/"我的淘宝"/"我的订单"等只有登录后才出现的链接 → 已登录
- 直接点"已买到",看跳转到订单页还是登录页 → 实际验证
**不要看到"立即登录"就向用户要账号密码。**
### 3. 头部 hover 触发的链接(淘宝"已买到"等)
淘宝头部"已买到"是 hover 触发的下拉菜单项,单纯 click 不跳转。两种解法:
```bash
# 方法 A先 hover 触发下拉,再 click
bash scripts/nb.sh hover e123 --session=tb-main # hover 父菜单
bash scripts/nb.sh wait --session=tb-main --timeout=1000
bash scripts/nb.sh snapshot --session=tb-main # 重新 snapshot 找下拉项
bash scripts/nb.sh click e456 --session=tb-main
# 方法 B更快直接 goto 目标 URL
bash scripts/nb.sh goto https://buyertrade.taobao.com/trade/itemlist/list_bought_items.htm --session=tb-main
```
常用直达 URL
- 淘宝已购:`https://buyertrade.taobao.com/trade/itemlist/list_bought_items.htm`(注意是 `buyertrade` 不是 `buyer.trade`
- 拼多多订单:`https://mobile.yangkeduo.com/orders.html`
- 京东订单:`https://order.jd.com/center/list.action`
### 4. 何时停止重试(重要)
遇到以下错误**立即停止**,告知用户而不是反复重试:
| 错误 | 含义 | 行动 |
|---|---|---|
| `net::ERR_NAME_NOT_RESOLVED` | DNS 失败 | 报告用户,可能是网络/代理问题 |
| `net::ERR_TIMED_OUT` 连续 2 次 | 站点不可达 | 报告用户 |
| `Ref 'eN' has no bounding box` 同 ref 2 次 | 元素消失或变化 | 重新 snapshot 找新 ref |
| 进入 `chrome-error://` 错误页 | 浏览器内部错误 | 报告用户检查代理/网络 |
**不要:**
- 用不同 URL 瞎试
- snapshot 看到一样内容超过 2 次说明操作没生效,停下分析
- 看到 chrome-error 就反复 reload
---
## Commands
### 会话管理
- `open <url> --session=NAME [--proxy=URL] [--fingerprint-seed=N] [--profile-dir=NAME] [--headed] [--priority=low|normal|high] [--queue]` 启动会话
- `close --session=NAME` 关闭profile 保留供下次复用)
- `list` 列出所有活跃会话
**代理必须在 open 时指定**,不能给已有 session 追加代理。如果需要换代理,先 close 再 open
```bash
bash scripts/nb.sh close --session=tb-main
bash scripts/nb.sh open https://www.taobao.com --session=tb-main --headed --proxy=socks5://user:pass@host:port
```
**代理协议必须匹配**SOCKS5 代理用 `socks5://`HTTP 代理用 `http://`。写错协议会 400/超时。
**⚠️ 走代理 + headed 时必须延长 bash 工具 timeout**:默认 bash timeout 是 30s但走代理首次打开浏览器需要 30-60s。**调用 bash 工具时务必传 `timeout: 60000`(毫秒)**——这是 bash 工具的参数(不是 nb.sh 的 --timeout
```
// AI 调 bash 工具时这样传:
{ "command": "bash scripts/nb.sh open ... --proxy=socks5://...", "timeout": 60000 }
```
不传 timeout 默认 30s 会被 NetaClaw kill 掉,导致 ECONNRESET。
### 检查
- `snapshot --session=NAME` 获取页面 ARIA 树YAML 格式,含 ref
- `screenshot --session=NAME [--full-page] [--out=path]` 截图
### 交互(默认拟人化 mode=full
- `click <ref> --session=NAME [--mode=full|fast|off]` 点击(含 visible+scrollIntoView 检查)
- `hover <ref> --session=NAME [--mode=...]` 悬停(触发 hover 菜单等)
- `fill <ref> <value> --session=NAME` focus + 清空 + 拟人化输入
- `type <text> --session=NAME` 在已 focused 输入框打字
- `press <key> --session=NAME` 按键Enter/Tab/Escape/Control+A 等)
- `select <ref> <value> --session=NAME` 选择 `<select>` 的某个 option
- `check <ref> --session=NAME [--uncheck]` 复选框勾选/取消
- `scroll <deltaY> --session=NAME [--mode=...]` 滚动(正数向下)
### 导航 + 等待
- `goto <url> --session=NAME` 跳转
- `wait --session=NAME [--ref=eN] [--state=visible|hidden] [--load-state=networkidle] [--timeout=ms]` 等待
### 状态持久化
- `cookie-list --session=NAME [--domain=DOM]` 获取 cookies
- `state-save --session=NAME [--output=PATH]` 保存完整登录态(默认 `<dataDir>/states/<session>.json`
- `state-load --session=NAME --input=PATH` 恢复
### 全局选项
- `--raw` 输出单行 JSON便于管道处理
- `NETA_BROWSER_HUMANIZE_MODE=full|fast|off` 环境变量设定本会话默认 mode
---
## 拟人化档位
| `--mode` | 单命令开销 | 适用场景 |
|---|---|---|
| **full**(默认)| 2-5s | 养号、敏感操作、AI 探索复杂页面 |
| **fast** | 0.3-0.7s | 批量发布、批量评论 |
| **off** | <100ms | 测试CI |
养号场景每号约 30 操作 × 5s 2.5min100 号串行 4 小时批量任务用 `--mode=fast`
---
## 详细参考文档
- [拟人化档位详解](references/humanization.md)
- [指纹参数fingerprintSeed 何时用)](references/fingerprint.md)
- [代理配置](references/proxy.md)
- [典型场景示例](references/examples.md)