Auditable, resumable external image-match screening for authorized shops
Project description
StoreWright Catalog Scout
StoreWright Catalog Scout 是面向已授权店铺数据的商品图片筛选与本地归档工具。它先用商品列表图调用 SerpApi Google Lens 精确匹配,再决定是否读取并保存完整商品详情;按类目最多保留指定数量的合格商品,并在店铺淘汰率显著过高时提前停止,减少 API、页面访问和存储消耗。
淘宝/天猫是首个数据源。编排、图片检索、判定、数据库和报告均通过通用接口实现,不把淘宝写死为唯一来源。
工具不会绕过登录、验证码、滑块或平台风控,不包含 stealth、代理轮换或指纹伪装。真实任务只可用于你拥有、控制或明确获授权访问的数据。SerpApi 会收到公开商品图片 URL;仅在机械导航失败时,页面状态才可能发送给配置的 Browser Use/DeepSeek 模型。
工作流
shops.csv
→ 发现并确定性打乱商品
→ 列表图 Serp 精确匹配
→ 外部精确匹配:淘汰,只保留最小审计证据
→ 无精确匹配:保存 screened_qualified,不立即打开详情
→ 每次成功判断后更新店铺淘汰率
→ Wilson 下界超过阈值:提前淘汰店铺并停止剩余处理
→ 全店列表图预筛完成后,按标题临时分类并限制候选数
→ 候选详情页固定间隔 30 秒,每件完成后立即持久化检查点
→ 详情主图变化:再次 Serp
→ 类目未满:保存完整详情和可识别商品图
→ 登录/验证/阻断页:立即 paused,不自动重试
核心决策全部是确定性规则。DeepSeek 只在固定商品列表 URL 无法直接打开时作为导航后备,不参与逐商品判定。
安装
包已发布到 PyPI。需要本机 Chrome。推荐使用 uv tool 安装;uv 会为命令创建隔离环境,并在需要时安装兼容的 Python。
uv tool install storewright-catalog-scout
storewright-scout --help
mkdir catalog-scout-workspace
cd catalog-scout-workspace
storewright-scout init
init 会创建当前工作目录下的 .env、SQLite 数据库和运行目录,不会覆盖已有 .env。新建的 .env 包含生产安全的详情访问默认值;填写至少一个 SerpApi Key 后即可运行。升级使用:
uv tool upgrade storewright-catalog-scout
输入 CSV
shops.csv 只需要一个字段,可提供多个店铺:
shop_url
https://shop-a.taobao.com/
https://shop-b.tmall.com/
空 URL 会报错,重复 URL 会去重。店铺名称和 ID 自动识别。
配置
关键配置:
SERPAPI_API_KEYS=key-a,key-b,key-c
MAX_POOL_SIZE=2000
MAX_QUALIFIED_PRODUCTS_PER_CATEGORY=20
SHOP_REJECT_RATE_THRESHOLD=0.60
EARLY_STOP_MIN_SEARCHES=10
EARLY_STOP_CONFIDENCE=0.90
MAX_SEARCH_ERROR_RATE=0.20
MAX_DETAIL_PRODUCTS_PER_BATCH=5
DETAIL_PAGE_INTERVAL_SECONDS=60
DETAIL_PAGE_INTERVAL_JITTER_SECONDS=15
DETAIL_PAGE_MAX_PER_HOUR=20
DETAIL_RISK_COOLDOWN_SECONDS=900
DETAIL_RISK_MAX_COOLDOWN_SECONDS=21600
PAUSE_AFTER_SCREENING=true
真实详情访问使用工作区级持久化节流和风险冷却。首个请求、恢复任务和跨店铺请求都遵守间隔;403、429、导航超时、登录/验证或异常详情页会暂停任务。同一工作区只允许一个 run、resume 或浏览器登录命令操作专用 Profile。
每次 SerpApi 查询都会随机排列 Key 池并选择一个 Key。若该 Key 鉴权失败、额度耗尽或触发限流,程序会自动尝试池内其他 Key;仅当全部 Key 均不可用时,当前查询才失败。配置中的空项和重复 Key 会自动清理。
淘汰率只使用成功判定作为分母:
精确匹配淘汰数 / 成功图片检索数
至少成功搜索 10 件后才允许提前淘汰。默认使用 90% Wilson 置信区间,下界达到 60% 才停止;最终完成时实际淘汰率达到 60% 也会淘汰店铺。检索错误率超过 20% 或商品发现被安全上限截断时进入人工复核。
DeepSeek 导航后备
BROWSER_USE_PROVIDER=deepseek
BROWSER_USE_MODEL=deepseek-chat
BROWSER_USE_VISION_MODE=false
DEEPSEEK_API_KEY=your-key
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
程序优先通过 SourceAdapter 生成商品列表 URL,并用 Playwright 直接打开和机械验证。只有失败时才调用 Browser Use + DeepSeek。
运行
先在专用 Chrome Profile 手工登录并诊断:
storewright-scout browser login
storewright-scout browser diagnose
完全离线 Mock E2E:
storewright-scout run \
--shops shops.csv \
--seed 20260718 \
--mock-vision \
--confirm-authorized
真实运行:
storewright-scout run \
--shops shops.csv \
--seed 20260718 \
--confirm-authorized
恢复与报告:
storewright-scout resume --run-id <uuid> --confirm-authorized
storewright-scout report --run-id <uuid>
storewright-scout rebuild-archives --run-id <uuid>
storewright-scout review list --run-id <uuid>
rebuild-archives 只读取已保存的 HTML,离线补齐结构化价格、属性和 SKU,重建扁平图片目录,不启动浏览器或调用 SerpApi。
成功的查询按 (provider, normalized_image_sha256, variant) 缓存;相同图片不会重复消耗 SerpApi。处理顺序由运行 seed 和店铺 canonical key 决定,恢复后保持不变。
一次已授权的 run/resume 默认连续处理剩余详情,不要求每 5 件重新授权。每件商品独立提交 SQLite,因此仍可从任意检查点恢复。只有显式配置正数 MAX_DETAIL_PRODUCTS_PER_BATCH、检测到登录/验证/阻断页或发生真实错误时才暂停;程序不会尝试处理安全验证。
本地输出
runtime/artifacts/<run_id>/
├── shops.csv
├── products.csv
├── summary.json
├── report.html
├── vision/
└── shops/<shop_key>/products/<item_id>/
├── screening-listing/
├── screening-detail/
├── product.json # 仅合格且类目未满的商品
├── images/ # 001-main.jpg、002-gallery.jpg、003-sku.jpg ...
└── evidence/
├── raw.html
├── image-sources.json
└── original-images/
images/ 只包含按结构化来源筛选、SHA-256/pHash 去重且通过尺寸校验的商品图,不创建逐图子目录。原始页面和图片来源信息放在 evidence/,避免干扰人工挑图。
被淘汰商品保留商品 ID、URL、列表图和 Serp 证据,不保存完整详情资产,因此不需要删除文件。商品状态包括:
qualifiedscreened_qualifiedrejectedreviewskipped_category_quota_reachedskipped_after_shop_rejected
判定边界
- 自身商品、同店页面和图片 CDN 不作为外部精确匹配。
- 外部页面完整图片匹配会淘汰商品。
- 无法映射到外部页面的完整图、局部匹配和搜索错误进入复核。
NO_INDEXED_MATCH_FOUND只表示当前 provider 没有返回精确匹配,不证明互联网不存在同款。- 图片匹配不证明 SKU、材质、质量或知识产权相同。
扩展其他平台
新增数据源时实现 SourceAdapter 与 CatalogBackend:
- 店铺和商品 URL 识别;
- 商品列表入口与 DOM 提取;
- 商品详情结构化解析;
- 自身商品/同店/外部 URL 关系分类;
- 页面和图片获取。
Serp provider、规则引擎、类目配额、店铺止损、SQLite 与报告无需依赖淘宝。
源码开发
git clone https://github.com/HughLee824/storewright.git
cd storewright/tools/product-research/catalog-scout
uv sync
质量检查
uv run ruff check .
uv run pyright
uv run pytest --cov=storewright_catalog_scout
发布流程见 RELEASING.md,版本变化见 CHANGELOG.md。本项目使用 MIT License。
已知限制
- 列表图与详情主图不同会多使用一次 Serp 查询。
- 所有列表图预筛先完成,详情页只按受控速率访问;公开图片下载使用独立 HTTP 客户端,不携带浏览器 Cookie。
- 类目通常在详情页才能可靠获得,因此部分已通过预筛的商品仍需轻量读取详情后才能判断类目名额。
- 页面可识别字段会随平台模板变化;原始 HTML 和结构化数据会随合格商品一起保存,便于重新解析。
- 达到
MAX_POOL_SIZE会标记目录不完整并进入复核,不会声称覆盖全店。 - 不执行购买、收藏、联系卖家或 Shopify 导入。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file storewright_catalog_scout-0.1.2.tar.gz.
File metadata
- Download URL: storewright_catalog_scout-0.1.2.tar.gz
- Upload date:
- Size: 231.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af089845ba901fde8bac515b1f5b70fb19fedf46bf1eb4da7d602f0de381db7e
|
|
| MD5 |
ca6574294fd9e351809832e2e5c246fd
|
|
| BLAKE2b-256 |
17193bfed2d15d27f687c0f62f87d48c94e57e8ca43588629a0c2cbc72d79263
|
File details
Details for the file storewright_catalog_scout-0.1.2-py3-none-any.whl.
File metadata
- Download URL: storewright_catalog_scout-0.1.2-py3-none-any.whl
- Upload date:
- Size: 76.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bdc0983ee73be5073b57cc94af1bb23ee2d79200ddeff1f6555e2ea9487981e8
|
|
| MD5 |
eeeb5146a81dc660155f5998f2e8d7cc
|
|
| BLAKE2b-256 |
d89b1fc128eca3070135f7903d860ccc61c3ff143636996ed348ca3cae8ebce5
|