妙手导入采集打通:xls 8 列(产品主编号/链接地址/标题/货币类型/SKU售价/SKU库存/价格/促销价)解析成功 47/0/47
This commit is contained in:
1 parent
69c7ee5fd5
commit
bfc1caac00
4 files changed
+69
No files matched your search
@@ -130,3 +130,32 @@ await c.send('DOM.setFileInputFiles', { files: ['/path/ms_import.csv'], nodeId }
|
||||
|
||||
### 当前队列状态
|
||||
已导入文件列表里有 3 条失败任务(`ms_import` / `ms_import2` / `ms_nobom`),可在页面上「删除文件」清掉。
|
||||
|
||||
## ✅✅ 导入链接采集终于通了:`ms2.xls` 解析成功 47/0/47(2026-09-21 08:55)
|
||||
|
||||
### 能用的 .xls 表头(**照抄这 8 列**)
|
||||
| 列 | 示例值 | 说明 |
|
||||
|---|---|---|
|
||||
| `产品主编号` | `548459586741` | 1688 商品 id,**必须**有 |
|
||||
| `链接地址(必填)` | `https://detail.1688.com/offer/548459586741.html` | 采集源链接 |
|
||||
| `产品标题` | 英文标题 | 可留空(留空以来源为准) |
|
||||
| `货币类型` | `CNY` | **必须**;空值报「不允许此货币类型」 |
|
||||
| `SKU售价` | `34.0` | **必须 ≥ 0.01**;空值报「必须大于等于0.01」 |
|
||||
| `SKU库存` | `999` | **必须 ≥ 0** |
|
||||
| `价格(RMB)` | `34.0` | 模板原有列 |
|
||||
| `促销价(RMB)` | 空 | 模板原有列(表头提示:仅可用于采集到 Lazada) |
|
||||
|
||||
### 关键结论(下一轮别再走弯路)
|
||||
1. **必须是 `.xls`/`.xlsx` 二进制表格**——CSV 一律只报「未识别到【产品主编号】表头」,`txt` 走 JSON 也走不通;
|
||||
2. **页面下载的模板是旧的**:它只有 4 列、**缺 `产品主编号`**,照它填一定失败
|
||||
(错误提示会写「请下载最新模版」,但最新模板实际要的就是上面这 8 列);
|
||||
3. 生成脚本:`pip install --break-system-packages xlwt` → `xlwt.Workbook(encoding='utf-8')` → 写表头+47 行 →
|
||||
存 `.xls` → 用 `DOM.setFileInputFiles` 注入 `input.jx-upload__input` → 点「确认」;
|
||||
4. 失败时**点「查看失败原因」**能看到逐行逐列的精确原因(这次就是靠它拿到 `货币类型/SKU售价/SKU库存` 三个列名)。
|
||||
|
||||
### 产物
|
||||
`/home/admin9webs/miaoshou/dl/ms2.xls`(47 行,可复用为模板);上传脚本 `ms_upload.mjs`;
|
||||
状态查询 `ms_status.mjs`;失败原因 `ms_reason.mjs`。
|
||||
|
||||
### 下一步
|
||||
「查看导入产品」/ **公用采集箱** 里核对这 47 条采集结果,再验证子账号能否 `认领`/`发布`。
|
||||
@@ -0,0 +1,20 @@
|
||||
import { listPages, wait } from '/home/admin9webs/shein建品/sh_lib.mjs';
|
||||
import { CDP, SAN as S } from '/tmp/cdp3.mjs';
|
||||
const t = (await listPages()).find(x=>/91miaoshou/i.test(x.url));
|
||||
const c = await CDP.connect(t.webSocketDebuggerUrl);
|
||||
await c.send('Page.enable'); await c.send('Runtime.enable'); await wait(1200);
|
||||
console.log('点查看导入产品:', String(await c.evalJS(`(()=>{
|
||||
const rows=[...document.querySelectorAll('tr')].filter(e=>e.offsetParent!==null&&/^\\s*ms2\\s/.test((e.innerText||'').trim()));
|
||||
const row=rows[0]; if(!row) return 'no-row';
|
||||
const a=[...row.querySelectorAll('*')].find(e=>(e.innerText||'').trim()==='查看导入产品');
|
||||
if(!a) return 'no-link';
|
||||
for(const ev of ['mousedown','mouseup','click']) a.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window})); return 'clicked';})()`)));
|
||||
await wait(7000);
|
||||
const o = await c.evalJS(`(()=>{
|
||||
const rows=[...document.querySelectorAll('tr')].filter(e=>e.offsetParent!==null).map(e=>(e.innerText||'').replace(/\\s+/g,' ').trim()).filter(Boolean).slice(0,5);
|
||||
const tabs=[...document.querySelectorAll('[class*=tab]')].filter(e=>e.offsetParent!==null).map(e=>(e.innerText||'').replace(/\\s+/g,' ').trim().slice(0,10)).filter(Boolean);
|
||||
return JSON.stringify({href:location.href, rows, tabs:[...new Set(tabs)].slice(0,10),
|
||||
body:(document.body.innerText||'').replace(/\\s+/g,' ').trim().slice(0,200)});})()`);
|
||||
console.log('导入产品:', S(String(o)).slice(0,1000));
|
||||
try{ await c.shot('/tmp/ms_items.jpg'); console.log('shot ok'); }catch(e){}
|
||||
process.exit(0);
|
||||
@@ -0,0 +1,20 @@
|
||||
import { listPages, wait } from '/home/admin9webs/shein建品/sh_lib.mjs';
|
||||
import { CDP, SAN as S } from '/tmp/cdp3.mjs';
|
||||
const t = (await listPages()).find(x=>/91miaoshou/i.test(x.url));
|
||||
const c = await CDP.connect(t.webSocketDebuggerUrl);
|
||||
await c.send('Page.enable'); await c.send('Runtime.enable'); await wait(1200);
|
||||
console.log('点查看失败原因:', String(await c.evalJS(`(()=>{
|
||||
const rows=[...document.querySelectorAll('tr')].filter(e=>e.offsetParent!==null&&/^\\s*ms\\s/.test((e.innerText||'').trim()));
|
||||
const row=rows[0]; if(!row) return 'no-row';
|
||||
const link=[...row.querySelectorAll('*')].find(e=>(e.innerText||'').trim()==='查看失败原因');
|
||||
if(!link) return 'no-link';
|
||||
for(const ev of ['mousedown','mouseup','click']) link.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window}));
|
||||
return 'clicked';})()`)));
|
||||
await wait(5000);
|
||||
const o = await c.evalJS(`(()=>{
|
||||
const dlgs=[...document.querySelectorAll('.jx-dialog,.jx-drawer,[class*=dialog]')].filter(e=>e.offsetParent!==null)
|
||||
.map(e=>(e.innerText||'').replace(/\\s+/g,' ').trim().slice(0,500)).filter(Boolean);
|
||||
return JSON.stringify({dlgs:dlgs.slice(0,2)});})()`);
|
||||
console.log('失败原因:', S(String(o)).slice(0,1200));
|
||||
try{ await c.shot('/tmp/ms_reason.jpg'); console.log('shot ok'); }catch(e){}
|
||||
process.exit(0);
|
||||
Binary file not shown.
Reference in new issue
Block a user