# 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) ```yaml 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`(回报结果)。 ## 媒体机直传(把下载/上传从前端搬出来) ```yaml media: upload: true # 打开:spider 自己下载图并直传对象存储,后端只写库 concurrency: 6 # 下载/上传并发 ``` 打开后 spider 会:下载图片 → 按内容 sha1 生成 key(`runway/.jpg`)→ 向后端 `/admin/internal/upload-url` 申请一次性 PUT 地址 → 直接上传 → 上报时只带 key。 **关键点**: - 密钥只在后端:spider 拿的是 15 分钟有效的预签名 URL,不持有存储 AK/SK - key 是内容寻址,重复上传幂等,重爬不产生孤儿文件 - 单张失败不影响整场:失败的图仍带原始 URL,后端会兜底下载 - 关掉 `upload` 就完全回到旧行为(后端下载),可随时回滚 **什么时候值得打开**:spider 部署在**带宽比后端机器好**的地方时收益明显; 如果两者在同一台机器上,下载带宽是同一份,拆开不会更快(只是把活儿换个进程干)。 ## 服务模式怎么跑 ```bash # 编译 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 ``` ## 单次模式(调试用) ```bash ./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` 通过审核 |