M13 F2.3 · Playground Crawler

Playground Crawler

当 client-side crawl 力不从心时 — 服务端 Chromium 来做 DOM 扫描、pattern detection、screenshot 复查。

何时需要

Client-side crawl 不够用

JS-heavy SPA、late mount、动态内容、shadow DOM — 这时服务端 Chromium 上场。

  • JS-heavy SPA

    React/Vue/Angular 单页应用 — DOM 完全由 JS 渲染时。

  • Late mount

    初始 HTML 为空;2-5 秒后真实内容才挂载 — Chromium 可以等。

  • 动态加载 DOM

    Scroll + click + lazy load — 需要脚本交互才会出现的元素。

  • Shadow DOM

    Client-side 访问 web component shadow root 受限;服务端 Chromium 可穿透。

3 种 crawl 模式

Single · Multi · 仅截图

三种模式按需选择。Multi-page 从 CH events_canonical 拉取动态 URL 列表。

single_page

single_page

给一个 URL → DOM 扫描 + pattern detect + 截图。最快模式 — 适合 playground 预览。

multi_page

multi_page

CH events_canonical 最近 7 天 distinct source_context['context_url'] → 多页 crawl。在多页中寻找同样 pattern(总计数)。

screenshot_only

screenshot_only

整页 + viewport 截图,不做 DOM 扫描。用于 UX 复查 / regression。

6 策略 selector 生成器

分层 selector,auto-healing fail-safe

每个 event 拿到 6 种 selector 类型 — 一种断了,下一种顶上(5 层 fallback healing)。

为何 6 层?

前端改版可能毁掉 CSS class、ARIA label 或文本。除非 6 种同时断,否则 event tracking 持续工作。

  • dataAttrdata-* 属性 — 最稳(手动添加、dev 可控)
  • text可见文本 — i18n 变化时会断
  • cssCSS class / id — class refactor 时风险大
  • xpathXPath 表达式 — 依赖 DOM 层级
  • regex属性 regex 匹配 — 基于 pattern
  • ariaARIA role + label — 可访问性级别,相对稳定
// 6 strateji, en spesifikten en gevşeğe doğru
{
  "selectors": [
    { "type": "data_attr", "value": "[data-testid='cart-add']" },
    { "type": "aria",      "value": "[role='button'][aria-label='Sepete ekle']" },
    { "type": "text",      "value": "button:has-text('Sepete ekle')" },
    { "type": "css",       "value": ".product-card .add-to-cart" },
    { "type": "xpath",     "value": "//button[contains(., 'Sepete ekle')]" },
    { "type": "regex",     "value": "button[name=~'add.cart']" }
  ]
}

Pattern detection

1,248 个购物车按钮 → 一个 event

自动聚合同样设计的重复元素 — 一条 event 定义覆盖所有页面。

如何聚合?

按 selector + 相邻 DOM 结构 + accessible label 相似度聚类。一个 cluster 中的所有元素绑到同一个 event。

# Multi-page crawl → 1.248 add-to-cart noktası bulundu
gurulu playground crawl \
  --mode multi_page \
  --base https://shop.example.com \
  --discover ch_events_last_7d \
  --max-pages 200

# Sonuç: pattern grouping (eşleşen selector → tek event'e bağla)
# event:add_to_cart  →  matched 1.248 instances across 47 pages

截图复查

MinIO presigned + 缩略图

Crawl 之后,每个页面截图写入 MinIO;API 返回 302 redirect 到 presigned URL。

GET /v1/playground/crawl/{crawl_id}/screenshot
  → 302 redirect → MinIO presigned URL (15 dk TTL)

# Thumbnail (JPEG, dashboard list için)
GET /v1/playground/crawl/{crawl_id}/screenshot?variant=thumb

访问控制

Presigned URL 带 15 分钟 TTL — 先检查 workspace 权限,再重定向到 MinIO bucket。Dashboard 缩略图是 JPEG。

性能配置

Browser pool 2、timeout 30s、shm 1gb

Chromium SHM 段 1 GB — Docker 默认 shm_size 64 MB 不行,必须覆盖。

设置
默认
备注
Browser pool size
2
并发 Chromium 实例 — 2 稳定;更多会吃 RAM。
页面 timeout
30 s
DOM 未就绪 30s 后失败。对 SPA 足够。
shm_size
1 GB
Docker SHM 1 GB — 防止 Chromium 崩溃。64 MB 默认不行。
Job 并发
1 job / worker
每个 worker 1 个 job — 控制 Chromium 内存泄漏风险。

使用场景

Onboarding + 发现

两个典型场景 — 新 workspace 设置和已有 workspace 中发现新 pattern。

Onboarding playground

新 workspace 设置:从 sessions 列表点「scan multi-page」按钮,在每个页面检测 pattern 并批量创建 events。

Pattern 发现

上线后已有 workspace 中 — 从 playground 跑一次 multi-page crawl 找出新元素并加入 event registry。

相关文档

下一步阅读

从 pattern 构建受众、在 AI 摘要中查看出现的 pattern、了解架构。

Playground Crawler — Gurulu 文档