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

197 lines
7.6 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.
# oshwhub 扩抓批 50执行计划
**创建**2026-04-29
**目标**:在已落库的 15 项5 Pro + 10 Std基础上再抓 50 个高质量项目
**候选清单**`data/state/oshwhub_batch50_candidates.jsonl`50 行)
**承接**`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.jsonl`33,695 项全量 listing 索引)
**硬过滤**
- `grade >= 3 AND like >= 10`A 档)
- `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 全集**。
```bash
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 投影时再用白名单过滤。
```bash
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.x`branch_uuid` 是否 null然后对应走 modern / legacy 路径:
```bash
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
```bash
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% 体积。
```bash
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.json``license``source_format``source_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 的限流真上限