# FacereDataset 爬取与建设计划 **维护**:Charles **最近更新**:2026-04-23 **状态**:Phase 0 已完成(仓库骨架),Phase 1 待启动 --- ## 总体策略 **先广度后深度,先合规后规模。** 1. 每个数据源先做一份 "可行性调研"(一页纸,放 `docs/sources/.md`),明确:访问形式、速率限制、许可证分布、ToS 摘要、数据字段覆盖。 2. 每个站点实现一个最小 MVP 爬虫,**单项目跑通** → 然后才全量化。 3. 全量化之前先对齐抽样结果与存储开销。 4. 所有站点输出统一到 `schemas/project.schema.json` 定义的结构,不要让下游消费者去适配 N 种 schema。 --- ## Phase 0 — 仓库骨架 ✅ - [x] `README.md` / `CLAUDE.md` / `plan.md` / `log.md` - [x] 目录骨架 `crawlers/ schemas/ scripts/ data/ docs/` - [x] `.gitignore`(排除 derivative 目录)/ `.gitattributes`(LFS 规则) - [x] 初始提交并推送 --- ## Phase 0.5 — 基础设施 / 运行环境 **目标**:把爬取从本地 dev 机迁到专用云服务器(广州,已规划),集中管理登录凭据、磁盘和长跑任务。 ### 0.5.1 云服务器初始化(待机器到位) - [ ] 机器规格确认(CPU / 内存 / 磁盘初始容量;广州可用区) - [ ] 基础环境: - [ ] 系统升级 + 防火墙 - [ ] 安装:`git`, `git-lfs`, `uv`, `python 3.11+`, `jq`, `curl` - [ ] 创建非 root 用户 + SSH key(不允许密码登录) - [ ] 克隆仓库:`git clone https://git.deepknow.site/Facere/FacereDataset.git ~/repo/FacereDataset` - [ ] `git lfs install` + 配置 Gitea 带 token 的 remote - [ ] `uv sync` 安装依赖 - [ ] 凭据目录:`~/.secrets/` (mode 700),放 Gitea token、oshwhub cookie、其它登录态 - [ ] 写 `docs/infra.md` 记录主机 ID、用户、路径、端口开放情况(**不**含凭据值) ### 0.5.2 调度 - [ ] 单次长跑:`tmux` / `nohup` + 输出落 `~/logs/-.log` - [ ] 定期增量:`systemd timer`(优先)或 `cron`,每周扫新增 / 更新 - [ ] 磁盘监控:` df -h | cron` 告警阈值 80% ### 0.5.3 登录态获取(按站点) - [ ] oshwhub / u.lceda.cn:用浏览器登录后导出 cookie → 转 `~/.secrets/oshwhub-cookies.txt`,httpx 通过 `cookies=` 注入 - [ ] 换号 / 重登事件记到 `docs/secrets.md`(只写事件,不写值) --- ## Phase 1 — 立创开源平台(oshwhub.com)MVP ✅ 首批完成 **目标**:跑通 10 个项目的完整抓取,验证 schema。 **实际**:10/10 成功,52 附件,524 MB 入 LFS。 ### 1.1 调研 ✅ - [x] 列表 API `/api/project?page=N&pageSize=M&sort=hot`(无鉴权) - [x] 详情页 SSR HTML 嵌入 escaped JSON,含 attachments 数组与 license - [x] 附件 CDN `image.lceda.cn/{src}` 直连 - [x] `docs/sources/oshwhub.md` 调研笔记 ### 1.2 爬虫 MVP ✅ `crawlers/oshwhub/crawler.py`: - [x] 列表分页 + 质量打分排序 - [x] HTML 解析:title / description / license / attachments - [x] 每项目目录:metadata / description / cover / files / _urls - [x] QPS ≤ 0.5,UA 真实声明 ### 1.3 验收 ⏳ - [x] 10/10 成功,产出符合 `schemas/project.schema.json` - [ ] **待人工**:随机抽查 2-3 条对照原站 - [ ] `scripts/validate.py` 自动 schema 校验(未写,后续补) ### 1.4 放量(待决策) - [ ] 定目标规模:50 / 500 / 5000 / 全量 12493 - [x] 实测规模分布(见 `docs/sources/oshwhub.md` §5): - median/proj 9 MB → 全量 **~110 GB**(合理预算) - p90 上界 **660 GB** - mp4+qt 视频占 54% → 加 `--skip-ext mp4,qt` 可省一半 - [ ] **存储分级**(按规模演进): - **Phase 1.x 前期(< 50 GB)**:直接落云服务器磁盘,`git-lfs push` 到 Gitea - **放量中期(50 – 200 GB)**:Gitea LFS 容量压力评估;可选方案 (a) 服务器挂载大盘扩容,(b) 分批 push 分仓(按月 / 按 grade 档位切仓库) - **放量后期(> 200 GB)**:迁移到**网盘 / 对象存储**(候选:阿里云 OSS、腾讯 COS、MinIO 自建),Gitea 只存 metadata + 指针 - [ ] 选型决策点:达到 50 GB 时评估,**不**过早迁移 - [ ] 增量更新:`updated_at` 变动检测 + LFS prune 策略(未实现) - [ ] 登录态工程源(u.lceda.cn EasyEDA JSON)现在纳入范围,见 §1.6 ### 1.6 登录态工程源抓取(u.lceda.cn) **目标**:拿到立创 EDA 的**真正工程源 JSON**(含原理图、PCB、组件数据),而不只是用户附件。是训练数据质量的关键升级。 - [ ] 在广州云服务器上用合法账号登录 oshwhub / EasyEDA,导出 cookie - [ ] 探明 `u.lceda.cn/api/...` 的项目源下载端点: - `/api/projects` 返回 401(需 session)——登录后试 - 可能的端点:`/api/project/`、`/api/document//source` - [ ] 扩展 `crawlers/oshwhub/crawler.py`: - `--with-source` 开关触发登录态抓取 - 把工程源 JSON 存到 `data/raw/oshwhub//source.json`(LFS) - schema 加 `source_format: "easyeda"` 字段 - [ ] 账号速率更保守:登录态 QPS ≤ 0.2,避免被封号 ### 1.7 立创 EDA → KiCad 格式转换 **目标**:把 `source.json`(立创 EDA / EasyEDA 格式)批量转成 KiCad 原生格式(`.kicad_sch` + `.kicad_pcb` + 可选 `.pretty` 库),打通 oshwhub(EasyEDA 生态)与 `bshada/open-schematics`(KiCad 生态)的统一训练语料。 **预选工具**:[`easyeda2kicad`](https://github.com/uPesy/easyeda2kicad.py)(pypi 包,活跃维护) - 支持 EasyEDA → KiCad 6/7/8 symbol / footprint / 3D model 转换 - 可能需要扩展以支持整个 project JSON → `.kicad_pro` + 关联文件 - [ ] 调研 `easyeda2kicad.py` 的整工程转换能力;若只支持单符号 / 封装,评估是否需要自写 orchestrator - [ ] 写 `scripts/convert_to_kicad.py`: - 输入:`data/raw/oshwhub//source.json` - 输出:`data/processed/oshwhub//kicad/` 下的 `.kicad_sch`、`.kicad_pcb` 等 - 支持批处理:`--input data/raw/oshwhub/ --output data/processed/oshwhub/` 扫全目录 - 失败样本落 `data/state/convert_failed.jsonl`(记 uuid + 原因) - 转换后跑 KiCad CLI `kicad-cli sch erc` / `pcb drc` 做语法校验 - [ ] 产出统计:转换成功率、常见失败模式,反馈到工具选型 - [ ] 运行:云服务器定期批处理(每次爬完新项目后跑) ### 1.5 纳入第三方预处理数据集 `bshada/open-schematics` **性质**:Hugging Face 已发布的 KiCad schematics 数据集(非待爬网站),镜像导入即可。 **目标**:补 KiCad 原生生态,与 oshwhub (EasyEDA) 互补。 - [x] 调研(见 `docs/sources/hf_bshada_open_schematics.md`) - [ ] **待拍板** 6.4 GB LFS 预算 - [ ] 目录:`data/external/huggingface/bshada--open-schematics/` - 整包镜像,**不**拆成 per-project 目录(10K+ 条记录) - 78 parquet shards + README + 封面 + 追加 `ATTRIBUTION.md` - [ ] `.gitattributes`:`data/external/**/*.{parquet,png}` 走 LFS - [ ] 下载:`huggingface-cli download bshada/open-schematics --repo-type dataset --local-dir data/external/huggingface/bshada--open-schematics` - [ ] 单独维护 `datasets.md`(per-project 索引 `projects.md` 不适合整包数据集) --- ## Phase 2 — GitHub 开源硬件 repo **目标**:抓 KiCad / EasyEDA / Eagle 格式的公开 repo。 - [ ] 用 GitHub Code Search API 查 `extension:kicad_pcb` / `extension:sch` / `filename:*.epro` 等 - [ ] 过滤 star ≥ N(降噪,可调) - [ ] 抓 repo 元数据 + 文件树 + 关键文件,**不 clone 全仓**(省带宽) - [ ] License 从 repo `LICENSE` 文件 + GitHub API `license` 字段双取 - [ ] MCP:优先 `mcp__github__*` 工具;大规模批量可切 `gh api` + `gitingest` 预计工期:3-5 天。 --- ## Phase 3 — Hackaday.io - [ ] 探测是否有公开 API(`/api/v1/` 曾经存在,需 key) - [ ] 若无 API:解析 explore 列表 + project/log 页面 - [ ] 重点抓项目叙事(README / build log)——这是 LLM 语料的高价值部分 预计工期:3 天。 --- ## Phase 4 — 长尾站点 并列小项目,每个 0.5-1 天: - [ ] CERN OHR(`ohwr.org`)—— 高质量、CERN-OHL 许可清晰 - [ ] Wikifactory - [ ] Open Hardware Park - [ ] Tindie(仅商品元数据,文件多半不公开) - [ ] Instructables 硬件类目(文本叙事为主) --- ## Phase 5 — 数据清洗与派生 - [ ] 去重:`sha256(files)` + `(title, author)` 模糊匹配 - [ ] 质量打分:字段完整度 + 文件大小合理性 + license 有效性 - [ ] 派生数据集: - `components.jsonl`:从 BOM 汇总常见元件 → 成本曲线 - `subcircuits.jsonl`:常见子电路模板(电源、USB、MCU 最小系统) - `narratives.jsonl`:项目叙事文本语料(给 LLM 预训练) - [ ] 生成 README 级统计:项目总数、许可证分布、站点覆盖 --- ## Phase 6 — 持续运营 - [ ] 增量爬取 cron:每站点每周扫一次新增/更新 - [ ] 数据发布:版本化 snapshot(v0.1, v0.2, ...),Release tag 到 Gitea - [ ] 反馈回路:模型训练团队发现脏数据 → issue → 过滤规则下沉到 `scripts/` --- ## 风险与未决项 | 风险 | 影响 | 缓解 | |-----|-----|-----| | oshwhub 反爬加强 | 卡住 Phase 1 | 切 lightpanda/真 Chrome;降速;部分内容弃 | | 许可证字段缺失 / 模糊 | 下游训练合规风险 | 默认剔除 `license: unknown`;建 whitelist | | 单个项目附件过大(>100MB) | 存储爆炸 | 实测 p90=54MB 可接受;大于阈值走外部 OSS、只存 URL | | GitHub API rate limit | Phase 2 慢 | 使用已登录 `gh` token;必要时换 fine-grained PAT | | 站点改版 | 爬虫失效 | 爬虫带 schema 自检,HTML 结构变化时告警 | | **登录态账号被封** | §1.6 登录态工程源卡住 | 账号 QPS ≤ 0.2;多账号轮询;凭据泄露应急计划(见 `docs/infra.md`) | | **EDA→KiCad 转换缺失字段** | §1.7 产物不可用 | 每轮记录失败样本;扩展工具 or 保留原始 JSON 作 fallback | | **云服务器单点故障** | 长跑任务中断 | 数据及时 push 到 Gitea;定时快照云盘;抓取进度存 `data/state/` | **未决**: - 数据规模目标:第一版想要 1 万 / 10 万 / 全量? - 存储分级切换阈值:什么时机从 Gitea LFS 迁到对象存储?(当前提议 200 GB) - 对象存储选型:阿里云 OSS / 腾讯 COS / MinIO 自建? - 是否保留视频(mp4/qt 占 54% 存储):加 `--skip-ext` 还是全保?