Install
openclaw skills install @yuhao1443796193-commits/yidian-uploadAutomates batch uploading and management of Xianyu shop products on Yidian backend using Playwright, with stepwise confirmation and screenshot validation.
openclaw skills install @yuhao1443796193-commits/yidian-upload🏪 店铺路由指引:本技能同时支持多个店铺,根据用户提到的店铺名自动匹配配置。
- 店铺名和配置由用户在首次使用时提供,AI 会引导用户填写店铺名、库存、售价等参数
- 之后每次说「上架到XX店」,AI 自动匹配对应配置
当用户第一次请求操作易店上货时,发送以下确认:
你好!我是易店上货操作顾问。 在开始操作前,请确认以下几点: - ✅ 易店后台已打开并登录(ekadmin 页面可见) - ✅ 你知道需要执行什么操作(添加商品/配置发货/开关设置...) **📋 我擅长这些场景:** - ✅ 闲鱼批量添加商品(标题+描述+图片+城市+规格+售价) - ✅ 自动发货 + 网盘链接配置(含重试机制) - ✅ 2人小刀开关配置 - ✅ 售罄自动上架开关 - ✅ 一键完整流程(发布+配置全自动) - ✅ 界面状态截图诊断 **⚠️ 我无法做到:** - ❌ 直接操控闲鱼网页/APP - ❌ 自动识别登录验证码 - ❌ 并行操作多个商品(每次只处理一个) 请告诉我你想做什么操作!当前版本使用 Playwright CDP 连接已有 Edge 浏览器(持久化登录态):
from playwright.sync_api import sync_playwright
p = sync_playwright().start()
browser = p.chromium.connect_over_cdp("http://127.0.0.1:9222")
page = browser.contexts[0].pages[0]
Edge 需以 --remote-debugging-port=9222 启动,登录态由 Edge 持久化保存。
每次运行前检查 CDP 端口是否可用。
图片目录在首次配置时由用户指定(如 图片资料/),商品配置中的 PRODUCT["image"] 只需传文件名(含扩展名),脚本自动拼接完整路径。
脚本位于工作区(如 scripts/):
| 脚本 | 说明 |
|---|---|
full_flow.py | 单商品发布脚本(不再直接使用,由auto_publish.py自动更新配置区) |
publisher.py | 发布函数模块 — publish_product(config) 可直接 import 调用,不走子进程 |
auto_publish.py | 自动上货脚本V3 — 直接调用发布函数,支持日期过滤+已发布标记+已上架记录去重 |
batch_parser.py | 总txt解析+按天拆分工具 v3.3 — 支持新旧两种格式,自动识别,跳过已发布标记 |
product_parser.py | 单商品三段式配置解析器(v2.0遗留,v3.0由batch_parser替代) |
python full_flow.py
配置参数在首次使用时由 AI 引导用户逐项填写,包括:
| 功能 | 说明 |
|---|---|
| 日期过滤 | 总txt中写"一、发布时间:6.23",脚本只上当天商品 |
| 已发布标记 | 上架后自动在总txt中追加「已发布」,下次跳过 |
| 已上架记录 | 写入 已上架记录.txt,防重复上架 |
| 多格式支持 | 自动识别新旧两种格式(数字. 或 一/二/三/四) |
| 商品级店铺 | 新版格式每个商品可独立指定店铺 |
| dispatchEvent选店铺 | 绕过Element UI teleport不可见问题 |
| getComputedStyle检测弹窗 | 比offsetParent更可靠的弹窗检测 |
周末:你更新总上货.txt
→ 跑 batch_parser.py --apply 拆分
→ 你确认拆分结果
→ 设置自动化任务
每天定时:auto_publish.py 自动运行
→ 找到最小 dayN 文件夹
→ 只处理当天日期的商品(如有日期字段)
→ 跳过已上架记录中的商品
→ 逐个上架并标记已发布
→ 完成后移入 done/
新版格式(自动识别,建议使用):
一、发布时间:6.23
二、商品文案:
UPDF 专业版永久激活码
支持 Windows/Mac/iOS/Android 全平台
温馨提示:自动发货 24h内发货
三、店铺:2号店
四、网盘发货文案:
通过网盘分享的文件:xxx.txt
链接:https://pan.baidu.com/s/xxxxx
提取码:abcd
一、发布时间:6.24
二、商品文案:
商品标题
商品介绍内容...
三、店铺:1号店
四、网盘发货文案:
通过网盘分享的文件:xxx.txt
链接:https://pan.baidu.com/s/yyyyy
提取码:efgh
格式要点:
旧版格式(向后兼容):
以下为2号店未来一周要上货的货品:
1.标题
描述内容...
通过网盘分享的文件:xxx
链接: https://... 提取码: xxxx
2.标题
描述内容...
通过网盘分享的文件:xxx
链接: https://... 提取码: xxxx
你的闲鱼文件夹\
├── 图片资料\ ← 所有商品图片
├── 软件包\ ← APK/ZIP安装包
├── 待上架\
│ ├── 总上货.txt ← 你每周维护的总清单
│ ├── day1\ ← 周一商品
│ │ └── 商品A.txt
│ ├── day2\ ← 周二商品
│ │ └── 商品B.txt
│ ├── ...
│ └── done\ ← 已上架的
python auto_publish.py
脚本顶部有6个变量,每次上新货只需改这里:
| 变量 | 含义 | 示例 |
|---|---|---|
TITLE | 宝贝标题 | "商品名称(免广告版)" |
DESC | 宝贝描述(从第二行开始写,第一行不要重复标题,不含网盘链接) | 商品简介开头,末尾加"自动发货 24h内发货\n百度网盘发货\n虚拟商品拍下不退不换" |
IMAGE_FILE | 图片文件名 | "商品图.jpg" |
IMAGE_KEYWORD | 图库搜索关键字(模糊匹配) | "商品名" — 匹配被截断的文件名 |
PAN_TEXT | 网盘分享完整文本 | 包含文件名、链接、提取码 |
PAN_CODE | 提取码 | "abcd" |
page.screenshot() 截图page.evaluate 返回 false 就反复重试点击locator.click(force=True),这是已验证的方式imgs[0] / imgs[length-1] 等位置猜测方式IMAGE_DIR 常量自动拼接页面: /ekadmin/product/add_product
图库中已有图片时,直接选中已有图片,不要重复上传。
打开图片管理弹窗
触发元素: .upLoad(class 包含 upLoad 的 div)
调用: page.locator('.upLoad').first.click(force=True)
弹窗: aria-label="图片管理", z-index=2019
选中第一张图片
page.evaluate("""() => {
const imgs = document.querySelectorAll('img');
for (const img of imgs) {
if (img.width > 80 && img.height > 80) { img.click(); return true; }
}
return false;
}""")
点击「使用选中图片」按钮(不是"确定")
page.evaluate("""() => {
const btns = document.querySelectorAll('button');
for (const b of btns) {
if (b.innerText.includes('使用选中图片')) { b.click(); return true; }
}
return false;
}""")
⚠️ 重要: 图库不要反复上传图片。先通过文件名匹配检查图库中是否已有图片,有则直接选中,无才考虑上传。
定位城市是 el-cascader 组件,需要点三次(省/市/区):
打开城市级联 — 点击 el-cascader 内的 input:
city_input = page.locator('.el-form-item').filter(has_text="定位城市").locator('.el-cascader input').first
city_input.click()
time.sleep(2)
依次点击省/市/区节点(用JS evaluate遍历所有menu):
# 广东省
page.evaluate("""() => {
const menus = document.querySelectorAll('.el-cascader-menu');
for (const menu of menus) {
for (const n of menu.querySelectorAll('.el-cascader-node')) {
const label = n.querySelector('.el-cascader-node__label');
if (label && label.innerText.trim() === '广东省') { n.click(); return true; }
}
}
return false;
}""")
time.sleep(2)
# 同理选广州市、海珠区
💡 注意: 用
input.click()打开菜单比直接点el-cascader更可靠。不要用menus[1]这种索引方式,改为遍历所有menu。
filter(has_text) 因中文编码问题经常匹配失败,改用JS evaluate直接选择:
# 点击所属店铺输入框
page.evaluate("""() => {
const labels = document.querySelectorAll('.el-form-item__label');
for (const label of labels) {
if (label.innerText.includes('所属店铺')) {
const fi = label.closest('.el-form-item');
if (fi) { const inp = fi.querySelector('input'); if (inp) inp.click(); return true; }
}
}
return false;
}""")
time.sleep(2)
# 选择目标店铺
shop_name = "店铺名" # 根据用户配置替换
page.evaluate(f"""() => {{
const items = document.querySelectorAll('.el-select-dropdown__item');
for (const item of items) {{
if (item.innerText.includes('{shop_name}')) {{
item.click();
return true;
}}
}}
return false;
}}""")
input[placeholder*="宝贝标题"])textarea[placeholder*="宝贝描述"])el-select,filter(has_text)可能失败,需遍历label文字)el-radio)el-radio)button.submission(class 包含"submission")locator.click(force=True),不是 JS click页面: /ekadmin/product/product_list
| 索引 | 内容 |
|---|---|
| 0 | 选择框 |
| 1 | ID |
| 2 | 店铺 |
| 3 | 商品ID |
| 4 | 商品图 |
| 5 | 名称 |
| 6 | 售价 |
| 7 | 曝光 |
| 8 | 浏览 |
| 9 | 想要 |
| 10 | 自动发货 |
| 11 | 售罄上架 |
| 12 | 2人小刀 |
| 13 | 发布日期 |
| 14 | 更新时间 |
| 15 | 操作列(更多) |
locator.click(force=True);若不生效,改用 Vue emit 方式sleep(2) 再检查弹窗button:has-text("确定"),避免 CSS 选择器失效page.evaluate("() => {
var tr = document.querySelector('.el-table__body-wrapper tbody tr:first-child');
var tds = tr.querySelectorAll('td');
var sw = tds[COL_IDX].querySelector('.el-switch');
var vm = sw.__vue__;
vm.value = 1;
vm.$emit('input', 1);
vm.$emit('change', 1);
}")
td[10] .el-switch如需配置网盘内容,弹窗内6步操作:
button:has-text("保存"))→ 截图确认弹窗关闭td[11] .el-switch → 截图确认td[12] .el-switch → 截图确认| 弹窗 | 含义 |
|---|---|
| addproduct-dialog | 网盘配置面板 |
| groupon-dialog | 2人小刀金额 |
| 绑定邮箱弹窗 | 干扰弹窗,直接关闭 |
r = page.evaluate('()=>{var t=document.querySelector(".el-table__body-wrapper tbody tr").querySelectorAll("td");return[t[10].innerText,t[11].innerText,t[12].innerText]}')
# 预期: 根据店铺配置决定
python switch_version.py # 查看当前版本
python switch_version.py v3.2 # 切换到 v3.2
python switch_version.py v3.3 # 切换到 v3.3
python switch_version.py --restore # 从 .version_backup/ 恢复
切换前自动备份当前版本到 .version_backup/。
桌面版本库是存档目录,每个版本是独立的文件夹,直接用对应版本目录下的脚本即可。
| 版本 | 日期 | 更新内容 |
|---|---|---|
| v3.3 🆕 | 2026-06-22 | 整合沛神优化 — 新增日期过滤(一、发布时间),支持商品级店铺(三、店铺),已发布标记自动跳过("已发布"防重复),自动识别新旧两种格式;auto_publish.py新增日期过滤+已上架记录去重+已发布标记写回;publisher.py新增dispatchEvent选店铺(绕过teleport)+getComputedStyle弹窗检测;桌面发布版同步更新至v3.3 |
| v3.2 | 2026-06-22 | 稳定性修复 — 2人小刀三级兜底机制(force click → Vue emit → 超时重试);图库选图重试机制(匹配不到自动上传);全局try/except包裹降低崩溃率;Skill文档同步更新 |
| v3.1 | 2026-06-22 | SkillHub 发布包完善 — 补全 README.md、CHANGELOG.md 等发布必需文件;完整脱敏处理;店铺配置改为 AI 引导模式;自动化上货体系改为通用引导;脚本参数保留占位符+注释引导 |
| v3.0 | 2026-06-21 | 全自动化上货体系 — 新增 batch_parser.py(总txt解析+按天拆分)、publisher.py(可import调用的发布函数)、auto_publish.py V2(直接调用发布函数,一天多商品排队上架);新增自动化任务配置;图片目录迁移到 图片资料\ |
| v2.7 | 2026-06-20 | 变量配置化 + 自动发货二次点击修复 — 脚本顶部商品配置区(6个变量),上新货只需改配置;上传确定后强制关闭所有弹窗防止遮挡;图库搜索改为模糊匹配 IMAGE_KEYWORD;自动发货保存后检查主开关,没变蓝再点一次 |
| v2.6 🏆 | 2026-06-20 | 全流程验证通过 — 图库上传v3.0重写(set_input_files 直接注入→搜索选中);子进程EOFError修复;高级配置展开/折叠(非标签页)+弹窗滚动操作;绑定邮箱弹窗干扰修复;checkbox/radio全面搜索策略 |
| v2.5 | 2026-06-19 | 2号店铺全流程 + 自检规则 — 新增2号店铺配置,图库选图改为直接点图+「使用选中图片」,城市级联改为input.click+遍历menu,店铺选择改用JS evaluate,库存区分1号店9999/2号店1,新增脚本硬推自检铁律 |
| v2.4 | 2026-06-19 | 图片精确匹配 + 弹窗修复 — 图片选择改为文件名精确匹配,禁止回退位置猜测;弹窗确定按钮改为文字匹配(非CSS选择器);宝贝描述去重(不含标题);新增IMAGE_DIR常量;自动发货主开关重试机制;售罄上架策略回调修正 |
| v2.3 | 2026-06-18 | 自动发货修复 — 修复自动发货状态开关定位逻辑;完善弹窗内6步操作流程;修复保存按钮选择器 |
| v2.2 | 2026-06-18 | 持久化登录 — 放弃CDP改用launch_persistent_context;图片上传改为图库查重;售价/库存改用JS赋值;创建串联脚本yidian_full_flow.py |
| v2.1 | 2026-06-18 | 双脚本对齐 — 对齐SKILL.md流程;修复中文选择器编码;确立6条铁律 |
| v2.0 | 2026-06-17 | 首次Python实现 — 初始Playwright脚本,CDP连接浏览器,基础发布+配置功能 |
| v1.0~v1.3 | 2026-06-12~06-18 | SKILL.md 文档阶段,定义自动化流程规范和操作经验 |
connect_over_cdp 连接已有Edge浏览器,登录态由Edge持久化imgs[0]/imgs[length-1] 方式已废弃,改为文件名精确匹配menus[1]/menus[2]/menus[3] 方式已废弃,改为遍历所有menu┌──────────────┐ ┌──────────────────┐
│ WorkBuddy │ ──→ │ 飞书文档(镜像) │
│ SKILL.md │ (主)│ │
└──────────────┘ └──────────────────┘
同步规则:以 WorkBuddy SKILL.md 为中心,单向推送到飞书文档。
~/.workbuddy/skills/yidian-upload/SKILL.md)— 所有修改都在这里进行,当前版本 v3.3需要同步时,告诉 AI 即可。AI 会读取 SKILL.md 内容,整理后写入飞书文档。