- TikTok/Shopee/速卖通/Walmart 各 46-47 条已在待发布 - Ozon 47 条已建、改价 40/47 - SHEIN 配方跑通第一条;Temu 差「预览图」一步 - 核心产出:MYJ.message.error 钩子诊断法(解开了三个平台的保存静默拦截) - 含下一轮提示词 NEXT-ROUND-PROMPT.md
81 lines
5.9 KiB
JavaScript
81 lines
5.9 KiB
JavaScript
import { attach } from '/tmp/cdp3.mjs';
|
|
import fs from 'fs';
|
|
/* 给已存在的 Walmart 产品补:无品牌 + 网络图片 */
|
|
const PID = process.argv[2];
|
|
const OID = process.argv[3];
|
|
const IN = JSON.parse(fs.readFileSync('/tmp/wm_input.json','utf8'))[OID];
|
|
if(!PID||!IN){ console.log('用法: node wmfixone.mjs <pid> <oid>'); process.exit(1); }
|
|
const wait = ms => new Promise(z => setTimeout(z, ms));
|
|
const log=(...a)=>console.log(' ',...a);
|
|
const tl=await (await fetch('http://127.0.0.1:9223/json/list')).json();
|
|
for(const t of tl.filter(x=>x.type==='page'&&/walmart/i.test(x.url))) await fetch(`http://127.0.0.1:9223/json/close/${t.id}`).catch(()=>{});
|
|
await wait(1000);
|
|
const t=await (await import('/tmp/cdp3.mjs')).newTarget('about:blank');
|
|
const {CDP}=await import('/tmp/cdp3.mjs');
|
|
const c=await CDP.connect(t.webSocketDebuggerUrl);
|
|
await c.send('Page.enable'); await c.send('Runtime.enable');
|
|
await c.send('Page.navigate',{url:`https://www.dianxiaomi.com/web/walmartProduct/edit?id=${PID}`});
|
|
await wait(24000);
|
|
// 1. 无品牌
|
|
const br=await c.evalJS(`(()=>{const lab=[...document.querySelectorAll('.ant-form-item')].filter(e=>e.offsetParent!==null)
|
|
.find(x=>{const l=x.querySelector('label'); return l&&/Brand/.test(l.innerText||'');});
|
|
if(!lab)return'nf';
|
|
const inp=lab.querySelector('input[name=brand]');
|
|
if(inp&&inp.value&&inp.value!=='')return 'already:'+inp.value;
|
|
const cb=[...lab.querySelectorAll('.ant-checkbox-wrapper')].find(e=>/无品牌/.test(e.innerText||''));
|
|
if(!cb)return'no-cb';
|
|
for(const ev of ['mousedown','mouseup','click']) cb.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window}));
|
|
const i2=cb.querySelector('input[type=checkbox]'); if(i2) i2.click();
|
|
return 'clicked';})()`);
|
|
log('无品牌:',br);
|
|
await wait(2000);
|
|
const bv=await c.evalJS(`(()=>{const lab=[...document.querySelectorAll('.ant-form-item')].filter(e=>e.offsetParent!==null)
|
|
.find(x=>{const l=x.querySelector('label'); return l&&/Brand/.test(l.innerText||'');});
|
|
const inp=lab?lab.querySelector('input[name=brand]'):null; return inp?inp.value:'?';})()`);
|
|
log('brand 现值:', String(bv));
|
|
// 2. 图片(若已有则跳过)
|
|
const cur=await c.evalJS(`(()=>{const it=[...document.querySelectorAll('.ant-form-item')].filter(e=>e.offsetParent!==null)
|
|
.find(x=>{const l=x.querySelector('label'); return l&&/产品图片/.test(l.innerText||'');});
|
|
const m=(it?it.innerText:'').match(/已经选用了\\s*(\\d+)\\s*张/); return m?Number(m[1]):-1;})()`);
|
|
log('已有图片数:', String(cur));
|
|
if (Number(cur) < 4) {
|
|
const pos=JSON.parse(String(await c.evalJS(`(()=>{const it=[...document.querySelectorAll('.ant-form-item')].filter(e=>e.offsetParent!==null)
|
|
.find(x=>{const l=x.querySelector('label'); return l&&/产品图片/.test(l.innerText||'');});
|
|
const b=[...it.querySelectorAll('button')].find(e=>/选择图片/.test(e.innerText||''));
|
|
b.scrollIntoView({block:'center'}); const r=b.getBoundingClientRect();
|
|
return JSON.stringify([Math.round(r.x+r.width/2),Math.round(r.y+r.height/2)]);})()`)));
|
|
await c.send('Input.dispatchMouseEvent',{type:'mouseMoved',x:pos[0],y:pos[1]}); await wait(1500);
|
|
await c.send('Input.dispatchMouseEvent',{type:'mouseMoved',x:pos[0]+2,y:pos[1]+2}); await wait(2200);
|
|
const hit=JSON.parse(String(await c.evalJS(`(()=>{const d=[...document.querySelectorAll('.ant-dropdown')].filter(e=>e.offsetParent!==null).pop();
|
|
if(!d)return'[]'; const it=[...d.querySelectorAll('li,.ant-dropdown-menu-item')].find(e=>/网络图片/.test(e.innerText||''));
|
|
if(!it)return'[]'; const r=it.getBoundingClientRect(); return JSON.stringify([Math.round(r.x+r.width/2),Math.round(r.y+r.height/2)]);})()`)));
|
|
if(hit.length){ await c.send('Input.dispatchMouseEvent',{type:'mouseMoved',x:hit[0],y:hit[1]}); await wait(300);
|
|
for(const type of ['mousePressed','mouseReleased']) await c.send('Input.dispatchMouseEvent',{type,x:hit[0],y:hit[1],button:'left',clickCount:1}); }
|
|
await wait(4000);
|
|
const f=await c.evalJS(`(()=>{const m=[...document.querySelectorAll('.ant-modal')].filter(e=>e.offsetParent!==null).pop();
|
|
if(!m)return'no-modal'; const ta=m.querySelector('textarea'); if(!ta)return'no-ta';
|
|
ta.focus(); Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype,'value').set.call(ta, ${JSON.stringify((IN.imgs||[]).join('\n'))});
|
|
ta.dispatchEvent(new Event('input',{bubbles:true})); ta.dispatchEvent(new Event('change',{bubbles:true}));
|
|
return 'n='+ta.value.split('\\n').filter(Boolean).length;})()`);
|
|
log('填URL:', f);
|
|
await wait(1200);
|
|
await c.evalJS(`(()=>{const m=[...document.querySelectorAll('.ant-modal')].filter(e=>e.offsetParent!==null).pop();
|
|
if(!m)return 0; const b=[...m.querySelectorAll('button')].find(x=>/^\\s*添加\\s*$/.test(x.innerText||''));
|
|
if(b) for(const ev of ['mousedown','mouseup','click']) b.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window})); return 1;})()`);
|
|
await wait(15000);
|
|
}
|
|
const after=await c.evalJS(`(()=>{const it=[...document.querySelectorAll('.ant-form-item')].filter(e=>e.offsetParent!==null)
|
|
.find(x=>{const l=x.querySelector('label'); return l&&/产品图片/.test(l.innerText||'');});
|
|
const m=(it?it.innerText:'').match(/已经选用了\\s*(\\d+)\\s*张/); return m?Number(m[1]):-1;})()`);
|
|
log('补后图片数:', String(after));
|
|
// 3. 保存
|
|
await c.evalJS(`(()=>{const b=[...document.querySelectorAll('button')].filter(e=>e.offsetParent!==null&&/^\\s*保存\\s*$/.test((e.innerText||'').trim()));
|
|
const el=b[b.length-1]; el.scrollIntoView({block:'center'});
|
|
for(const ev of ['mousedown','mouseup','click']) el.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window})); return 1;})()`);
|
|
let ok=false;
|
|
for(let i=0;i<16;i++){ await wait(800);
|
|
const m=await c.evalJS(`(()=>[...document.querySelectorAll('.ant-modal,.ant-message-notice')].some(e=>e.offsetParent!==null&&/成功/.test(e.innerText||'')))()`);
|
|
if(m){ ok=true; break; } }
|
|
log('保存:', ok?'成功':'未见成功提示');
|
|
process.exit(ok?0:3);
|