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 会问你这些:
你自己要先准备好的:
pip install playwright && playwright install chromium"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --remote-debugging-port=9222🏪 店铺路由指引:本技能支持多个店铺,首次使用时 AI 会问你的店铺信息并记住。之后你只需要说「上架到 1 号店」或「2 号店」,AI 会自动匹配对应配置。
当用户第一次说「帮我上货」,你先发这段话确认:
你好!我是你的上货小助手 😄 动手之前,先确认几件事: - ✅ 易店后台打开了没?登录了没? - ✅ 今天要干啥?(加商品?配发货?开关设置?)我能帮你做的事:
我做不到的事:
你想做什么?告诉我就行!
用 Playwright 连到已经打开的 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 自己记住。
每次跑之前检查一下端口能不能连上。
商品配置里 PRODUCT["image"] 只需要传文件名(比如 xxx.jpg),脚本会自动拼接完整路径。
| 脚本 | 干嘛用的 |
|---|---|
full_flow.py | 单个商品发布脚本(一般由 auto_publish.py 自动调) |
publisher.py | 发布函数模块 — publish_product(config) 可以 import 调用 |
auto_publish.py | 自动上货脚本 — 直接调发布函数,一天能上多个商品 |
batch_parser.py | 总清单解析工具 — 把总上货.txt 拆成每天一个文件夹 |
product_parser.py | 旧版解析器(v3.0 已被 batch_parser 替代) |
周末:你把下周要上的货整理到「总上货.txt」
→ AI 跑 batch_parser.py --apply 拆分
→ 你检查一下拆分结果
→ AI 设置好自动化任务
周一到周六:每天到点自动跑
→ 找到还没上架的 day 文件夹
→ 逐个上架里面的商品
→ 上完的移到 done 文件夹
以下为2号店未来一周要上货的货品:
1.商品标题
商品介绍内容...
温馨提示:自动发货...
通过网盘分享的文件:xxx.apk
链接: https://pan.baidu.com/s/xxx 提取码: xxxx
2.下一个商品标题
介绍内容...
你的闲鱼文件夹\
├── 图片资料\ ← 放商品图片
├── 软件包\ ← 放 APK/ZIP 安装包(不是必须)
├── 待上架\
│ ├── 总上货.txt ← 你每周维护的总清单
│ ├── day1\ ← 周一的商品
│ │ └── 商品A.txt
│ ├── day2\ ← 周二的商品
│ │ └── 商品B.txt
│ ├── ...
│ └── done\ ← 已上架的会移到这里
# 先解析总清单
python batch_parser.py --apply
# 再自动上架
python auto_publish.py
脚本最上面有 6 个变量,每次上新货改这里就行:
| 变量 | 意思 | 例子 |
|---|---|---|
TITLE | 宝贝标题 | "XX软件(免广告版)" |
DESC | 宝贝描述(第二行开始写,第一行不要重复标题,不要写网盘链接) | 商品介绍,末尾加"自动发货 24h内发货\n百度网盘发货\n虚拟商品拍下不退不换" |
IMAGE_FILE | 图片文件名 | "商品图.jpg" |
IMAGE_KEYWORD | 图库搜索关键词(模糊匹配) | "商品名" |
PAN_TEXT | 网盘分享完整文本 | 包括文件名、链接、提取码 |
PAN_CODE | 提取码 | "abcd" |
locator.click(force=True)第一张、最后一张 这种位置猜的方式页面: /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遍历所有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)
# 同理选市、区
filter(has_text) 中文经常匹配失败,改用JS直接选:
# 点所属店铺输入框
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)el-radio)el-radio)button.submission(class 包含"submission")locator.click(force=True)页面: /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 emitbutton:has-text("确定")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 步:
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]}')
# 1号店预期: ['开启', '开启', '开启']
# 2号店预期: ['开启', '开启', '关闭'] (2人小刀跳过)
| 版本 | 日期 | 更新内容 |
|---|---|---|
| v3.2 🆕 | 2026-06-23 | 稳定性修复 — 修复2人小刀弹窗精确识别(不再混淆其他弹窗);图库选图增加3次重试机制并确认选中;上传图片增加完整容错流程;所有关键步骤 try/except 包裹防止单步崩溃;2人小刀弹窗增加标题识别+兜底Vue emit方案;自动发货二次点击增加最多3次重试 |
| v3.1 | 2026-06-22 | SkillHub 发布包完善 — 补全 README.md、CHANGELOG.md 等发布必需文件;完整脱敏处理(店铺名/路径/配置参数全部替换为通用占位符);店铺配置改为 AI 引导模式(首次使用由 AI 逐项询问);自动化上货体系改为通用引导(目录/时间/频率由用户自定义);脚本参数保留占位符+注释引导;AI 引导文案通俗化,加入 DSFlash 省流量提示 |
| v3.0 | 2026-06-21 | 全自动化上货体系 — 新增 batch_parser.py(总txt解析+按天拆分)、publisher.py(可import调用的发布函数)、auto_publish.py V2(直接调用发布函数,一天多商品排队上架);新增自动化任务(每周一~六10:00自动运行);图片目录迁移到 图片资料\;新增 MEMORY.md 完整文档记录 |
| v2.7 | 2026-06-20 | 变量配置化 + 自动发货二次点击修复 — 脚本顶部商品配置区(6个变量),上新货只需改配置;上传确定后强制关闭所有弹窗防止遮挡;图库搜索改为模糊匹配 IMAGE_KEYWORD;自动发货保存后检查主开关,没变蓝再点一次 |
| v2.6 🏆 | 2026-06-20 | 全流程验证通过 — 图库上传v3.0重写(set_input_files 直接注入→搜索选中);子进程EOFError修复;高级配置展开/折叠 + 弹窗滚动操作;绑定邮箱弹窗干扰修复;自动发货+售罄上架全链路验证通过 |
| v2.5 | 2026-06-19 | 2号店铺全流程 + 自检规则 — 新增2号店铺配置,图库选图改为直接点图+「使用选中图片」,城市级联改为input.click+遍历menu,店铺选择改用JS evaluate,库存区分,新增脚本硬推自检铁律 |
| v2.4 | 2026-06-19 | 图片精确匹配 + 弹窗修复 — 图片选择改为文件名精确匹配,弹窗确定按钮改为文字匹配,宝贝描述去重,新增IMAGE_DIR常量,自动发货主开关重试机制 |
| v2.3 | 2026-06-18 | 自动发货修复 — 修复自动发货状态开关定位逻辑;完善弹窗内6步操作流程;修复保存按钮选择器 |
| v2.2 | 2026-06-18 | 持久化登录 — 放弃CDP改用launch_persistent_context;图片上传改为图库查重;售价/库存改用JS赋值 |
| 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浏览器