en un clic
dxm-attributes
店小秘速卖通编辑页——属性信息模块:产品属性批量填(ant-select CDP填充)+ 自定义属性删除
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Menu
店小秘速卖通编辑页——属性信息模块:产品属性批量填(ant-select CDP填充)+ 自定义属性删除
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Basé sur la classification professionnelle SOC
速卖通店铺运营自动化 — 每日巡检/每周策略/商品上架/数据分析全流程。填入你的店铺名即可使用。
店小秘速卖通编辑页——基本信息模块:标题改英文 + 产品分类选择
速卖通上架——1688采集模块:从1688搜索产品 → 采集到店小秘采集箱 → 提取产品参数(价格/库存/重量/材质等)
店小秘速卖通编辑页——店小秘信息模块:来源URL(只读,记录用)
店小秘速卖通上品完整工作流——从采集箱到发布的所有模块编排、调用顺序、区域调价、保存发布
店小秘速卖通编辑页——其他信息模块:半托管/关税/责任人/制造商/资质 + 区域调价 + 保存并移入待发布
| name | dxm-attributes |
| description | 店小秘速卖通编辑页——属性信息模块:产品属性批量填(ant-select CDP填充)+ 自定义属性删除 |
| domain | ecommerce |
| triggers | ["用户说\"填属性\"、\"产品属性\"、\"属性信息\"、\"删自定义属性\"","店小秘编辑页打开后需要填属性信息"] |
CDP browser_cdp 直连。编辑页 target_id 通过 Target.getTargets 获取。
Runtime.evaluate:
const links = document.querySelectorAll('.anchor-menu-item, a');
for (const l of links) {
if (l.textContent.trim() === '属性信息') { l.click(); break; }
}
在填属性之前,需要从1688获取产品参数。
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;
}
Target.createTarget: { url: 1688_URL }
详见 references/1688-json-extraction.md:
window.__INIT_DATA__ 或 <script> 内 JSON2026-07-18/19 血训(两次!):
类名是 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)'
}));
| 属性 | 来源 | 常用值 |
|---|---|---|
| 产地 | 固定 | 中国大陆 |
| 省份 | 固定 | 浙江(义乌产) |
| 品牌 | 固定 | NONE |
| 材质 | 1688 | 硅胶→塑料(无硅胶选项时), 不锈钢, 尼龙等 |
| 高关注化学品 | 固定 | 天然未处理 |
| 类型 | 1688 | 狗狗/猫咪/通用 |
| 液晶显示 | 推断 | 无(No) — 宠物水杯无LCD |
| 最大出餐量 | 推断 | 选中间值(如水杯500g) |
| 最小出餐量 | 推断 | 选最小值(如水杯100g) |
| 是否智能 | 推断 | no(no) — 宠物水杯非智能 |
| 是否包含电池 | 推断 | no(no) — 宠物水杯无电池 |
| 电源 | 推断 | 无数据跳过 |
| 电压 | 1688 | 无数据跳过(共享下拉池重灾区) |
| 动力来源 | 推断 | 无数据跳过 |
| 承受重量 | 1688 | 无数据跳过 |
| 季节/特性 | 1688 | 无数据跳过(这些可能是空下拉) |
首选方案(下拉已初始化时):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
ant-design 的 select dropdown 打开后仍在 DOM 中且有一个透明遮罩。如果不关闭,下一个 select 的 click 会打在遮罩上,完全无效。
❗ CDP 下的关键发现:Input.dispatchKeyEvent Escape 无法关闭 ant-select dropdown。 必须用 JS classList.add('ant-select-dropdown-hidden') 强制隐藏。
店小秘的电压和功率字段共享同一个下拉数据池。如果连续 3 次选不上——停手,开新标签页先填这两个字段,不要死磕。
自定义属性的 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(需 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 真点击。
❌ 已证伪的方法:
element.click() / dispatchEvent('click') → Vue 不认,删不掉Input.dispatchMouseEvent → 坐标难定位classList.add('ant-select-dropdown-hidden') 关闭,CDP Escape 无效!innerText.trim() 而非 textContent.trim()item.querySelector('.ant-select-selector').getBoundingClientRect(),不要用 label 坐标window.context JSON(productPackInfo.fields.pieceWeightScale)+ 页面文本双路径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 检修脚本。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个字段失败,放弃属性模块,先填其他模块,最后通知用户手动修正。 属性字段是店小秘自动化中最脆弱的一环。dd.classList.remove('ant-select-dropdown-hidden') 强制显示后 querySelectorAll('.ant-select-item-option') 返回空数组。必须先Playwright page.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') → 值不持久化keyboard.type() + keyboard.press("Enter") → 值被清空keyboard.press("Tab") → 提交裸字符串,不带括号部分(如 "300" 而非 "300g(300g)")document.execCommand('insertText') → 值被组件截断⚠️ 中文输入: page.keyboard.press("塑") 会报错 Unknown key。中文必须用 page.keyboard.type("塑料")。
已知 auto-complete 字段示例:最大出餐量、材质。
作者: Rigi AI Commons | 小红书 @瑞吉AI人民公社 | AI自动化专家工作流