跳转至

ISSUE-0084:抓取响应内容丢失 — 反爬识别无法迭代规则

现象 / 用户反馈

用户问:"网站输出内容少于多少字,记录内容(markdown 格式前 300?)便于分析反爬"

痛点

当前 SPEC-004 Phase 1 pipeline 命中可疑场景时只记 mstage 标签,丢弃原始 body:

场景 当前记录 缺失信息
fetch-too-small (< 1KB) mstage:fallback/fetch-too-small@fetch — too-small:823 是 SPA 壳?404 软文?反爬空页?
antibot-body mstage:fallback/antibot-body@fetch — challenge:just a moment 反爬变体内容?上下文?
contact-keyword-but-empty mstage:fallback/contact-keyword-but-empty@extract 页面提 contact 但抓不到 — 正则漏了什么?

后果: - 不能事后分析"为什么这个网站采不到" - 不能积累反爬样本派生新 marker - 不能上云聚合(云端没原始数据可分析) - 用户主观感受:「日志只说失败了,没说为什么」

已有但未用的数据

website-fetcher.ts:101 已经把 html 带回上层:

return {
  kind: 'too-small',
  html,  // ← 已经在 fetcher 里抓到了
  byteLength,
  ...
};

但 caller 只看 kind/reasonhtml 字段被丢弃

修复(v0.10.121 — 完整 SPEC-007)

客户端 6 件套

  1. jsstore 新表 FetchSnapshots(version 5)
  2. fetch-snapshot.ts — write/query/clear + sanitizeBodyPreview 脱敏 helper
  3. website-scrape-pipeline.ts 3 处分支命中时 fire-and-forget 写快照
  4. log-view 加「响应快照」tab + 导出 Markdown
  5. Settings 3 toggle
  6. enableFetchSnapshot(默 true)
  7. fetchSnapshotSanitize(默 true — 脱敏 emails/phones/csrf/bearer)
  8. fetchSnapshotMaxChars(默 300)
  9. 存储策略:200 条上限按 domain 唯一性环形淘汰

脱敏(4 层)

function sanitizeBodyPreview(raw, maxChars) {
  // 1. emails → <REDACTED:email>
  // 2. phones (含分隔符 7-15 位) → <REDACTED:phone>
  // 3. csrf_token / authenticity_token / api_key → <REDACTED:secret>
  // 4. Bearer / Basic auth → <REDACTED:secret>
  // 5. 截到 maxChars,不在 < 中间断
}

服务端(未实施)

SPEC-007 起草 3 个 endpoint: - POST /api/v1/fetch-snapshots/batch — 上传 - GET /api/v1/fetch-snapshot/rules — 拉派生规则 - DELETE /api/v1/fetch-snapshots/all — GDPR 撤回

验证

  • 装 v0.10.121 后:
  • 启用「多阶段抓取」+「响应快照」(默认 ON)
  • 跑一次抓取
  • 打开 日志 → 响应快照 tab
  • 应看到 200 条上限的快照,按 domain 去重
  • 点击行看完整 preview(已脱敏)
  • 「导出 Markdown」生成报告,可贴 issue

教训

  • 数据缺失反过来推不出规则 — fetcher 已经拿到 body,丢弃是浪费
  • 共享池要有原始证据 — ContactPool 共享结果,FetchSnapshots 共享原因,缺一不可
  • 脱敏先于上云 — 客户端 + 服务端双 enforce
  • 观察先于优化 — 没有快照就没办法知道反爬第 15 种 marker 是什么