Files
FacereDataset/log.md
Knowit 3282a028c4 Add EasyEDA Pro EPRO2 source ingestion (3/5 batch test)
打通 oshwhub origin=pro 现代 Pro 3.x 工程的 EPRO2 源抓取链路。3/5
modern Pro 项目完整解出(共 8423 docs / 542 MB plain):

- X86 主板        7374 docs / 481 MB plain (chain=85, editor=3.2.15)
- 220V 桌面电源     771 docs /  26 MB plain (chain=28, editor=3.2.69)
- ESP-VoCat       278 docs / 7.5 MB plain (chain=12, editor=3.2.91)

剩余 2/5 是 legacy Pro 2.x(立创泰山派 RK3566、梁山派),项目 meta
返回 branch_uuid=null + editorVersion="2.1.40",没有 git-style chain
模型,文档直接挂在 boards[].sch/pcb 字段上,访问端点暂未挖通;元
数据落库 metadata.json,source/ 留空。

实现要点:
- fetch_pro_source(): 4 步流程(project → branch HEAD → structures
  → /branches/<B>/histories/<HEAD> 即返完整 chain,无需 ?limit 批量
  端点)+ 逐 history 走 AES-128-GCM 解密(16 字节 IV,pycryptodome
  原生支持)+ gunzip + 按 DOCHEAD 切 per-doc EPRO2 流
- EPRO2 解析坑:行末单 `|` 是行终止符不是字段分隔符,必须先
  rstrip("|") 再 split("||"),否则 payload JSON 解析失败 silently
  swallow 导致 cur_doc 不设 → 第一轮 X86 板 7374 docs 抽出来只剩 2 个
- docType 实测远不止 BOARD/PCB/SCH/SCH_PAGE,还含 SYMBOL /
  FOOTPRINT / DEVICE / BLOB / FONT / CONFIG —— Pro 把组件库快照也
  随项目存到 history,下游做 EPRO2→KiCad 转换时必须先把这些 lib
  doc 加载进 symbol cache
- Pro 2.x vs 3.x 是不同存储模型 —— 3.x 走 branch 模型(已打通),
  2.x 走 boards[] 直链(未打通);判别条件:project meta 的
  branch_uuid 是否为 null

CLI 新增 --with-pro-source / --backfill-pro-source / --pro-cookie /
--origin(按 origin 字段服务端过滤 listing API),crawl_one() 按
origin=pro 自动 dispatch 到 Pro fetcher。

schema:docType 类型从 integer 放宽到 [integer, string, null]
(兼容 Std 的 1/3 + Pro 的 BOARD/SCH 等),新增 message_count 字段。

License 注意:本批 5 个项目全是 NC-SA / GPL,未达 Pro source doc
§4.2 Forge 白名单(MIT/BSD/Apache/CC0/CC-BY/CERN-OHL-P/Unlicense)。
按 CLAUDE.md "研究用、不再分发" 原则 raw 入库无碍;Forge 投影时
另过白名单。

详细技术细节见 docs/sources/easyeda_pro_source.md rev 3 + log.md。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 21:45:52 +08:00

25 KiB
Raw Blame History

FacereDataset 执行日志

时间倒序,最新在顶部。


2026-04-28 21:35 Pro 工程源EPRO2批量抓取打通3/5 modern Pro 项目 2/5 legacy 2.x

Claude 会话

承接刚做完 Std 链路;用户给了浏览器 HAR (tmp/prodownload.har174 请求,目标 = 立创·泰山派 RK3576 现代 Pro 项目) 验证 endpoint 形态,要求"找 5 个专业版项目,看能不能批量抓 EPRO2"。

5 个候选

oshwhub /api/project?origin=pro&sort=hot 取前 5详情 API 拿 license

# UUID License 项目 结果
1 b77840665e2e... GPL 3.0 【全网首发】X86电脑主板
2 7360e73de5dd... GPL 3.0 立创·泰山派 RK3566 开发板 legacy 2.x
3 0c4675983733... GPL 3.0 立创·梁山派开发板 legacy 2.x
4 dc91a91e6693... CC BY-NC-SA 4.0 高颜值220V 300W 桌面电源
5 ba64bd6f1c9c... GPL 3.0 ESP-VoCat 喵伴 AI 萌宠

License 全是限制性CC-NC-SA / GPL— Pro 用户群是立创团队/教育机构,默认上 NC-SA。和用户对齐本仓库为研究用、不再分发license 字段忠实落库;下游 Forge 投影时再用白名单过滤。

关键发现Pro 2.x ≠ Pro 3.x重要

立创开发板的旗舰板RK3566 / 梁山派)抓 /api/v4/projects/<uuid> 返回 branch_uuid: null + editorVersion: "2.1.40"

这是 Pro 编辑器旧版2.x:没有 git-style branch/history 模型,文档直接通过 boards: [{sch, name, pcb}] 字段定位。我们之前调研的全是 3.x泰山派 RK3576 / 无界 PLUS3.x 才有 /branches/<B>/structures + /histories/<H> 全套。

旧版的访问端点暂未挖通:/api/v4/documents/<doc> 404/api/documents/<doc> 401/api/v4/projects/<P>/snapshots 200 但响应体是 project meta 不是 doc。需要录一份"在 pro.lceda.cn 编辑器里打开 RK3566"的 HAR 才能继续。已记入 docs/sources/easyeda_pro_source.md §1.1

EPRO2 解析坑:行末单 |(找了 2 轮才看到)

第一轮跑 5 个项目结果X86 board 7374 docs 抽出来只剩 2 个220V 电源和 ESP-VoCat 都是 0 docs

定位过程:

  1. 直接 dump 一条 history 的 lines看到 DOCHEAD payload 行末有单个 |,例如 {"docType":"BOARD",...,"version":"..."}|
  2. 我的解析 json.loads(ln.split(b"||")[1]) 拿到带尾随 | 的字符串 → Extra data: line 1 column 127
  3. silently swallow exception → cur_doc 没设 → 全 chain 的 message 被丢弃。
  4. 修复:解析前先 ln.rstrip(b"|").split(b"||")。已在 docs/sources/easyeda_pro_source.md §3.1 记录"行末单 | 是行终止符不是字段分隔符"。

修复后批量结果

3 个 modern Pro 项目完整解出来:

项目 chain docs plain blob editor
ESP-VoCat 12 278 7.5 MB 1.1 MB 3.2.91
220V 电源 28 771 26.3 MB 7.4 MB 3.2.69
X86 主板 85 7374 481 MB 61 MB 3.2.15

X86 主板5123 FOOTPRINT + 1243 DEVICE + 837 SYMBOL = 7203 个组件库 doc数据量惊人是个超复杂工程。

docType 取值表(实测扩展)

之前 doc 只列了 BOARD/PCB/SCHEMATIC/SHEET。实测 EPRO2 流里 docType 实际取值更细:

  • 用户级文档:BOARD(板物理边框)+ PCB(板内容)+ SCH(原理图)+ SCH_PAGE(子图)。一个完整 PCB 板 = 一对 BOARD + PCB,不是命名变化。
  • 组件库 / 资源:SYMBOL / FOOTPRINT / DEVICE / BLOB / FONT / CONFIG。每个独特组件 / 字体 / 项目配置都是独立 doc。
  • 抓 EPRO2 = 抓项目 + 完整的局部组件库快照。下游做 EPRO2 → KiCad 转换时必须先把 lib doc 加载进 symbol cache。

已更新到 docs/sources/easyeda_pro_source.md §3.4

代码改动

  • crawlers/oshwhub/crawler.py
    • 新增 make_pro_source_client() —— 加载 ~/.secrets/pro-lceda-cookie-header.txt,自动配 Editor-Version / Referer / per-request path header
    • 新增 fetch_pro_source(client, project_uuid, proj_dir, sleep) —— 4 步流程project meta → branch HEAD → structures → history chain然后逐 history 解密AES-128-GCM, 16 字节 IV+ gunzip + 按 DOCHEAD 切 per-doc
    • 新增 _order_history_chain() —— 沿 parent 链从 root 到 HEAD 排序
    • 新增 _pro_get_json() —— 包装 /api/v4 GET 调用,自动加 path header + 校验 success
    • 扩展 crawl_one()pro_source_client 参数,按 list_item.origin 自动 dispatch
    • 新增 CLI flag --with-pro-source / --backfill-pro-source / --pro-cookie / --origin
    • 新增 _run_backfill_pro_source()filter on raw_fields.origin == "pro"
  • schemas/project.schema.jsondocType 类型从 integer 放宽到 ["integer","string","null"](兼容 Std 的 1/3 + Pro 的 BOARD/PCB/SCH 等字符串),新增 message_count 字段
  • docs/sources/easyeda_pro_source.md rev 3加 §1.1 Pro 2.x vs 3.x、§3.1 行末 | 警告、§3.4 docType 实测表、§2.2 单 history endpoint 即返完整 chain

数据落地

data/raw/oshwhub/
  b77840665e2e48148c1b04ce84b5f7e7/   # X86 主板modern Pro 3.2.15
    source/
      manifest.json          # 7374 docs index
      structure.json         # 项目树boards/schematics/sheets/pcbs
      <doc_uuid>.epro2       # 7374 个 EPRO2 文件
  dc91a91e669349898d709a5ba02f5b5f/   # 220V 电源modern Pro 3.2.69
  ba64bd6f1c9c467ba3b674a54943557d/   # ESP-VoCatmodern Pro 3.2.91
  7360e73de5dd428e9f29e10573f2d8ac/   # legacy Pro 2.x无 source/
  0c46759837334318aa4882d6d37f96fa/   # legacy Pro 2.x无 source/

下一步

  1. 重要legacy Pro 2.x 抓取链:录 HAR 看 RK3566 / 梁山派 在 pro.lceda.cn 编辑器打开时走什么 endpoint
  2. 想跑量到 50 / 500 项目时,先做风控测试:阶梯放量,监控 403 / 429 / 1111111
  3. EPRO2 → KiCad 转换器是 Forge 投影前置硬门槛
  4. 可考虑 cookie 轮换 / 多账号 poolPro 风控相对 Std 严)

2026-04-28 19:50 Std 工程源链路打通 + 10 板子 schematic/PCB 全部回填

Claude 会话

承接计划:把已抓 10 个板子的"需登录才能下载的原理图 + PCB"补齐。

关键发现:根本不需要登录

10 个板子全是 origin: "std"EasyEDA 标准版)。原 plan.md §1.6 假设源数据要登录 — 实际公开项目的 dataStr 匿名可访

调研路径4 轮探测,留痕在 data/state/std_probe[1-5]/

  1. /api/user/api/projects 401cookie 已过期,但和源抓取无关)
  2. oshwhub.com/api/project/<uuid> 浏览器 UA 匿名 200,返回 version_documents[](含 doc uuid + master + history chain
  3. modules.lceda.cn/histories/<hash>.json 仍 403与 Pro 同结构,但 Std 不走这条路)
  4. 翻 Std 编辑器 /editor/6.5.51/js/main.min.js5 MBgrep /api/,找到 76 个端点。关键的 ajaxDetail = '/api/documents/{uuid}'
  5. 命中:https://lceda.cn/api/documents/<doc>?uuid=<doc>&path=<doc> 匿名 200body 是完整 EasyEDA JSONdataStr.{head,canvas,shape,BBox,colors[layers,objects,DRCRULE,...]}

两种响应 shape(按 docType 区分):

  • docType=1 (Schematic):返"项目视图"result.schematics[0].dataStr
  • docType=3 (PCB):返"文档视图"result.dataStr 直接在顶层

与 Pro 的差异

维度 Std (本轮) Pro (docs/sources/easyeda_pro_source.md)
鉴权 无需 lceda_pro_session 必须
加密 AES-128-GCM + gzip
源格式 扁平 EasyEDA JSONshape[] EPRO2 消息流(事件溯源)
多 doc version_documents[] 逐个 GET /structures + history chain 重放

实施

  • docs/sources/easyeda_std_source.md:完整调研(含 dataStr 字段、抓取伪代码、附录重跑脚本)
  • crawlers/oshwhub/crawler.py
    • 新增 make_source_client() —— 浏览器 UA + Referer规避 oshwhub /api/project/<uuid> 端点对 FacereDataset/0.1 UA 的 reject在 commit message 注明 UA 例外原因)
    • 新增 fetch_std_source():项目 → version_documents → 逐文档 dataStr → 落 source/<doc>.json + source/manifest.json
    • 新增 --with-source 标志(爬新项目时一并抓源)和 --backfill-source(仅扫已有项目补源)
    • QPS ≤ 0.2SLEEP_SOURCE = 5.0s
  • schemas/project.schema.json:加 source_format/source_path/source_documents/editor_version 字段(前 3 个进 enum 锁定,后续新源好对齐)

跑批结果dev1QPS 0.2

10/10 全成功schema 验证 10/10 pass

项目 docs docTypes 大小 editor
ST-LINK V2-1 2 [1,3] 682 KB 6.5.39
USB 电压电流表 4 [3] 1.2 MB 6.5.15
红外热成像 2 [1,3] 1.6 MB 6.5.22
t12-858d 焊台 11 [1,3] 6.1 MB 6.5.15
加热台量产计划 6 [1,3] 12.0 MB 6.5.43
ESP32-S3 智能手表 4 [1,3] 1.4 MB 6.5.41
RT300-MKV 可调电源 3 [1,3] 3.3 MB 6.5.23
YuzuMaix V831 4 [1,3] 5.4 MB 6.5.37
盖革计数器 6 [1,3] 1.2 MB 6.5.47
ZVS 感应加热 3 [1,3] 990 KB 6.5.40

合计45 个文档 / 33.2 MB中位 ~1.5 MB / 项目,附件主体约为附件主流量的 6%

观察:

  • USB 电压电流表只有 PCB 文档4 个:主板 + 盖板 + 底板 + 面板,作者未上传原理图源)
  • t12 焊台 11 个文档(拆得碎,估计含多个独立模块)
  • editor 版本散布在 6.5.15 - 6.5.47(取决于作者上一次保存项目时的客户端版本)

落盘结构per project

data/raw/oshwhub/<uuid>/
├── metadata.json         # ★ 新增字段source_format/source_path/source_documents/editor_version
├── description.md
├── cover.*
├── _urls.json
├── files/                # 用户附件已存在LFS
└── source/               # ★ 新EasyEDA Std 工程源
    ├── manifest.json     # 文档清单 + 抓取时间 + upstream version_documents 留档
    └── <doc_uuid>.json   # 完整 dataStr 响应(普通 git文件 1-5 MB 量级)

source/*.json 走普通 git 而不是 LFS10 项目共 33 MB 完全够用;放量时再考虑加 LFS 规则)。

安全 / 合规

  • 无登录态、无凭据使用 → 无账号封禁风险,无 cookie 泄漏顾虑
  • UA 例外:源抓取使用浏览器 UA 而非 FacereDataset/0.1,原因写入 docs/sources/easyeda_std_source.md §3 与本 commit message
  • License与原项目附件相同的 license 字段已在 metadata下游 whitelist 过滤逻辑不变

未决 / 下一步

  1. dev1 上的 ~/.secrets/lceda.json cookie 已过期XSRF 4-22 失效,今天 4-28本任务已不依赖它。是否保留待定 —— Pro 流程可能仍要
  2. easyeda2kicad.py 转换:现有 45 个 dataStr 是关键测试样本,可立刻跑(plan.md §1.7
  3. 放量决策:从 10 → 50 → 全量 12,493 时,按 33 MB / 10 ≈ 3.3 MB/proj 估算,全量源 ~40 GB不含附件本体
  4. 多账号轮询、Pro 链路打通仍是 plan.md §1.6 的开放项(仅当遇到 Pro 项目时才用得上)

改动清单

  • 新增:docs/sources/easyeda_std_source.mdscripts/probe_std_api[1-5].pydata/raw/oshwhub/<uuid>/source/10 项目)
  • 修改:crawlers/oshwhub/crawler.pyschemas/project.schema.json、10 项目的 metadata.json
  • 待人工:projects.md 重生成(脚本未跑);plan.md §1.6 状态从 §1.7 unblocked

2026-04-24 00:25 打通 pro.lceda.cn 工程源完整链 + EPRO2 格式解析

Claude 会话

核心成果:立创 EDA Pro 工程源的 API + 加密 + 格式三层全打通

完整链路

1. GET /api/v4/projects/<PROJ>                                    → branch_uuid
2. GET /api/v4/projects/<PROJ>/branches/<BRANCH>                  → history_uuid
3. GET /api/v4/projects/<PROJ>/branches/<BRANCH>/histories/<HIST> → {key, iv, dataStrUrl}
4. GET <dataStrUrl> (modules.lceda.cn)                            → 417 KB 加密 blob
5. AES-128-GCM decrypt (tag=blob[-16:])                           → 417 KB gzip
6. gunzip                                                          → 2.7 MB EPRO2 源流

关键 headersEditor-Version: 3.2.127 / path: <PROJ_UUID> / Referer: https://pro.lceda.cn/editor / Cookie: lceda_pro_session=...(与 u.lceda.cn 的 session 不共享)

加密细节

  • 算法: AES-128-GCMmodules.lceda.cn/pro-mgr/.../project-worker.jsthis.tool.decrypt({name:"AES-GCM",iv:this.iv,tagLength:128},...) 反查确认)
  • key / iv 都是 32 hex = 16 byte
  • WebCrypto 约定ciphertext || 16-byte-authTag末尾附
  • 解密后 gzip magic 1f 8b 08gunzip 得最终源流

EPRO2 格式

立创 EDA Pro 2 的事件溯源格式:消息流按 \n 分行,每行 {"type":...,"ticket":N,"id":...}||{payload}||[extra]。 示例样本(无界PLUS BOARD 文档)8 357 条消息40 种 type

  • PART / COMPONENT / ATTR / PIN零件与属性
  • PAD / VIA / WIRE / NET / PAD_NETPCB 电气)
  • LINE / POLY / RECT / ARC / CIRCLE / ELLIPSE / TEXT几何
  • LAYER (1572) / LAYER_PHYS / ACTIVE_LAYER层堆叠
  • FILL / POUR / POURED铺铜
  • RULE / RULE_SELECTOR / RULE_TEMPLATE设计规则

与 Std 版对比

u.lceda.cn (Std) pro.lceda.cn (Pro)
Cookie lceda_session lceda_pro_session
源 API 单一 /api/projects/<uuid> 4 步 /api/v4/...
版本控制 branches + histories
加密 待验证 AES-128-GCM
源格式 EasyEDA JSON扁平 EPRO2 消息流
工具 easyeda2kicad.py 第三方 现成 KiCad 转换器

落地

  • 新建 docs/sources/easyeda_pro_source.md(完整调研,见该文档附录 A 一键重跑)
  • pyproject.tomlpycryptodome>=3.23.0
  • 清理dev1 上 /tmp/source.blob/tmp/source.json(后者含 Charles 私人工程源 2.7 MB

待验证 / 下一步

  1. 他人公开 Pro 工程能否同样 4 步通 —— 需 HAR
  2. SCHEMATIC docType 的 API 入口(本次只解出 BOARD
  3. 多 document 枚举project → documents 列表端点)
  4. Pro 编辑器"导出 KiCad"功能的 API 端点(若存在,能省自写转换器的工作)
  5. 对齐 OSHWHUB_INGEST_SPEC.mdForge 消费侧要求 .kicad_sch + 更严 license whitelist

⚠️ 安全

Charles 在聊天里粘过两次 cookieu.lceda.cn 一次 + pro.lceda.cn 一次),已写入 dev1 ~/.secrets/。 当前会话 transcript 含明文 —— 本轮验证完 Charles 应登出再重登一次,让测试期间暴露过的 session invalidate。


2026-04-23 20:10 策略大调:登录内容入场 + 云服务器 + EDA→KiCad 转换

Claude 会话

四项变更落实到文档(暂不写代码,等云服务器到位):

1. 登录态内容纳入范围

原则(CLAUDE.md

  • 合法账号登录后抓,禁止盗号 / 共享号
  • 凭据集中云服务器 ~/.secrets/ (mode 700)不入 git / 日志 / metadata
  • 仍不绕付费墙、不破 DRM、不抓站点明确禁抓的内容
  • 换号 / 重登事件记 docs/secrets.md(只事件、不含值)

2. 云服务器(广州,待交付)

新增 plan.md §0.5 基础设施段:

  • 0.5.1 机器初始化git / git-lfs / uv / python 3.11+,非 root SSH~/.secrets/
  • 0.5.2 调度tmux/nohup 长跑 + systemd timer 增量
  • 0.5.3 登录态获取cookie 导出流程

3. 存储分级演进

plan.md §1.4 改写:

  • 前期 < 50 GB云服务器磁盘 + Gitea LFS
  • 中期 50200 GB评估 Gitea 容量压力;扩容 or 分仓
  • 后期 > 200 GB迁对象存储OSS / COS / MinIOGitea 只存元数据 + 指针
  • 50 GB 是决策评估点,过早迁移

4. 立创 EDA → KiCad 转换

新增 plan.md §1.6(登录态工程源抓取)+ §1.7EDA→KiCad 转换):

  • §1.6 用登录账号抓 u.lceda.cn/api/project/<uuid> 工程源 JSONsource.json
  • §1.7 写 scripts/convert_to_kicad.py,候选工具 easyeda2kicad.pypypi活跃维护
  • 批处理扫 data/raw/oshwhub/ → 输出 data/processed/oshwhub/<uuid>/kicad/
  • kicad-cli sch erc / pcb drc 做语法校验,失败样本记 data/state/convert_failed.jsonl
  • 目的:打通 oshwhub (EasyEDA) 与 bshada/open-schematics (KiCad) 两个生态的训练语料

同步改动

  • docs/sources/oshwhub.md §3.5 从"未开放"改为"需登录,纳入范围"R4 风险更新
  • README.md 数据源表加「登录态」列,加运行环境说明

等待

  • 广州云服务器到位 → 启动 Phase 0.5
  • 账号登录凭据由 Charles 提供

2026-04-23 19:55 oshwhub.md 重写成完整调研文档

Claude 会话

Charles 要求把 12 493 总数验证、90 项目采样结果合进主调研文档。

docs/sources/oshwhub.md 重写为 9 节 + 2 附录的完整调研:

  1. 一页纸 TL;DR 表
  2. 站点架构
  3. robots.txt 与合规
  4. API 与抓取入口(列表 / SSR 详情 / 附件 CDN / 排除项 / 未开放端点)
  5. 项目总数验证(新):三路 sort 一致 + 分页二分搜索250 × 50 = 12 500 吻合)+ grade 覆盖抽样
  6. 抽样语料特征(从 oshwhub_corpus_estimate.md 并入):体积 / 文件类型 / license 分布
  7. Schema 映射
  8. 速率与礼貌
  9. 目录输出约定
  10. 风险与未解决7 条)
  11. 附录:重跑命令、变更历史

删除重复文件 oshwhub_corpus_estimate.md(内容已并入 §5


2026-04-23 19:50 加入 HF bshada/open-schematics 计划

Claude 会话

Charles 点名把 https://huggingface.co/datasets/bshada/open-schematics 纳入第一批。

调研结论:

  • 这是已预处理的 HF 数据集,非待爬网站
  • 78 parquet shards 6.4 GBCC-BY-4.0(商用友好)
  • 10K+ 条记录,每条含 .kicad_sch 源 / PNG / 组件列表 / JSON / YAML / name / description
  • 与 oshwhub (EasyEDA) 互补,补 KiCad 生态

决定:

  • 整包镜像data/external/huggingface/bshada--open-schematics/拆 per-project 目录
  • huggingface-cli download ... --repo-type datasetparquet 走 LFS
  • 维护单独的 datasets.md,不与 per-project 的 projects.md

改动:

  • 新增 docs/sources/hf_bshada_open_schematics.md 完整调研
  • plan.md 加 Phase 1.5
  • README.md 数据源表加一行

未下载,等拍板 6.4 GB LFS 预算。


2026-04-23 19:30 Phase 1 MVP10 个高质量 oshwhub 项目入库

Claude 会话:承接仓库初始化

API 调研结论

  • 列表 APIGET https://oshwhub.com/api/project?page=N&pageSize=M&sort=hot,无鉴权,返回 12493 个项目元数据(含 grade / likes / stars / views / forks
  • 详情:GET https://oshwhub.com/<path> 是 SSR HTML嵌入 escaped JSONlicense + attachments[](每个带 name / src / size / md5 / ext / mime / download_count
  • 附件 CDNhttps://image.lceda.cn{src} — 已验证无鉴权直接下载
  • EasyEDA 工程源 JSONu.lceda.cn需登录v0.1 不抓
  • 详细调研见 docs/sources/oshwhub.md

选 10 个高质量项目

判据:grade == 4(平台精品徽章) + likes ≥ 100 + 应用领域多样(避免同类堆叠)+ 排除 _copy 派生仓。

10 个项目覆盖调试器、加热台、盖革计数器、可调电源、焊台、智能手表、USB 测电流、ZVS 感应加热、AI 开发板、红外热成像。

MVP 爬虫

位置:crawlers/oshwhub/crawler.py

  • list_projects() — 列表 API 分页
  • pick_top() — 按 like×3 + star + fork×2 + views/100 + comments×2 + grade×50 排序
  • parse_detail_html() — 从 SSR HTML 提取 title / license / description / attachments
  • crawl_one() — 每项目产出:metadata.json / description.md / cover.* / files/* / _urls.json
  • QPS ≤ 0.5SLEEP_BETWEEN = 2.0UA 显式声明 FacereDataset/0.1

抓取与入库

  • 10/10 成功52 个附件,524 MB
  • Gitea LFSv25.4.3 原生支持)+ 本地 git-lfs 3.5.1(用户态二进制装在 ~/.local/bin/
  • .gitattributes 规则:data/raw/**/files/** 一律走 LFS元数据metadata.json / description.md / _urls.json / cover.*)走普通 git
  • 每项目目录结构:
    data/raw/oshwhub/<uuid>/
    ├── metadata.json      # 按 schemas/project.schema.json
    ├── description.md
    ├── cover.{jpg,png,jpeg}
    ├── _urls.json         # 所有原始 URL 清单
    └── files/*            # 原始附件LFS
    

改动汇总

  • 新增:crawlers/oshwhub/{__init__,__main__,crawler}.pyschemas/project.schema.jsondocs/sources/oshwhub.mdpyproject.toml
  • 修改:.gitattributes(缩窄到 data/raw/**/files/**)、.gitignore(移除 data/raw/* 排除)

下一步建议

  1. 验收 10 个项目元数据质量(随机抽 2-3 条对照原站)
  2. 决定 Phase 1.4 放量目标50500全量 12493
  3. Phase 2 准备GitHub KiCad repo 调研

2026-04-23 19:40 fs-web-stream 排查 + schema 自动校验

Claude 会话(自主推进)

fs-web-stream.jlc.com 定性

重新抓 /CYIIOT/ST_LINK-V2_1 并看 13 个 fs-web-stream.jlc.com 链接的上下文:全部是嘉立创服务侧栏/推广图标3D 打印、发热片、Ican、EDA 扩展广场、开源硬件平台 badge 等),与项目本身无关image.lceda.cn/attachments/ 就是项目附件的唯一入口,已确认闭环。docs/sources/oshwhub.md 对应章节已更新。

scripts/validate.py

jsonschema 做两层校验:

  • 默认:所有 data/raw/**/metadata.jsonschemas/project.schema.json 的结构校验
  • --check-files:另外验证每条 file 的本地 path 存在且 sha256 匹配

结果10/10 项目两项全通过。

新增

  • scripts/validate.py
  • pyproject.tomljsonschema>=4.26

待决策

  • 放量规模 —— 已提供实测数据:median ≈ 110 GBp90 上界 ≈ 660 GB建议预算 150180 GB(见 docs/sources/oshwhub_corpus_estimate.md
  • 是否需要抓 u.lceda.cn 的 EasyEDA 源 JSON需登录v0.1 跳过)

2026-04-23 19:45 全量规模实测 + License 分布

Claude 会话(自主推进)

scripts/estimate_size.py,只抓详情 HTML 解析 attachments[].size,不下载;采样 90 个 hot 项目3 页 × 30

关键发现

  • 单项目 median 9 MB / mean 22 MB / p90 54 MB / max 204 MB12493 全量 median 估算 110 GBp90 上界 660 GB
  • 视频 (.mp4 + .qt) 占 54% 存储!如果训练只要 PCB/原理图/BOM--skip-ext mp4,qt 存储直接砍半
  • License 分布健康GPL 3.0 占 49%Public Domain 21%CC 系列 ~20%CERN/TAPR OHL 6%;样本内无闭源
  • NC (Non-Commercial) 占 ~11%,商用场景必须过滤

结果固化到 docs/sources/oshwhub_corpus_estimate.md,可随时重跑验证。

建议

  1. 存储预算定 180 GBmedian + 15% buffer
  2. Phase 1.4 前给 crawler 加 --skip-ext 开关滤视频
  3. 下游建立 license whitelist 过滤 NC / 未知

2026-04-23 18:50 仓库初始化 & 数据源调研

Claude 会话:初始化

完成:

  • git.deepknow.site/Facere/FacereDataset 克隆空仓到 ~/repo/FacereDataset
  • 调研立创开源平台oshwhub.com初步数据
    • robots.txt 仅 Disallow /posts,其他路径允许
    • 存在 sitemap.xml(首页 + explore + activities + market 等入口已列出)
    • 项目详情页路径为 /detail/<uuid>(示例 f0652fd2ae3e40b8a0ecc8dc773e3512
    • 图片 CDNimage.lceda.cn/oshwhub/pullImage/...
    • 文件下载:fs-web-stream.jlc.com/fs-web-stream/file-operation/download/<snowflake-id>
    • 页面是 Next.js SPA首屏 HTML 800KB但数据加载具体 API 入口需要浏览器 trace留给 Phase 1.1
  • 创建项目骨架:
    • README.md — 项目简介与数据源表
    • CLAUDE.md — 项目级 Claude 指令爬虫规约、合规红线、schema 要求)
    • plan.md — 6 阶段建设计划Phase 0 骨架 → Phase 5 数据清洗 → Phase 6 持续运营)
    • log.md — 本文件
    • .gitignore — 排除 data/raw data/processed data/state Python 缓存等
    • 目录骨架 crawlers/ schemas/ scripts/ data/{raw,processed,state} docs/{sources,}
    • 每个空目录放 .gitkeep
  • 首次提交 & 推送到 origin main

下一步建议

  1. 拍板存储方案(本地盘 / Gitea LFS / 外部 OSS—— 影响 Phase 1.4 放量时机
  2. 目标规模1 万 / 10 万 / 全量)
  3. 决定是否保留二进制附件或只存 URL
  4. 完成上述 3 项后启动 Phase 1.1(用 chrome-devtools MCP 录 oshwhub 的 network trace 定位真实 API