8.8 KiB
8.8 KiB
id, title, phase, deps, status, created
| id | title | phase | deps | status | created | ||
|---|---|---|---|---|---|---|---|
| T-632 | ①采集短标题就绪识别与页面错误诊断修复 | 2 |
|
TODO | 2026-07-14 |
问题 / 背景
最新代码采集商品 48363984966 时,账号 Chrome/CDP 连通正常,程序打开的商品详情 tab 也已加载成功,但任务在约 63 秒后失败:
step=wait_ready result=failed
detail=等待蝦皮商品编辑器就绪超时:此物流選項不支援較長備貨商品
运行事件只进入 open_product -> wait_ready,尚未执行 read_title、read_cover 或 download_cover。用户导出的商品图片区域 HTML 与实时只读 CDP 探查确认:
- 主图区域存在
data-product-edit-field-unique-id="images",其中有 5 个可拖拽.shopee-image-manager__itembox;5 张图片均已取得susercontentCDN 地址。 - 该业务字段范围内存在 1 个主图上传 input;当前
read_cover_src()也能正常取得第一张封面 URL。因此图片未加载和封面下载不是本次失败原因。 - 页面商品名称输入框位于
data-product-edit-field-unique-id="name"下,真实value/modelvalue长度为 20。 app/editor.py当前TITLE_XPATH使用string-length(@modelvalue)>24猜测标题输入框;该商品命中数为 0,导致JS_READY即使图片和上传入口均存在也持续返回false。- 用
data-product-edit-field-unique-id="name"作为标题业务字段定位后,实时页面准确命中 1 个标题输入框,标题/5张图片/上传入口三项就绪判断立即为true。
错误末尾的“此物流選項不支援較長備貨商品”不是页面未加载原因。_open_product_ready_error() 当前在没有商品失效 toast 时,会把缓存中的最后一条任意 toast 直接拼到就绪超时后面;物流、备货或表单校验提示因此可能被误报为采集失败根因。
方案
1. 标题输入框改用业务字段定位
- 标题主定位改为
data-product-edit-field-unique-id="name"范围内的文本输入框,例如:
//*[@data-product-edit-field-unique-id='name']
//input[contains(concat(' ', normalize-space(@class), ' '), ' eds-input__input ')]
- 不再用标题字符数判断输入框身份;1~24 字、空值编辑态和长标题都必须识别到同一个商品名称字段。
- 不使用“页面第一个
.eds-input__input”或中文商品名稱label 作为唯一定位,避免规格、价格、库存输入框误命中和站点语言变化。 - 为兼容尚未带
data-product-edit-field-unique-id的旧页面,在主定位不存在时才回退当前已验证的旧 XPath;主定位命中时不得再通过长度启发式改选其他输入框。 - 抽取单一标题定位事实,让
JS_READY、JS_TITLE_STATE、read_title()和change_title()共用;禁止采集、就绪判断和③更新各维护一份不同选择器。 - 若主定位命中多个可见标题输入框,返回明确诊断并停止,不猜测写入其中任意一个。
2. 主图区域限定到 images 业务字段
- 商品主图优先限定在
data-product-edit-field-unique-id="images"业务字段内,再读取:.shopee-image-manager;- 可拖拽且
data-draggable="true"的主图 itembox; .shopee-image-manager__upload input[type=file]。
- 实时页面全局共有多个文件 input,但
images业务字段内只有 1 个主图上传入口;就绪判断、读取封面、图片矩形、上传状态和点击上传块必须指向同一个主图 manager,不能由全局querySelector()分别命中不同图片组件。 - 对缺少业务字段属性的旧页面保留现有 itembox/upload 选择器回退;回退只能在业务字段根不存在时启用。
- 本节只收敛选择范围,不改变③更新封面的删除第一张、上传、等待 CDN、拖到第一位和点击更新流程。
3. 就绪判断返回可诊断快照
- 将当前只返回布尔值的
JS_READY扩展为共享的就绪状态快照,至少包含:- 商品名称主定位/回退定位命中数;
- 主图业务字段是否存在;
- 已加载主图数量及 CDN/blob 概况;
- 主图上传 input 是否存在;
- 当前 URL。
_wait_ready()仍按现有最多 60 秒预算轮询,不增加固定 sleep、不切换 Chrome 前台;成功条件仍为标题字段、至少一张商品主图和主图上传入口同时存在。- 超时时按最后快照给出具体中文原因,例如:
商品编辑器未就绪:未识别商品名称输入框;商品图片5张;主图上传入口正常
- 诊断快照写入现有
run_log_events和本地脱敏日志,不保存标题全文、Cookie、token、上传文件内容或页面整份 HTML。
4. 区分页面错误与无关 toast
- 保持 T-404b 既有规则:明确商品失效、商品不存在、无权限或店铺不匹配类 toast,即使已经自动隐藏,也可作为
open_product()的主要失败原因并驱动①列表显示“商品失效”。 - 非商品失效类 toast 不得无条件覆盖就绪快照。物流、较长备货、库存、价格、标题校验、图片重复等编辑表单提示不能被描述为“商品页加载失败”。
- 未分类 toast 只有在当前仍可见且与本次导航/页面打开直接相关时,才可作为附加“页面提示”显示;已经隐藏的普通 toast 只保留在脱敏诊断 payload,不拼成用户可见的主要错误原因。
- 若同时存在明确商品失效 toast 和选择器缺失,商品失效优先;否则优先显示缺失的就绪组件,并把普通 toast 标为可能无关的诊断信息。
5. 测试与真实页面验证
- 更新 editor 单元测试,覆盖:
- 20 字及 1~24 字短标题通过业务字段主定位并判定页面就绪;
- 长标题仍命中同一业务字段;
- 旧 DOM 缺少业务字段时旧 XPath 回退仍可用;
- 页面有大量规格/价格/库存
.eds-input__input时不误选; - 主定位命中多个候选时明确失败,不猜测;
read_title()与change_title()使用同一标题节点,并继续校验value == modelvalue == 新标题;- 主图业务字段内图片、上传 input 和上传状态来自同一个 manager;旧 DOM 回退不回归;
- 图片与上传入口正常、仅标题旧启发式不命中的页面,会报告“未识别商品名称输入框”;
- 隐藏的“此物流選項不支援較長備貨商品”不再成为加载失败主因;明确商品失效 toast 仍按 T-404b 上浮。
- 使用商品
48363984966做只读 CDP 验证:新就绪快照须为标题1个、主图5张、主图上传入口1个;read_title()非空、read_cover_src()为susercontent,①采集可进入read_title/read_cover/download_cover/db_write并成功关闭本轮自动创建 tab。 - 标题写入路径只在仓库指定测试商品或 mock 中验证,不在该运营商品上点击「更新」提交;测试商品失效导致实跑不可用时如实记录限制。
- 选择器变化后同步
docs/04-architecture.md第七节与docs/api.md,不得继续把标题长度启发式记作当前唯一已验证事实。
验收要点
- 标题不足25个字符的有效商品不再卡在
wait_ready;页面图片已加载时能正常采集标题和第一张封面。 - 标题识别基于
name业务字段,不会误选规格、价格、库存、物流或货号输入框;旧页面仍有受控回退。 - 商品名称、主图 itembox 和上传入口分别来自明确业务字段,且所有读写/就绪脚本复用同一定位事实。
- 就绪超时能明确指出标题、主图或上传入口哪一项缺失,不再只显示泛化超时。
- 物流/备货等无关且已隐藏 toast 不再伪装成商品页面加载失败;商品失效/无权限 toast 捕获不回归。
- 不改变①后台采集、不切前台、只关闭程序自动创建 tab的策略;不改变③封面上传、拖拽、确认和线上提交边界。
- 自动验证:
py -3.10 -m unittest tests.test_editor_loginpy -3.10 -m unittest tests.test_guipy -3.10 -m unittest discover -s testspython -m ruff check app tests main.pypy -3.10 -m compileall app main.pygit diff --check
边界(不改什么)
- 不通过降低为
document.readyState、只检查 URL 或取消关键字段检查来掩盖问题。 - 不通过固定等待更久、把60秒改得更大或切换 Chrome 前台解决选择器错误。
- 不修改登录检测、账号 Chrome 启动、只读 tab 生命周期或①采集并发策略。
- 不修改③删除第一张封面、上传、拖拽第一位、更新确认框和成功后关闭 tab 的业务顺序,不点击线上「更新」做本任务验收。
- 不修改 SQLite/Excel schema、AI/cmhub、提示词或 GUI 布局。
- 不提交用户导出的
48363984966.html、运营 Excel、data/日志、账号登录态或其他业务数据。