简介
适用场景:Debian 13 VPS 已部署 PicoClaw,并以普通用户
picoclaw通过微信 iLink 提供 Agent 服务。
本文目标:不修改 PicoClaw 源码,不新增 Docker、MCP、常驻浏览器服务或 cron 任务;仅安装 Obscura,并让 Agent 在普通抓取不足时按需渲染 JavaScript 页面。
1. 方案概览
网页访问采用分层后备,而不是让无头渲染器替代全部请求:
web_search / web_fetch
↓
bounded curl GET / HEAD
↓
Obscura fetch(仅当公开页面正文需要 JavaScript 渲染时)
web_fetch、curl 仍然更适合静态 HTML、JSON、状态码、重定向和下载链接。只有普通抓取拿不到 JavaScript 渲染后的正文时,Agent 才启动一次 Obscura CLI;执行结束后进程退出。
这种设计适合 1C / 1 GB 级别 VPS:
- 不改 PicoClaw 源码或
config.json; - 不增加 Obscura systemd 服务;
- 不启动 MCP、代理、批量抓取或常驻浏览器;
- 单次请求有导航时限和总时限;
- Obscura 由
root管理,Agent 只拥有执行权限。
Obscura 用于公开 JavaScript 页面的正文渲染,不保证可以通过 Google 搜索挑战、CAPTCHA、登录墙、HTTP 403、HTTP 429 或其他访问限制。遇到这些情况应停止并报告。
![Agent/PicoClaw 增加 Obscura JavaScript 网页渲染后备[picoclaw-obscura-javascript-rendering]-CXT - Enjoy Life | 生活、技术、交友、分享](https://www.cxthhhhh.com/wp-content/uploads/2026/07/2026071311430770.jpg)
1.1 输出格式策略:Markdown 默认,Text 按需,HTML 受限
timeout 35s obscura fetch "<URL>" --stealth --quiet --timeout 20 --dump markdown
| 输出格式 | 规则 | 适用场景 |
|---|---|---|
markdown | 默认使用 | 调研、长文阅读、资料归档、保留标题层级、段落、列表和链接语义。 |
text | 按需使用 | 只需简洁问答、标题/日期/价格等事实提取、快速可用性检查、页面预计很长或用户明确要求纯文本。 |
html | 默认禁止 | 仅当用户明确要求渲染后的 HTML,或 Agent 正在排查正文提取失败、需要检查 DOM 结构时使用。 |
Markdown 比纯文本更适合研究任务,因为它保留页面结构;但对于很长或很嘈杂的页面,Agent 应把 Markdown 保存到当前任务目录的 output/ 中,再读取或总结相关章节,而不是把整页原文直接发到微信对话。
text 是低输出量的简洁模式;管理脚本的 smoke test 也故意使用 --dump text,因为它只验证程序、权限和网络路径是否可用,不代表 PicoClaw 的默认调研输出格式。
2. 文件布局和权限
安装后增加以下文件:
/usr/local/bin/obscura
/usr/local/bin/obscura-worker
/root/obscura-manager.sh
/home/picoclaw/workspace/AGENT.md # 只追加调用规则
| 路径 | 权限 | 说明 |
|---|---|---|
/usr/local/bin/obscura | root:root,755 | Obscura 主程序。 |
/usr/local/bin/obscura-worker | root:root,755 | Worker,必须与主程序同目录。 |
/root/obscura-manager.sh | root:root,700 | 管理员专用的安装、更新、状态、回滚脚本。 |
AGENT.md | 保持 PicoClaw 原有权限 | 只增加 Obscura 后备规则。 |
PicoClaw 服务的 PATH 应已经包含:
Environment=PATH=/home/picoclaw/workspace/bin:/usr/local/bin:/usr/bin:/bin
因此安装到 /usr/local/bin 后,不需要修改 PicoClaw 服务单元、config.json 或源码。
3. 获取管理脚本
本文配套提供管理员管理脚本:obscura-manager.sh。
#!/usr/bin/env bash
# Obscura manager for a PicoClaw host.
# Commands: install | update | rollback | status | help
#
# PicoClaw research policy uses --dump markdown by default. This script's
# smoke test deliberately uses --dump text because it verifies only executable
# availability, permissions, network reachability, and basic rendered output.
set -Eeuo pipefail
IFS=$'\n\t'
umask 077
DIR='/usr/local/bin'
BIN="${DIR}/obscura"
WORKER="${DIR}/obscura-worker"
PREV_BIN="${DIR}/obscura.previous"
PREV_WORKER="${DIR}/obscura-worker.previous"
ASSET='obscura-x86_64-linux.tar.gz'
URL="https://github.com/h4ckf0r0day/obscura/releases/latest/download/${ASSET}"
SERVICE='picoclaw.service'
TMP=''
WAS_ACTIVE=0
fail() { echo "[ERROR] $*" >&2; exit 1; }
info() { echo "[INFO] $*"; }
cleanup() { [[ -z "$TMP" || ! -d "$TMP" ]] || rm -rf -- "$TMP"; }
trap cleanup EXIT
[[ "$(id -u)" -eq 0 ]] || fail 'Run as root.'
for c in curl tar find install timeout runuser grep sha256sum systemctl cp; do
command -v "$c" >/dev/null 2>&1 || fail "Missing command: $c"
done
stop_picoclaw() {
WAS_ACTIVE=0
if systemctl is-active --quiet "$SERVICE"; then
WAS_ACTIVE=1
info "Stopping $SERVICE temporarily..."
systemctl stop "$SERVICE"
fi
}
start_picoclaw() {
if [[ "$WAS_ACTIVE" -eq 1 ]]; then
info "Starting $SERVICE..."
systemctl start "$SERVICE"
systemctl is-active --quiet "$SERVICE" || fail "$SERVICE did not become active."
fi
}
prepare_latest() {
TMP="$(mktemp -d)"
archive="$TMP/$ASSET"
extract="$TMP/extract"
info 'Downloading GitHub Latest Release...'
curl --fail --location --proto '=https' --tlsv1.2 --connect-timeout 10 --max-time 180 --retry 0 -o "$archive" "$URL"
tar -tzf "$archive" >/dev/null
mkdir -p "$extract"
tar -xzf "$archive" -C "$extract"
NEW_BIN="$(find "$extract" -maxdepth 3 -type f -name obscura -print -quit)"
[[ -n "$NEW_BIN" ]] || fail 'obscura was not found in the archive.'
NEW_WORKER="$(dirname "$NEW_BIN")/obscura-worker"
[[ -f "$NEW_WORKER" ]] || fail 'obscura-worker was not found beside obscura.'
chmod 0755 "$NEW_BIN" "$NEW_WORKER"
info 'Candidate version:'
"$NEW_BIN" --version
}
deploy_latest() {
install -o root -g root -m 0755 "$NEW_BIN" "$BIN"
install -o root -g root -m 0755 "$NEW_WORKER" "$WORKER"
}
smoke_test() {
info 'Running a read-only smoke test as picoclaw...'
# Keep the smoke test minimal; Agent research defaults to --dump markdown.
output="$(mktemp /tmp/obscura-smoke.XXXXXX)"
if ! runuser -u picoclaw -- timeout 35s "$BIN" fetch 'https://example.com' --stealth --quiet --timeout 20 --dump text > "$output"; then
rm -f -- "$output"
return 1
fi
grep -qi 'Example Domain' "$output"
rm -f -- "$output"
}
restore_previous() {
[[ -f "$PREV_BIN" && -f "$PREV_WORKER" ]] || return 1
install -o root -g root -m 0755 "$PREV_BIN" "$BIN"
install -o root -g root -m 0755 "$PREV_WORKER" "$WORKER"
}
install_cmd() {
[[ ! -e "$BIN" && ! -e "$WORKER" ]] || fail "Already installed. Use: $0 update"
prepare_latest
stop_picoclaw
deploy_latest
if ! smoke_test; then
rm -f -- "$BIN" "$WORKER"
start_picoclaw || true
fail 'Installation failed the smoke test; new files were removed.'
fi
start_picoclaw
info 'Installation completed successfully.'
}
update_cmd() {
[[ -x "$BIN" && -x "$WORKER" ]] || fail "Not installed. Use: $0 install"
prepare_latest
stop_picoclaw
cp -f -- "$BIN" "$PREV_BIN"
cp -f -- "$WORKER" "$PREV_WORKER"
deploy_latest
if ! smoke_test; then
info 'Smoke test failed; restoring previous version...'
restore_previous || true
start_picoclaw || true
fail 'Update failed; previous version was restored.'
fi
start_picoclaw
info 'Update completed successfully.'
}
rollback_cmd() {
[[ -f "$PREV_BIN" && -f "$PREV_WORKER" ]] || fail 'No previous version is available.'
stop_picoclaw
stamp="$(date +%Y%m%d-%H%M%S)"
cp -f -- "$BIN" "${BIN}.failed-${stamp}"
cp -f -- "$WORKER" "${WORKER}.failed-${stamp}"
restore_previous
smoke_test || fail 'Rollback smoke test failed.'
start_picoclaw
info 'Rollback completed successfully.'
}
status_cmd() {
echo '=== Installed files ==='
ls -l "$BIN" "$WORKER" 2>/dev/null || true
echo; echo '=== Version ==='
"$BIN" --version 2>/dev/null || true
echo; echo '=== SHA-256 ==='
sha256sum "$BIN" "$WORKER" 2>/dev/null || true
echo; echo '=== Previous files ==='
ls -l "$PREV_BIN" "$PREV_WORKER" 2>/dev/null || true
echo; echo '=== PicoClaw service ==='
systemctl is-active "$SERVICE" || true
}
case "${1:-help}" in
install) install_cmd ;;
update) update_cmd ;;
rollback) rollback_cmd ;;
status) status_cmd ;;
help|-h|--help) echo "Usage: $0 {install|update|rollback|status|help}" ;;
*) fail "Unknown command: ${1:-}" ;;
esac
该脚本的特点:
- 从 GitHub
Latest Release下载当时最新版本; - 首次安装、手动更新、状态检查、回滚分别使用不同命令;
- 安装或更新时确认
obscura和obscura-worker同时存在; - 安装为
root:root、755; - 如果 PicoClaw 原本是运行状态,只在操作期间短暂停止,随后自动恢复;
- 以
picoclaw用户进行一次只读 smoke test; - 更新前保留一组上一版文件,便于回滚;
- 不创建 cron 自动更新、代理、MCP 服务或常驻浏览器服务。
将脚本上传到服务器 /root/obscura-manager.sh 后,以 root 执行:
sed -i 's/\r$//' /root/obscura-manager.sh
chmod 700 /root/obscura-manager.sh
bash -n /root/obscura-manager.sh
/root/obscura-manager.sh help
预期输出:
Usage: /root/obscura-manager.sh {install|update|rollback|status|help}
4. 首次安装当前最新版本
执行:
/root/obscura-manager.sh install
脚本会:
- 从 GitHub 的
releases/latest/download/下载当前 Latest Release; - 检查压缩包;
- 检查主程序与 worker 是否同时存在;
- 如果 PicoClaw 原本运行,暂时停止服务;
- 将两个程序安装到
/usr/local/bin/; - 以
picoclaw用户执行一次只读网页 smoke test; - 恢复 PicoClaw 服务;
- 输出版本、权限和 SHA-256。
安装完成后检查:
/root/obscura-manager.sh status
预期至少包含:
/usr/local/bin/obscura
/usr/local/bin/obscura-worker
active
5. 在 AGENT.md 中增加 Obscura 后备规则
在已有 PicoClaw 规则的末尾追加下面小节。它只授权一个受限的、只读、单页面的 Obscura 后备调用。
以 root 执行:
set -eu
AGENT=/home/picoclaw/workspace/AGENT.md
test -f "$AGENT"
if grep -qE '^[[:space:]]*#+[[:space:]]+Obscura JavaScript fallback[[:space:]]*$' "$AGENT"; then
echo "[ERROR] An Obscura policy section already exists in: $AGENT" >&2
echo "[INFO] Do not append a duplicate section. Review the existing policy instead." >&2
exit 1
fi
cat >> "$AGENT" <<'EOF'
# Obscura JavaScript fallback
- The administrator-approved `/usr/local/bin/obscura` command is the only
exception to the browser-automation, anti-detection, alternate-client, and
system-level-tool restrictions above. Do not install, copy, update, replace,
or modify it.
- It is allowed as a read-only, one-page fallback only after `web_fetch` and a
bounded `curl` GET/HEAD attempt cannot retrieve public-page content because
JavaScript rendering is required.
- First verify availability with `command -v obscura`. For research and
structured page reading, use:
`timeout 35s obscura fetch "<URL>" --stealth --quiet --timeout 20 --dump markdown`
- Use `--dump text` instead when the user needs only a concise answer, a small
set of facts, a quick compatibility check, plain text, or when the page is
likely too long or noisy for a useful Markdown result in the current chat.
- If a Markdown result is too long for a concise chat response, save it in the
current task directory's `output/` path, then read or summarize only the
relevant sections. Do not paste the full raw page into the chat.
- Do not use `--dump html` unless the user explicitly requests rendered HTML or
the Agent is diagnosing a content-extraction problem.
- Do not retry automatically, run concurrent Obscura requests, use a proxy,
start `serve` or `mcp`, submit forms, log in, upload data, or use arbitrary
JavaScript evaluation.
- If Obscura encounters a CAPTCHA, login requirement, HTTP 403, HTTP 429,
access restriction, DNS failure, or timeout, stop and report the limitation.
EOF
chown picoclaw:picoclaw "$AGENT"
chmod 600 "$AGENT"
echo '=== Obscura policy appended ==='
tail -n 34 "$AGENT"
最终允许的调用命令是:
timeout 35s obscura fetch "<URL>" --stealth --quiet --timeout 20 --dump markdown
| 参数 | 作用 |
|---|---|
--stealth | 使用 Obscura 的兼容性/反指纹模式。 |
--quiet | 抑制冗余日志。 |
--timeout 20 | 页面导航最多 20 秒。 |
外层 timeout 35s | 整个前台命令最多 35 秒,避免同一微信会话长期阻塞。 |
--dump markdown | 默认输出;适合调研,保留标题、段落、列表与链接语义。 |
--dump text | 仅用于简洁问答、事实提取、快速检查或过长/嘈杂页面。 |
--dump html | 默认禁止;只允许用户明确索取渲染 HTML,或排查内容提取故障时使用。 |
规则没有授权启动 serve、mcp、代理、批量抓取、登录、表单提交、上传数据或自动重试。
6. 重启 PicoClaw
这里只修改了 AGENT.md,没有修改 systemd unit 文件,所以不需要执行 daemon-reload。
systemctl restart picoclaw.service
systemctl is-active picoclaw.service
journalctl -u picoclaw.service -n 30 --no-pager
预期:
active
7. 验证 JavaScript 渲染
以 root 执行动态页面 smoke test。该测试故意使用 --dump text,因为它只验证程序、权限、JavaScript 渲染和网络路径;它不改变 Agent 默认使用 --dump markdown 的调研策略:
runuser -l picoclaw -c '
set -eu
out="$(mktemp /tmp/obscura-js-render-test.XXXXXX)"
trap "rm -f \"$out\"" EXIT
timeout 35s /usr/local/bin/obscura fetch "https://quotes.toscrape.com/js/" \
--stealth \
--quiet \
--timeout 20 \
--dump text > "$out"
test -s "$out"
echo "=== First 1500 bytes of rendered text ==="
head -c 1500 "$out"
printf "\n"
'
成功时会输出多条名言及作者,证明:
picoclaw 用户权限正常
→ Obscura 与 worker 可执行
→ JavaScript 渲染正常
→ 正文提取正常
→ 20 秒 / 35 秒限制正常
本文假设 PicoClaw 基础部署文章已包含
Environment=LANG=C.UTF-8。这是 PicoClaw 服务级 UTF-8 设置,
不会修改服务器的全局系统语言。如果你是从旧版部署升级,且原有
picoclaw.service尚未包含该行,
请按 PicoClaw 基础部署文章更新服务文件,并执行systemctl daemon-reload和systemctl restart picoclaw.service。
8. 微信端端到端测试
向微信 ClawBot 发送:
请访问 https://quotes.toscrape.com/js/ 。
先按正常网页抓取流程尝试;如果普通抓取无法取得正文且确实需要 JavaScript 渲染,则按当前规则使用 Obscura。
只回复前两条名言及其作者,不创建文件,不重试。
成功标准:
- 返回两条名言和作者;
- 不创建不必要的工作区文件;
- 不出现
command not found、权限或 worker 错误; - 不在同一微信会话中长时间卡住;
- 对公开动态网页成功返回正文,或在 35 秒内清晰报告失败原因。
9. Google、CAPTCHA 与受限站点
Google 搜索结果页可能返回异常流量挑战、CAPTCHA、HTTP 403 或其他访问限制。这不代表 Obscura、JavaScript 或 PicoClaw 安装失败。
建议的职责划分:
搜索发现:web_search
已知公开 URL:web_fetch / curl
JavaScript 动态正文:Obscura
验证码、登录墙、403、429、访问限制:停止并报告
不要通过循环请求、延长超时或更换长 URL 参数来处理访问挑战。这些做法不能改善正常访问能力,反而可能增加等待时间或触发更严格限制。
10. 更新、状态和回滚
更新到当前最新版本
/root/obscura-manager.sh update
更新前会保留当前版本:
/usr/local/bin/obscura.previous
/usr/local/bin/obscura-worker.previous
新版本安装后会再次以 picoclaw 用户运行 smoke test;失败时恢复上一版。
查看状态
/root/obscura-manager.sh status
回滚
/root/obscura-manager.sh rollback
回滚前的版本会保留为:
/usr/local/bin/obscura.failed-YYYYMMDD-HHMMSS
/usr/local/bin/obscura-worker.failed-YYYYMMDD-HHMMSS
不建议创建 cron 自动更新。对低配 VPS,更稳妥的做法是管理员需要时手动运行一次 update,确认 smoke test 与 PicoClaw 服务状态后再继续使用新版。
11. 备份和恢复说明
本文刻意不修改既有 PicoClaw 部署文章和既有 PicoClaw 备份脚本。
Obscura 是独立的系统级可选增强组件:
/usr/local/bin/obscura
/usr/local/bin/obscura-worker
/root/obscura-manager.sh
如果既有 PicoClaw 备份未覆盖这些路径,服务器恢复后可按本文重新部署 Obscura。建议将本文和配套管理脚本作为独立的安装、更新和恢复资料发布。
12. 最终检查清单
[ ] /usr/local/bin/obscura 存在,root:root,755
[ ] /usr/local/bin/obscura-worker 存在,root:root,755
[ ] /root/obscura-manager.sh 存在,root:root,700
[ ] /root/obscura-manager.sh status 可显示版本和服务状态
[ ] AGENT.md 已追加 Obscura JavaScript fallback 规则
[ ] picoclaw.service 为 active
[ ] picoclaw 用户可运行 Obscura 动态页面测试
[ ] 微信 Agent 可提取公开 JavaScript 页面正文
[ ] CAPTCHA、403、429、登录墙等限制会停止并报告
[ ] 未创建 Obscura 常驻服务、MCP 服务、代理或 cron 自动更新
参考资料
- Obscura 官方仓库:https://github.com/h4ckf0r0day/obscura
- Obscura 最新发布页:https://github.com/h4ckf0r0day/obscura/releases/latest
- PicoClaw 官方仓库:https://github.com/sipeed/picoclaw