店小秘属性信息模块
SkillDev toolsDianxiaomai (店小秘) AliExpress edit page, attributes info module: bulk-fill product attributes (ant-select CDP fill) + delete custom attributes
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the 店小秘属性信息模块 skill
What this skill tells your AI
The instructions your AI receives, as published by southernspark-nfxh/aliexpress-auto-listing-skill in dxm-attributes/SKILL.md and read by ahel’s review.
环境
CDP browser_cdp 直连。编辑页 target_id 通过 Target.getTargets 获取。
Step 1:切换到属性信息 tab
Runtime.evaluate:
const links = document.querySelectorAll('.anchor-menu-item, a');
for (const l of links) {
if (l.textContent.trim() === '属性信息') { l.click(); break; }
}
Step 2:先开1688查参数(新标签页)
在填属性之前,需要从1688获取产品参数。
获取1688 URL
Runtime.evaluate (在编辑页 target):
const links = document.querySelectorAll('a');
for (const l of links) {
if (l.href && l.href.includes('detail.1688.com')) return l.href;
}
在新标签页打开1688
Target.createTarget: { url: 1688_URL }
提取1688参数
详见 references/1688-json-extraction.md:
- 嵌入JSON正则:
window.__INIT_DATA__或<script>内 JSON - 页面文本提取:货号、重量、品牌、材质、产地
Step 3:填写产品属性
🔴 铁律:先枚举所有星号字段再填,不要声称完成
2026-07-18/19 血训(两次!):
- 填了5个属性就声称「模块3完成」→ 用户指出还有液晶显示、最大出餐量、最小出餐量、是否智能、是否包含电池全部没填。
- 填了7/9就声称完成 → 用户:"你怎么叫验证通过了呢?验证通过是要把所有带星号的选项都要填了,才能叫通过。" 必须先用 DOM query 枚举 ALL 带星号字段,逐项验证填完,9/9才算通过。
检测带星号字段(正确方式)
类名是 span.attr-label.required,不是 .ant-form-item-required!
// 正确检测星号
labelEl.querySelector('span.attr-label.required')
// 完整枚举所有星号字段及当前值
Array.from(document.querySelectorAll('#attrInfo .ant-form-item'))
.filter(item => item.querySelector('span.attr-label.required'))
.map(item => ({
label: item.querySelector('label').innerText.trim(),
value: item.querySelector('.ant-select-selection-item')?.textContent?.trim() || '(empty)'
}));
铁律(按优先级)
- 红色星号必填 — 必须选一个值
- 有下拉选项的都选一个值 — 不能空着
- 填空输入框不填 — 跳过
- 1688有的参数按1688选最接近的值 — 无数据则跳过
- 不知道选什么时选最接近的选项 — 选错用户会纠正
属性值速查
| 属性 | 来源 | 常用值 |
|---|---|---|
| 产地 | 固定 | 中国大陆 |
| 省份 | 固定 | 浙江(义乌产) |
| 品牌 | 固定 | NONE |
| 材质 | 1688 | 硅胶→塑料(无硅胶选项时), 不锈钢, 尼龙等 |
| 高关注化学品 | 固定 | 天然未处理 |
| 类型 | 1688 | 狗狗/猫咪/通用 |
| 液晶显示 | 推断 | 无(No) — 宠物水杯无LCD |
| 最大出餐量 | 推断 | 选中间值(如水杯500g) |
| 最小出餐量 | 推断 | 选最小值(如水杯100g) |
| 是否智能 | 推断 | no(no) — 宠物水杯非智能 |
| 是否包含电池 | 推断 | no(no) — 宠物水杯无电池 |
| 电源 | 推断 | 无数据跳过 |
| 电压 | 1688 | 无数据跳过(共享下拉池重灾区) |
| 动力来源 | 推断 | 无数据跳过 |
| 承受重量 | 1688 | 无数据跳过 |
| 季节/特性 | 1688 | 无数据跳过(这些可能是空下拉) |
CDP 操作:ant-select 下拉填充
首选方案(下拉已初始化时):JS强制显示 + 点击(2026-07-19 验证)
⚠️ 此方案仅当dropdown已有option时有效。 全新编辑页需先Playwright mouse.click打开每个下拉初始化option。
Playwright mouse.click 坐标法在此页面上不可靠(坐标偏移、dropdown不出现、CDP relay频繁断连)。
真正有效的方案是纯JS操作——找到含目标选项的dropdown → 强制显示 → 点击选项。Vue 3会自动拾取点击事件并更新组件状态。
// 批量填充(通过 browser_cdp Runtime.evaluate 执行)
(function(){
var targets = ['中国大陆(Origin)(Mainland China)', 'NONE(NONE)', '无(No)',
'500g(500g)', '100g(100g)', '塑料(Plastic)',
'no(no)', '天然未处理(None)', 'no(no)'];
for (var t = 0; t < targets.length; t++) {
var target = targets[t];
var dds = document.querySelectorAll('.ant-select-dropdown');
for (var i = 0; i < dds.length; i++) {
var dd = dds[i];
var items = dd.querySelectorAll('.ant-select-item-option');
for (var j = 0; j < items.length; j++) {
if (items[j].textContent.trim() === target) {
dd.classList.remove('ant-select-dropdown-hidden');
dd.style.display = '';
dd.style.opacity = '1';
dd.style.pointerEvents = 'auto';
items[j].scrollIntoView({block: 'nearest'});
items[j].click();
items[j].dispatchEvent(new MouseEvent('mousedown', {bubbles: true}));
items[j].dispatchEvent(new MouseEvent('mouseup', {bubbles: true}));
break;
}
}
}
}
})()
⚠️ 批量填充陷阱: 当多个dropdown同时被显示时,no(no) 这类重复选项会匹配到错误的dropdown。对于重复选项值,必须逐个字段填充,每次填充后关闭所有dropdown再填下一个。
⚠️ Dropdown损坏陷阱(2026-07-19 发现): 对 dropdown 频繁执行 dd.style.display='none' + dd.classList.add('ant-select-dropdown-hidden') 会导致所有 dropdown 的 option 数量变为 0(querySelectorAll('.ant-select-item-option').length === 0)。只能重新加载页面才能恢复。 发现 0 items 时不要继续尝试——刷新页面重来。
⚠️ 批量填充后验证: JS批量填充后必须逐字段验证。不要因为8/9就声称"完成"。用户对"验证通过"的定义是所有带星号字段全部填完。
降级方案:Playwright坐标法(CDP relay正常时可用)
1. 【点】获取 selector DOM 坐标,打开下拉
Input.dispatchMouseEvent(type='mousePressed', x, y)
Input.dispatchMouseEvent(type='mouseReleased', x, y)
2. 【选】匹配选项并点击
Runtime.evaluate:
const drops = document.querySelectorAll('.ant-select-dropdown:not(.ant-select-dropdown-hidden)');
for (const d of drops) {
d.querySelectorAll('.ant-select-item-option').forEach(item => {
if (item.textContent.includes('目标值')) { item.click(); }
});
}
3. 【JS隐藏】强制关闭所有dropdown(Escape在CDP下无效!)
Runtime.evaluate:
document.querySelectorAll('.ant-select-dropdown').forEach(d => {
d.classList.add('ant-select-dropdown-hidden');
});
4. 【移动】到下一个 select,重复步骤 1
⚠️ 为什么必须关闭dropdown(下拉残留陷阱 — 2026-06-14 实战验证)
ant-design 的 select dropdown 打开后仍在 DOM 中且有一个透明遮罩。如果不关闭,下一个 select 的 click 会打在遮罩上,完全无效。
❗ CDP 下的关键发现:Input.dispatchKeyEvent Escape 无法关闭 ant-select dropdown。 必须用 JS classList.add('ant-select-dropdown-hidden') 强制隐藏。
⚠️ 电压/功率是共享下拉池重灾区
店小秘的电压和功率字段共享同一个下拉数据池。如果连续 3 次选不上——停手,开新标签页先填这两个字段,不要死磕。
Step 4:删除自定义属性
检测自定义属性是否存在
自定义属性的 DOM 结构不是 .ant-tag,而是 div.custom-attr-item。每行含两个 <input>(属性名/属性值)和一个关闭按钮。
查询(browser_cdp Runtime.evaluate):
(function(){
var items = document.querySelectorAll('#attrInfo .custom-attr-item');
var vals = [];
items.forEach(function(a){
var inputs = a.querySelectorAll('input');
if (inputs.length >= 2) vals.push(inputs[0].value + '=' + inputs[1].value);
});
return JSON.stringify(vals);
})()
实测有效方法:Playwright locator 逐条删除(2026-07-19 验证)
「批量操作→删除全部→确 定」路径未经实测验证。实际验证有效的方案是直接逐条点击关闭图标:
# Playwright(需 CDP relay 正常)
# 1. 滚动到自定义属性区域
await page.evaluate("document.querySelector('#attrInfo .smtCustomAttrs').scrollIntoView({block: 'center'})")
# 2. 获取自定义属性总数
count = await page.evaluate("document.querySelectorAll('#attrInfo .custom-attr-item').length")
# 3. 逐个点击关闭图标(.icon_close 类名,不是 .anticon-close!)
for i in range(count):
close_btn = page.locator("#attrInfo .custom-attr-item .icon_close").first
await close_btn.click(force=True, timeout=3000)
await asyncio.sleep(0.3)
# 4. 验证
remaining = await page.evaluate("document.querySelectorAll('#attrInfo .custom-attr-item').length")
⚠️ 关闭按钮类名是 iconfont icon_close,不是 .anticon-close 或 .ant-tag-close-icon! JS element.click() 无效——Vue 组件需要 Playwright 真点击。
❌ 已证伪的方法:
- JS
element.click()/dispatchEvent('click')→ Vue 不认,删不掉 Input.dispatchMouseEvent→ 坐标难定位
⚠️ 已知坑点
- 下拉残留 — 必须用 JS
classList.add('ant-select-dropdown-hidden')关闭,CDP Escape 无效! - 电压/功率共享池 — 卡3次就开新页
- JS click 对 antd 无效 — 必须用 Playwright 真点击(或对普通 select 用 JS 强制显示 dropdown + click)
- 弹窗「确 定」有空格 — 用
innerText.trim()而非textContent.trim() - 填空输入框不填 — 1688无数据的输入框直接跳过
- 同一操作不超3次 — 3次不成功停手汇报
- ant-select 坐标需精确定位 — 用
item.querySelector('.ant-select-selector').getBoundingClientRect(),不要用 label 坐标 - 1688参数提取 — 用
window.contextJSON(productPackInfo.fields.pieceWeightScale)+ 页面文本双路径 - 🔧 auto-complete 型 select 填充方法 — 见上方专节
- 🚨 CDP relay 断连(2026-07-19 发现) — Playwright
connect_over_cdp('http://127.0.0.1:19223')偶发超时(3分钟超时),症状为所有后续 Playwright 操作全部失败。此时必须检修 relay 链路:kill relay进程 → taskkill chrome → 重启Chrome(带--remote-debugging-port=9222) → 重启Relay2.exe → 重启WSL relay → 更新browser.cdp_url。参考aliexpress-store-ops/references/chrome-cdp-relay.md检修脚本。 - Dropdown 损坏后只能刷页 — 对 dropdown 频繁 classList.add/remove 会导致 option count 归零。发现 0 items 时刷新页面重来(7个已填字段也会丢失)。
- 🔴 属性下拉共享池乱串(2026-07-19新增——高频):
selector.click()+dispatchEvent(MouseEvent)能打开dropdown,但querySelectorAll('.ant-select-dropdown')可能返回错误字段的dropdown。表现:点品牌→dropdown显示产地选项,点最大出餐→dropdown显示液晶选项。唯一有效缓解: ①每次操作前classList.add('ant-select-dropdown-hidden')强制关闭所有dropdown ②用dds[dds.length-1]取最新打开的dropdown ③每字段等待1.5s以上让Vue渲染完毕。但即使遵守以上规则,成功率仍非100%。如连续3个字段失败,放弃属性模块,先填其他模块,最后通知用户手动修正。 属性字段是店小秘自动化中最脆弱的一环。 - 🔴 JS强制显示dropdown在全新页面上无效(2026-07-19): 新鲜加载的编辑页上,ant-select的dropdown里还没有option元素(未初始化)。JS
dd.classList.remove('ant-select-dropdown-hidden')强制显示后querySelectorAll('.ant-select-item-option')返回空数组。必须先Playwrightpage.mouse.click(selector坐标)打开下拉 → option渲染到DOM → 再用JS或keyboard选值。 此问题仅在首次填写时出现,之前填过的字段仍有option残留。
✅ 唯一有效方法:Playwright keyboard.type() + 点击空白处 blur(不要按 Enter!)
1. page.mouse.click(selector坐标) → 打开并聚焦
2. page.keyboard.press("Control+a") → 全选
3. page.keyboard.press("Backspace") → 清空
4. page.keyboard.type("300g", delay=40~80) → 逐字符键入
5. await asyncio.sleep(1.5) → 等 auto-complete 匹配
6. page.mouse.click(500, 100) → 点页面空白处 blur 提交(⚠️ 不能按 Enter!)
🚨 关键坑:不能按 Enter! Enter 会清空 auto-complete 的值。正确做法是点击页面其他地方让 input 失去焦点(blur),Vue 会在 blur 时提交值。
验证 auto-complete: 值存储在 input.value 中,不在 .ant-select-selection-item 中。验证代码必须分别处理:
const item = sel.querySelector('.ant-select-selection-item');
const inp = sel.querySelector('input');
const val = (item && item.textContent.trim()) || (inp && inp.value) || '';
const filled = val !== '' && !sel.querySelector('.ant-select-selection-placeholder')?.offsetParent;
❌ 已证伪的方法:
nativeInputValueSetter+dispatchEvent('input')→ 值不持久化- JS 强制显示 dropdown + click 选项 → Vue 不认
keyboard.type()+keyboard.press("Enter")→ 值被清空keyboard.press("Tab")→ 提交裸字符串,不带括号部分(如 "300" 而非 "300g(300g)")document.execCommand('insertText')→ 值被组件截断
⚠️ 中文输入: page.keyboard.press("塑") 会报错 Unknown key。中文必须用 page.keyboard.type("塑料")。
已知 auto-complete 字段示例:最大出餐量、材质。
作者: 南方星火 SouthernSpark | 小红书 @南方星火 SouthernSpark | AI自动化专家工作流
Signals
- GitHub stars
- 21
- Forks
- 3
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
dxm-attributes- Source
- github.com/southernspark-nfxh/aliexpress-auto-listing-skill