10 KiB
立创开源平台抓取 → Forge 接入 spec
Date: 2026-04-23 给: 同学爬 oshwhub.com / 立创开源广场 目的: 爬回来的数据按这份 spec 整理,我们直接批量接入 Forge 的 BoardReference corpus。
1. TL;DR — 你交付的目标形态
每个项目一个目录,三件套:
<project_id>/
├── schematic.kicad_sch # ← 我们主要吃这个:KiCad 7+ S-expression 格式
├── manifest.json # ← 项目元数据(见 §4)
└── source/ # ← 可选:原 EasyEDA 文件归档(.json / .epro 等)
命名: project_id = oshwhub_<oshwhub数字ID>_<slug>,纯小写下划线。
例:oshwhub_1234567_esp32_bluepill_clone。
交付: tar.gz 或 git repo 都行。放在我们能访问的路径;我们自己跑批量 migrate。
2. 硬性前置条件 —— 任何一条不满足就跳过这个项目
2.1 License 白名单(关键!)
仅抓这些许可的项目:
- MIT / BSD-2-Clause / BSD-3-Clause / Apache-2.0
- CC0-1.0 / CC-BY-4.0 / CC-BY-3.0
- CERN-OHL-P-2.0(permissive 变体)
- Unlicense / public domain
必须拒掉的:
- CC-BY-SA(share-alike,会污染我们 corpus——大比例立创项目是这个!务必过滤)
- GPL / LGPL / AGPL 全家
- "未声明 license" / "All rights reserved"
- CC-BY-NC(禁商用)
立创项目页面上会显示许可名。你的爬虫要先读许可、后抓文件——许可不合格直接跳过,节省带宽。
2.2 文件格式
必须有 KiCad 7+ 格式的 .kicad_sch:
- 文件首 20 字节包含
(kicad_sch - version 声明 ≥ 20210621(早于这个版本 KiCad 10 加载会 warning 一大堆)
如果项目只有 EasyEDA 原文件:
- 用
easyeda2kicad工具转(pip install easyeda2kicad) - 或者立创 EDA Professional 的"导出 KiCad"功能
- 转完后必须验证能被 kicad-cli 加载(见 §6 自测)——转不出来就跳过、不要硬塞
2.3 基本质量
- 至少 5 个元件(太简单的 breadboard prototype 没参考价值)
- 不超过 300 元件(太大的我们暂时不处理)
- 不是纯 footprint 测试板(没电气连接)
3. schematic.kicad_sch 的要求
原样保留,不改、不格式化、不重新生成。我们的 corpus 依赖字节级完整保留才能做零漂移 byte-copy render。
如果你用 easyeda2kicad 转换:
- 转一次、存盘、不要后续再处理
- 多 sheet 项目:把主 sheet 存为
schematic.kicad_sch,其它 sheet 存为sheets/<name>.kicad_sch(我们暂时只消费根 sheet,但不要删其它——留着我们以后升级)
4. manifest.json 格式
必填字段:
{
"project_id": "oshwhub_1234567_esp32_bluepill_clone",
"source_platform": "oshwhub",
"source_url": "https://oshwhub.com/username/esp32-bluepill-clone",
"source_author": "username",
"title": "ESP32 Blue Pill 克隆",
"description": "一行到三行描述。可以直接从项目页面抓。双语都抓最好(en + zh),至少一个。",
"description_zh": "中文描述 (如果有)",
"license": "MIT",
"license_source": "https://oshwhub.com/username/esp32-bluepill-clone/license",
"license_verified": true,
"components_used": ["ESP32-WROOM-32", "AMS1117-3.3", "USB_B_Micro", "C", "R", "LED"],
"file_checksum_sha256": "abc123...",
"file_size_bytes": 178825,
"kicad_sch_version": "20230121",
"crawl_timestamp": "2026-04-23T10:00:00Z",
"converted_from": "easyeda",
"conversion_tool": "easyeda2kicad 0.8.2",
"tags_raw": ["esp32", "dev_board", "usb"]
}
字段说明:
source_url:立创开源那个 project 的页面 URL。我们保存做 provenance。license:必须是 §2.1 白名单里的字符串之一。抓不准就跳过,宁缺毋滥。license_source:license 是从哪读到的(页面、LICENSE 文件、README)。方便我们事后验。components_used:从 sch 里或从 EasyEDA 原 BOM 抓。用于后续 tag 派生——越全越好。file_checksum_sha256:sha256 ofschematic.kicad_sch。dedupe 用。converted_from/conversion_tool:原生 KiCad 的项目写"converted_from": "native";EasyEDA 转来的写具体工具和版本。tags_raw:立创页面上那个项目自带的标签/分类。原样塞。我们这边有一个 enrich 管线会基于components_used+description再派生更细的 tag(has_mcu / chip_tp4056 / use_portable...),你不用管这一步。
可选但有用:
source_easyeda_json_path: 原 EasyEDA 文件的路径(如果你归档到source/下的话)commit_sha/version: 如果立创项目有版本号star_count/fork_count: 作为后续 quality 排序参考
5. 目录结构示例
batch_20260423/ # 你一次交付的批次目录
├── README.md # 批次元数据(数量、时间、任何 caveat)
├── BATCH_MANIFEST.json # 机器可读的批次清单(见 §5.1)
│
├── oshwhub_1234567_esp32_bluepill/
│ ├── schematic.kicad_sch
│ ├── manifest.json
│ └── source/
│ └── schematic.json # 原 EasyEDA
│
├── oshwhub_2234568_tp4056_charger_v2/
│ ├── schematic.kicad_sch
│ ├── manifest.json
│ └── source/
│ ├── schematic.json
│ └── pcb.json
│
├── oshwhub_3234569_audio_preamp/
│ ├── schematic.kicad_sch # 原生 KiCad,无 source/
│ └── manifest.json
│
└── ... (N 个项目)
5.1 BATCH_MANIFEST.json
让我们能一键扫批次:
{
"batch_id": "batch_20260423",
"created_at": "2026-04-23T12:00:00Z",
"total_projects": 153,
"by_license": {
"MIT": 87,
"CC-BY-4.0": 34,
"Apache-2.0": 20,
"CC0-1.0": 12
},
"projects": [
"oshwhub_1234567_esp32_bluepill",
"oshwhub_2234568_tp4056_charger_v2",
...
]
}
6. 自测 checklist(你交付前跑一遍)
对每个 <project_id>/ 跑这 4 个检查,任一失败就把这个项目踢出批次:
# 1. .kicad_sch 首字节对头
head -c 20 <project_id>/schematic.kicad_sch | grep -q "(kicad_sch" || echo FAIL_1
# 2. 版本 ≥ 20210621
grep -oE "version \d{8}" <project_id>/schematic.kicad_sch | head -1
# expect 20210621 或更大
# 3. 能被 kicad-cli 加载(这一步最关键,catch 掉所有转换失败)
kicad-cli sch export netlist <project_id>/schematic.kicad_sch \
-o /tmp/test.net 2>&1 | grep -qi "error\|失败" && echo FAIL_3
# 4. manifest.json 合法且必填字段齐
python3 -c "
import json, sys
m = json.load(open('<project_id>/manifest.json'))
required = ['project_id', 'source_url', 'license', 'components_used', 'file_checksum_sha256']
missing = [k for k in required if k not in m or not m[k]]
if missing:
print('FAIL_4 missing:', missing)
sys.exit(1)
"
把每个项目的检查结果写进 BATCH_MANIFEST 或单独一个 failed/ 子目录归档。交付前所有 4 个检查都要过。
7. 已知坑 & 建议
7.1 立创开源的 license 现实
经验数据(不保证准确):
- 立创项目里可能 50%+ 是 "CC-BY-SA 4.0",这是默认选项 → 我们直接拒
- 大概 20-30% 是 "未声明 license" → 拒
- 10-15% 是 MIT / Apache / CC0 → 要!
- 少量 GPL → 拒
预期 hit rate: 你抓 1000 个项目可能只有 150-250 能通过 license 关卡。这是正常的,不要为了数量降低许可标准。
7.2 EasyEDA → KiCad 转换质量
easyeda2kicad.py 对大部分项目能用,但:
- 自定义 symbol(立创 SZLCSC 专有库)可能转不过来 → 转完 kicad-cli 加载会 fail → 被 §6 check 3 过滤掉
- 多 sheet hierarchy 偶尔乱 → 只保根 sheet 也能用
- footprint 转换常有问题——我们暂时不在乎 footprint(corpus 主要消费 schematic),转不过就空着
7.3 描述文字
立创项目标题和描述常常中英混杂 + markdown 标记 + emoji。原样保留没关系,我们的 enrich 管线会 strip markdown。但别主动翻译或改写 —— 原文有最多信息。
7.4 同项目多版本
立创有的项目带版本(v1 / v2 / Rev.B)。不同版本视作不同项目,分别抓、分别起 project_id。不要合并。
7.5 电气图多页
立创项目经常一个 sch 项目分多页(root + mcu_sheet + power_sheet 等)。你遇到时:
- 如果 easyeda2kicad 能转出层级结构 → 主 sheet 存
schematic.kicad_sch,子 sheet 存sheets/<name>.kicad_sch - 如果只导出根 sheet → 根 sheet 存
schematic.kicad_sch,在manifest.json加"has_unsaved_subsheets": true标记 - 转不出来 → 跳
8. 交付后我们会做什么(你不用担心这部分)
参考、别去实现:
batch_migrate_oshwhub.py扫整个批次,逐个board_ingest_from_file入 corpus- License 白名单再 double-check 一遍(防你漏过)
- sha256 dedupe(跨批次)
enrich_tags.py跑一遍基于components_used+description生成 chip_* / has_* / use_* tag 家族- 用 kicad-cli 跑 ERC 取
source_erc_status,脏的标记一下但仍入库(用户能看到警告)
9. 测试批次建议
第一次交付先给小批 5-10 个项目,覆盖:
- 3-5 个 MIT/Apache 原生 KiCad
- 2-3 个 CC0/CC-BY-4.0 从 EasyEDA 转的
- 1-2 个你不确定的 edge case(多 sheet、异常元件等)
我们跑一遍 ingest,给你反馈"格式上还要改啥" / "这块数据不够",再开始量产爬。
10. 联系点
- 这份文档的源头:
hardware_agent_docs/OSHWHUB_INGEST_SPEC.md - 我们的 BoardReference schema 定义:
src/facere/references/schema.py - 已有的 ingest 入口:
src/facere/references/board_ingest.py - 批量 migrate 脚本参考:
benchmarks/corpus_build/migrate_raw_to_board_refs.py
有问题直接问我(张大佬)—— 格式细节比速度重要,不清楚的先对一下再做。