# 竞品价格监控采集(BIZ-145 / S2) 按 BIZ-144 v2 竞品名单每周采集一次公开价格信息,落地 JSON/CSV 快照,供 BIZ-146 生成周报。 ## 合规红线(硬编码于 `fetch_prices.py`,不可命令行覆盖) | 条目 | 实现 | |------|------| | C1 频率 | 每周一次(cron);单店 ≤10 页;请求间隔 ≥5s | | C2 robots.txt | 被禁止即跳过,记 `skipped_robots` | | C3 不绕反爬 | 固定常规 UA;遇验证码/登录墙(401/403/特征词)即放弃该页 | | C4 字段白名单 | `name / list_price / promo_text / sales_display`,只抽公开页面展示字段 | | C5 留存 | 原始快照保留 90 天,每次运行自动清理过期目录 | | C7 无代理/账号 | 直连、无登录态 | ## 目录结构 ``` competitor-price/ ├── fetch_prices.py # 采集脚本(仅标准库,Python ≥3.10) ├── targets.yaml # 竞品名单与 SKU URL(数据 Owner 维护,见文件头注释) ├── cron/ │ └── competitor-price.cron # 每周一 09:00 GMT+8 └── data/YYYY-MM-DD/ ├── prices.json # 含合规元信息 run_meta + results + failures ├── prices.csv # 同数据的 CSV 版(UTF-8 BOM,Excel 可直接打开) └── fetch.log # 运行日志 ``` ## 本地手动运行(调试用) ```bash cd monitoring/competitor-price python3 fetch_prices.py # 退出码 0=全部成功,1=存在失败/跳过 ``` 调试时不触发父单告警: ```bash MULTICA_PARENT_ISSUE="" python3 fetch_prices.py # 空值视为未配置,只写日志 ``` ## 安装 cron(每周一 09:00 Asia/Shanghai) ```bash crontab -l > /tmp/mycron 2>/dev/null || true cat cron/competitor-price.cron >> /tmp/mycron crontab /tmp/mycron && rm /tmp/mycron crontab -l | grep competitor-price # 验证 ``` cron 机器需满足:`python3` ≥3.10、`multica` CLI 已登录(用于失败时在父单 BIZ-143 评论告警)。 服务器并非 24h 开机的话,cron 条目含 flock 防重入;漏跑可在下周一前手动补跑一次即可。 ## 失败告警 任一条目非 `ok` 时,脚本在父单 BIZ-143 留一条失败汇总评论(需 `multica` 可用), 同时本地 `fetch.log` 留痕。白牌店铺未回填 URL 记为 `skipped_no_url`,属预期,不告警。 ## 已知边界(如实说明) - Tmall 店铺首页 `robots.txt` 对通用 UA 默认禁止 → 当前 4 家品牌旗舰店均记 `skipped_robots`, 这是合规设计的预期行为,不是脚本故障。要拿到真实价格,需要数据 Owner 在 `targets.yaml` 的 `sku_urls` 中回填**允许抓取的页面**,或由业务方决定改用其他公开数据源。 - 价格抽取基于页面公开 HTML 的通用正则(`"price"` 字段 / ¥ 符号),对重前端渲染页面 可能抽不到 → 记 `ok_no_price_field`,周报侧据此人工复核。