toom1996 3fe0b86e11 feat: 媒体机直传 + 向量回填
- media: spider 下载图片后按内容 sha1 生成 key,经后端预签名直传 S4,上报只带 key
  (spider 不持有 AK/SK;单张失败自动回退为上报 URL)
- embed: 新增 embed 子命令,从后端领取缺向量的图片→下载→本地 CLIP 编码→回传
  (媒体拆分后后端拿不到图片字节,向量只能靠回填补齐)
- serve: 服务化常驻模式(领取 crawl 任务 → 抓取 → 回报)
- config: 新增 media.upload/concurrency、vision.endpoint/concurrency
2026-10-25 00:27:46 +08:00
2026-08-11 00:49:59 +08:00
2026-09-28 10:54:33 +08:00
2026-10-25 00:27:46 +08:00
2026-09-13 00:52:09 +08:00
2026-09-13 00:52:09 +08:00
2026-08-10 20:47:34 +08:00
2026-10-25 00:27:46 +08:00
2026-09-13 00:52:09 +08:00
2026-09-21 15:56:36 +08:00
2026-09-20 00:44:47 +08:00
2026-09-20 00:44:47 +08:00
2026-09-20 00:44:47 +08:00
2026-09-28 10:54:33 +08:00

spider

Vogue 走秀 / The Impression 街拍采集器。抓到的元数据经 HMAC 签名上报后端 ingest 接口,由后端异步下载图片、写库、编码向量——spider 不直连数据库。

两种运行模式

模式 命令 适用
单次抓取 spider vogue -b <品牌id> [-s 场次上限] 临时补某个品牌、调试
常驻服务 spider serve -w 4 -i 5 -m 5 生产用法:从后台领取任务

服务模式不再由人指定品牌:后台决定爬谁(/admin/crawl),spider 领取并执行,执行结果回报后台。

配置(config.yml)

ingest:
  enabled: true                                        # serve 模式必须为 true
  endpoint: "http://<后端IP>:8092/admin/internal/ingest"
  secret: "<与后端 INGEST_SECRET 完全一致>"
  hashid_secret: ""                                    # 服务模式不需要(brand_uid 由后端下发)

endpoint 末尾是 /ingest,客户端会自己推导出 /crawl/tasks(领取任务)和 /crawl/tasks/:id/result(回报结果)。

媒体机直传(把下载/上传从前端搬出来)

media:
  upload: true        # 打开:spider 自己下载图并直传对象存储,后端只写库
  concurrency: 6      # 下载/上传并发

打开后 spider 会:下载图片 → 按内容 sha1 生成 key(runway/<sha1>.jpg)→ 向后端 /admin/internal/upload-url 申请一次性 PUT 地址 → 直接上传 → 上报时只带 key。

关键点:

  • 密钥只在后端:spider 拿的是 15 分钟有效的预签名 URL,不持有存储 AK/SK
  • key 是内容寻址,重复上传幂等,重爬不产生孤儿文件
  • 单张失败不影响整场:失败的图仍带原始 URL,后端会兜底下载
  • 关掉 upload 就完全回到旧行为(后端下载),可随时回滚

什么时候值得打开:spider 部署在带宽比后端机器好的地方时收益明显; 如果两者在同一台机器上,下载带宽是同一份,拆开不会更快(只是把活儿换个进程干)。

服务模式怎么跑

# 编译
go build -o spider .

# 启动:4 路并发、空队列每 5 秒轮询、单品牌内部并发 5
./spider serve -w 4 -i 5 -m 5
参数 含义 建议
-w/--workers 同时跑几个品牌 带宽/CPU 够就 2~4;每个品牌内部还有 -m 并发
-i/--interval 队列空时的轮询间隔(秒) 5~10,别设 1(会把后台接口打满)
-m/--max-co 单品牌内部的抓取并发 3~8;太大会被 Vogue 限流

优雅退出:Ctrl+C 会停止领新任务,等手上的品牌跑完再退。

日志里每个任务有两行关键输出:

[serve] host-1234-0 领取任务 task=7 品牌=Acne Studios(uid=001AJGov) 场次上限=3
[serve] host-1234-0 任务 7 完成:status=done 提交 3 场,耗时 42s

单次模式(调试用)

./spider vogue -b 7            # 只抓 Gucci,不限场次
./spider vogue -b 7 -s 2       # 只抓最近 2 场
./spider vogue -d              # debug:只打印,不上报
./spider theimpression -n 10   # 街拍,最多 10 条任务

-b 是数据库里的数字 id(brands.id),不是 hashid。

后台怎么操作

访问 http://<后端>:8092/admin/crawl(需先登录后台)。

1. 加任务

场景 操作
抓单个品牌 去 /admin/brands 找到品牌 → 点「加入抓取队列」(默认每品牌 3 场)
批量抓一批 在 /admin/crawl 顶部「批量加入」:前缀 A + 场次上限 3 + 数量 50 → 就是把 A 开头的 50 个品牌各抓最近 3 场
重爬某个品牌 在任务列表该行点「重试」(会把状态重置为待领取)

「场次上限」填 0 表示不限场次——批量时不要填 0,否则一个老品牌可能有上百场,一次灌进来几万张图。

2. 看状态

状态 含义
待领取 已入队,等 spider 来拿
执行中 某个 spider 已领取(列表里会显示 worker 标识)
已完成 跑完了。已提交 列是本次提交了几场走秀
失败 spider 侧进程级失败,会自动重试最多 3 次;耗尽后需手动「重试」

已提交 = 0 不一定是错误:Vogue 上很多品牌没有走秀页面(实测 A 开头品牌里约 75% 没有),这种情况任务是「已完成、提交 0 场」。

3. 取消 / 删除

  • 取消:只是不再被领取,无法中断正在执行的品牌(spider 手里还在跑)
  • 删除:只删任务记录,已入库的图集不受影响

4. 任务卡在「执行中」怎么办

正常情况会被自动回收:后台对 执行中 的任务有 15 分钟租约,超过仍未回报就自动放回「待领取」。所以 spider 断电/被杀不会导致任务永久丢失,重启后会被重新领走。

抓完之后

任务完成只代表元数据已提交。图片下载、写库、编码向量由后端 worker 异步完成,看进度去:

  • /admin/ingest-jobs — 入库任务(pending / processing / done / failed)
  • /admin/articles — 已入库的图集(默认 pending 状态,前台不可见,需在列表里通过)

常见问题

现象 原因 / 处理
启动即报「ingest 未启用」 config.yml 的 ingest.enabled 不是 true
一直「无任务」 后台还没加任务,或全部被其他 spider 领走了
领取报 401 ingest.secret 与后端 INGEST_SECRET 不一致
任务反复失败 看后台列表的「错误」列;常见是网络不通/被 Vogue 限流
抓到了但前台看不到 图集是 pending,去 /admin/articles 通过审核
Description
No description provided
Readme 37 MiB
Languages
Go 100%