Files
FacereDataset/docs/plans/oshwhub_batch50.md
Knowit eee1a9b97e crawler: --skip-ext + --max-source-mb gates for batch-50 expansion
Two CLI gates needed before scaling Pro batch beyond top-5:

--skip-ext mp4,qt,mov  (attachment filter)
  Skips video extensions in attachment download. Phase 1 measurements
  showed mp4+qt occupy ~54% of attachment storage. Entry still recorded
  in metadata.json with skipped:ext:<token> so we can re-fetch later if
  the policy changes. Honors both server-declared `ext` and filename
  suffix, case-insensitively.

--max-source-mb N  (Pro source size cap)
  Trips inside the chain replay loop on encrypted-blob total. On trip:
  raise ProjectOversizeError, wipe partial source/, append a row to
  data/state/oshwhub_pro_oversize.jsonl. Lets us shortlist 50+ Pro
  projects without one X86-board-class outlier (~500 MB) blowing the
  LFS budget. Std and Pro 2.x legacy are not capped (both <2 MB in
  sample).

Verified:
  - cap=0 trips on first blob (1.2 MB), source/ wiped, state recorded
  - cap=100 runs full ESP-VoCat (7.5 MB plain, 278 docs)
  - skip-ext microtest: 8/8 cases (case-insensitive, declared/suffix
    fallback, empty-token edge cases)

Plan + frozen candidate list for the next 50 projects:
  - docs/plans/oshwhub_batch50.md
  - data/state/oshwhub_batch50_candidates.jsonl (gitignore exception added)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 00:24:55 +08:00

7.6 KiB
Raw Permalink Blame History

oshwhub 扩抓批 50执行计划

创建2026-04-29 目标:在已落库的 15 项5 Pro + 10 Std基础上再抓 50 个高质量项目 候选清单data/state/oshwhub_batch50_candidates.jsonl50 行) 承接docs/sources/oshwhub_listing_full.md(全量索引盘点)


1. 目标

  • 把 corpus 从 15 项扩到 65 项,覆盖 Pro + Std + Pro 3.x + Pro 2.x 各形态
  • 在 LFS 1 TB 红线内,先做 ~3-4 GB 量级的中等规模验证
  • 结束后用 license 白名单评估这 50 项里有多少能进 Forge 投影
  • 暴露 ≥ top-5 才会出现的 corner case例如超大 Pro 项目、私有附件、跨账号 fork

显式不做详情页全量扫描19h 工作量,留待后续按 A 档全池一次性做);下游 KiCad 转换Phase 3 还在做)。


2. 候选池筛选标准

数据源:data/state/oshwhub_listing_full.jsonl33,695 项全量 listing 索引)

硬过滤

  • grade >= 3 AND like >= 10A 档)
  • uuid 不在已抓 15 项内

排序:复合质量打分

score = like*3 + star + fork*2 + views/100 + comments_count*2 + grade*50

多样性约束

  • 单作者上限 2 个项目(避免 course-examples / 45coll 等高产账号占满)
  • Pro / Std 25:25 平衡Pro 是新平台增长焦点Std 是 7 年质量积累)

3. 选出的 50 项概况

维度
总数 5025 Pro + 25 Std
唯一作者 43
Max 单作者 2
like 区间 min=246 / median=554 / max=2137
view 区间 min=54k / median=117k / max=362k
grade 分布 4: 33 项, 3: 17 项

Pro 头部(前 5HelloWord-Keyboard 2137 likes / STM32 桌面宠物 / OV-Watch 智能手表 / mini 加热台 / ESP-SparkBot

Std 头部(前 5触摸调光雪花灯 1036 likes / 桌面可调电源 / 立创 EDA PCB 直尺 / 自平衡莱洛三角 / PN532 NFC

完整名单见 data/state/oshwhub_batch50_candidates.jsonl


4. 执行步骤

Step 0 — 候选池冻结

data/state/oshwhub_batch50_candidates.jsonl 已生成,作为本次批的"事实档案"。后续就算重排序也以这份为准。

Step 1 — 详情页抓 license~5 minQPS=0.5

只对这 50 项扫详情页,提取 license / 完整 attachments 列表 / 原始描述。 不在这一步下载附件、不下源工程,只是获取每项的 metadata 全集

PYTHONUNBUFFERED=1 uv run python -u -m crawlers.oshwhub \
  --uuids "$(jq -r .uuid data/state/oshwhub_batch50_candidates.jsonl | paste -sd,)" \
  --no-files \
  --out data/raw/oshwhub

目前 crawl_one 已经会落 metadata.json + description.md + cover--no-files 跳过附件。

预期产出50 个 data/raw/oshwhub/<uuid>/metadata.json,含 license 字段。

Step 2 — license 分布盘点

写个一次性脚本读 50 份 metadata.json统计 license 分布。这一步只做盘点不做过滤——按 CLAUDE.md "研究用、不分发" 原则,所有 license 都入库。下游 Forge 投影时再用白名单过滤。

uv run python - <<'EOF'
import json, glob, collections
licenses = collections.Counter()
for p in glob.glob("data/raw/oshwhub/*/metadata.json"):
    m = json.load(open(p))
    if m["uuid"] in batch_50_uuids:
        licenses[m.get("license") or "<none>"] += 1
print(licenses)
EOF

预期会有大量 NC-SA / GPL参考已抓 5 Pro5/5 都是 GPL/NC-SA

Step 3 — Pro 子集预检 + 抓源(~30-60 min

25 个 Pro 项目里要先判 3.x vs 2.xbranch_uuid 是否 null然后对应走 modern / legacy 路径:

PYTHONUNBUFFERED=1 uv run python -u -m crawlers.oshwhub \
  --backfill-pro-source \
  --uuids "$(jq -r 'select(.origin=="pro") | .uuid' \
              data/state/oshwhub_batch50_candidates.jsonl | paste -sd,)" \
  --pro-cookie ~/.secrets/pro-lceda-cookie-header.txt

时间预算(已应用 chain replay sleep 优化commit 1e06ba6

  • 小型项目chain ~10~30s 各
  • 中型chain ~30-50~1-2 min 各
  • 大型chain ~100+~3-5 min 各
  • 超大X86 量级 chain ~700~3-5 min 各CDN 部分降到 0.2s/req

按已抓 5 项观察,预期 25 项里:

  • ~22 个 Pro 3.xchain replay
  • ~3 个 Pro 2.xplaintext dataStr

Step 4 — Std 子集抓源(~30 min

PYTHONUNBUFFERED=1 uv run python -u -m crawlers.oshwhub \
  --backfill-source \
  --uuids "$(jq -r 'select(.origin=="std") | .uuid' \
              data/state/oshwhub_batch50_candidates.jsonl | paste -sd,)"

每项 ~30sQPS=0.2 / 5s sleep × 几个 API 调用25 项 ≈ 12-15 min。

Step 5 — 附件下载(按需,可选)

附件Gerber / STEP / PDF / 视频)默认存 LFS但视频占大头之前 Phase 1 实测 mp4+qt 占 54%)。 建议加 --skip-ext mp4,qt,mov 节省 30-50% 体积。

PYTHONUNBUFFERED=1 uv run python -u -m crawlers.oshwhub \
  --uuids "$(jq -r .uuid data/state/oshwhub_batch50_candidates.jsonl | paste -sd,)" \
  --out data/raw/oshwhub
  # 注:当前 crawler 没有 --skip-ext 选项;要加得改 crawl_one如果偷懒就先全抓再人工删

这一步没那么紧迫,可以挪到 Step 3/4 完成后单独跑。

Step 6 — 验收 + 记录

scripts/build_index.py 重建 projects.md,更新 log.md,把统计信息写到 docs/plans/oshwhub_batch50.md 末尾"实施结果"段。


5. 资源预算

估算 备注
API 调用 ~600 次 50 详情 + 25×3 Pro meta + 25 Std API + chain blobs
时间 ~1.5-2 小时 远低于之前估算的 19h因为只 50 项 + sleep 优化)
存储(源工程) ~1.5 GB Pro 平均 30 MB、Std 平均 15 MB
存储(附件,估) 2-3 GB 含视频;不含视频估 1 GB
总 LFS 增量 ~3-4 GB 远低于现有 LFS 余量
网络下行 ~4 GB 大部分走 LFS

距离 200 GB"对象存储迁移决策点"还很远。


6. 风险与预案

风险 概率 影响 预案
Pro cookie 过期半路 卡住 Pro 抓取 重抓 cookie爬虫已有 oshwhub_pro_failed.jsonl 重试机制(未实现,现在失败只 stderr
单个 Pro 项目超大X86 量级 ~500 MB LFS 单项膨胀 设置 size cap超过 200 MB 跳过 + 记 state
license 全是 NC-SA → 下游 Forge 投影门槛低 Forge 阶段才发现 提前在 Step 2 盘点;本批不做过滤,只入库
某个项目附件含 mp4 视频 → 附件总量爆炸 多消耗 1-2 GB LFS --skip-ext mp4,qt,mov 选项(需小改 crawler
抓 50 项过程中触发反爬 / 限流 中途中断 已有 5s/req QPS如果触发加 jitter从中断点续

7. 验收标准

  • data/raw/oshwhub/ 下新增 ≥ 45 个项目目录(允许 ≤ 5 项失败)
  • 每个新增项目的 metadata.jsonlicensesource_formatsource_path
  • Pro 25 项里 3.x / 2.x 分类正确(看 source_format 字段)
  • LFS 增量 ≤ 5 GB
  • projects.md 自动重建后包含新 50 项
  • log.md 顶部一条总结性日志

8. 后续

成功结束后的下一步候选:

  1. license 详情扫描全 A 档 —— 把 license 信息覆盖到 2,806 项 A 档候选池,为下一次扩抓提供过滤条件
  2. 扩抓批 200(按 license 白名单 + 同样多样性策略)
  3. Pro 工程二进制图IMAGE/)补抓 —— 当前的真实数据 gap要不要补取决于下游需求
  4. 风控压测 —— 在某一批做并发提速试验,找 oshwhub / pro.lceda.cn 的限流真上限