From 61daff1241f7b4ff97d0b7f1df7e1862c70bad42 Mon Sep 17 00:00:00 2001 From: admin9webs Date: Thu, 24 Sep 2026 23:03:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A6=99=E6=89=8B=EF=BC=9A=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E4=B8=A4=E6=AC=A1=E5=A4=B1=E8=B4=A5=E4=B8=94?= =?UTF-8?q?=E6=97=A0=E6=8A=A5=E9=94=99=EF=BC=88=E7=96=91=E4=BC=BC=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E6=9C=AA=E8=A7=A6=E5=8F=91=EF=BC=89=EF=BC=9B=E5=BB=BA?= =?UTF-8?q?=E8=AE=AE=E6=94=B9=E7=9C=9F=E5=AE=9E=E9=BC=A0=E6=A0=87=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E6=88=96=E4=BA=BA=E5=B7=A5=E7=99=BB=E5=BD=95=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E8=A7=A6=E5=8F=91=E8=B4=A6=E5=8F=B7=E9=94=81?= =?UTF-8?q?=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 妙手建品/RECIPE.md | 16 ++++++++++++++++ 妙手建品/ms_cap4.mjs | 22 ++++++++++++++++++++++ 妙手建品/ms_login4.mjs | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 妙手建品/ms_cap4.mjs create mode 100644 妙手建品/ms_login4.mjs diff --git a/妙手建品/RECIPE.md b/妙手建品/RECIPE.md index 7c8167f..4d28bd8 100644 --- a/妙手建品/RECIPE.md +++ b/妙手建品/RECIPE.md @@ -232,3 +232,19 @@ await c.send('DOM.setFileInputFiles', { files: ['/path/ms_import.csv'], nodeId } ### 「导入产品」按钮:本轮没测到 点它之前会话就掉了(登录也未成功),所以**触发点仍未验证**。 恢复顺序:重新登录 → `/common_collect_box/items` → 点 `导入产品` → 看是否列出 `ms2` → 确认后回列表数 47 条。 + +## 第 6 轮:重新登录失败(提交疑似未触发),建议人工登录 +- 会话掉线后,我用 §登录步骤 重试了两次(验证码分别读作 `7317`、`0326`): + - 填表返回 `{a:1,p:1,k:1,btn:true}`(三个输入都填上了) + - 提交后 `location.href` 仍是 `https://erp.91miaoshou.com/`,`input[type=password]` 仍在, + **且页面上没有任何错误文案**(`err: []`) + - 对比第一次成功那次:当时同代码提交后立刻出现「图形验证码不正确」——说明**提交确实触发过**; + 现在连错误都没有 → 更可能是**提交事件没打进去**(登录弹窗状态不同/需要真实鼠标事件), + 而不是验证码读错。 +- 考虑到页面上那句「**再失败 9 次将锁定账号 1 小时**」,我没有继续盲试。 + +### 建议的下一条路 +**人工登录(最稳)**:在 VNC 里手动登录一次 → 我直接接手已登录会话, +去做 `导入产品` 那个触发点的验证(`/common_collect_box/items` → `导入产品` → 看是否列出 `ms2`)。 +若仍需我自动登录:下一步应改为**真实鼠标点 `.login-form__submit-btn`**(`Input.dispatchMouseEvent`), +而不是 DOM `dispatchEvent`——这是本轮与前几轮唯一的行为差异。 diff --git a/妙手建品/ms_cap4.mjs b/妙手建品/ms_cap4.mjs new file mode 100644 index 0000000..0eb9367 --- /dev/null +++ b/妙手建品/ms_cap4.mjs @@ -0,0 +1,22 @@ +import { listPages, wait } from '/home/admin9webs/shein建品/sh_lib.mjs'; +import { CDP, SAN as S } from '/tmp/cdp3.mjs'; +import { writeFileSync } from 'fs'; +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 c.send('Page.navigate',{url:'https://erp.91miaoshou.com/'}); await wait(12000); +const chk = async () => String(await c.evalJS(`JSON.stringify({acc:!!document.querySelector('input.login-form__input[placeholder="手机号/子账号/邮箱"]'), cap:!!document.querySelector('.captcha-field__img'), btn:!!document.querySelector('.login-form__submit-btn')})`)); +console.log('初始:', await chk()); +if (!/true/.test(await chk())) { + console.log('点登录开弹窗…'); + await c.evalJS(`(()=>{const b=[...document.querySelectorAll('button,a,span')].find(e=>e.offsetParent!==null&&/^\\s*登录\\s*$/.test((e.innerText||'').trim())); + if(b) for(const ev of ['mousedown','mouseup','click']) b.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window})); return 1;})()`); + await wait(3000); + console.log('点后:', await chk()); +} +const src=String(await c.evalJS(`(()=>{const i=document.querySelector('.captcha-field__img'); return i?(i.src||''):'';})()`)); +const b64=src.includes('base64,')?src.split('base64,')[1]:''; +if(!b64){ console.log('仍无验证码图'); process.exit(1); } +writeFileSync('/tmp/ms_cap4.jpg', Buffer.from(b64,'base64')); +console.log('验证码已存 /tmp/ms_cap4.jpg'); +process.exit(0); diff --git a/妙手建品/ms_login4.mjs b/妙手建品/ms_login4.mjs new file mode 100644 index 0000000..427c1f7 --- /dev/null +++ b/妙手建品/ms_login4.mjs @@ -0,0 +1,38 @@ +import { listPages, wait } from '/home/admin9webs/shein建品/sh_lib.mjs'; +import { CDP, SAN as S } from '/tmp/cdp3.mjs'; +import { readFileSync } from 'fs'; +const doc=readFileSync('/home/admin9webs/agent-a2-import/skills/ecommerce/miaoshou-erp/SKILL.md','utf8'); +const acc=(doc.match(/xiaochaoren\d+/)||[])[0], pwd=(doc.match(/Bingo\d+@/)||[])[0]; +const CAP=process.argv[2]; +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(1000); +const f=await c.evalJS(`(()=>{const set=(sel,v)=>{const el=document.querySelector(sel); if(!el) return 0; + const s=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set; s.call(el,v); + el.dispatchEvent(new Event('input',{bubbles:true})); el.dispatchEvent(new Event('change',{bubbles:true})); return 1;}; + return JSON.stringify({a:set('input.login-form__input[placeholder="手机号/子账号/邮箱"]', ${JSON.stringify(acc)}), + p:set('input.login-form__input[type=password]', ${JSON.stringify(pwd)}), + k:set('.captcha-field__input', ${JSON.stringify(CAP)}), + btn:!!document.querySelector('.login-form__submit-btn')});})()`); +console.log('填表:', S(String(f)).slice(0,150)); +await wait(700); +await c.evalJS(`(()=>{const b=document.querySelector('.login-form__submit-btn'); if(b) for(const ev of ['mousedown','mouseup','click']) b.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window})); return 1;})()`); +await wait(12000); +console.log('登录:', S(String(await c.evalJS(`JSON.stringify({href:location.href, login:!!document.querySelector('input[type=password]'), err:[...document.querySelectorAll('*')].filter(e=>e.children.length===0&&/不正确|错误|锁定/.test(e.innerText||'')).map(e=>e.innerText.trim()).slice(0,2)})`))).slice(0,220)); +await c.send('Page.navigate',{url:'https://erp.91miaoshou.com/common_collect_box/items'}); await wait(13000); +const pos=JSON.parse(String(await c.evalJS(`(()=>{const b=[...document.querySelectorAll('button')].filter(e=>e.offsetParent!==null&&(e.innerText||'').trim()==='导入产品'); + if(!b.length) return '[]'; b[0].scrollIntoView({block:'center'}); const r=b[0].getBoundingClientRect(); + return JSON.stringify([Math.round(r.x+r.width/2),Math.round(r.y+r.height/2)]);})()`))); +console.log('导入产品坐标:', JSON.stringify(pos)); +if(pos.length){ + await c.send('Input.dispatchMouseEvent',{type:'mouseMoved',x:pos[0],y:pos[1],buttons:0}); await wait(300); + for(const tp of ['mousePressed','mouseReleased']) await c.send('Input.dispatchMouseEvent',{type:tp,x:pos[0],y:pos[1],button:'left',clickCount:1,buttons:1}); + await wait(7000); +} +const o=await c.evalJS(`(()=>{const dlgs=[...document.querySelectorAll('.jx-dialog,.jx-drawer,[class*=dialog]')].filter(e=>e.offsetParent!==null) + .map(e=>({txt:(e.innerText||'').replace(/\\s+/g,' ').trim().slice(0,280), btns:[...e.querySelectorAll('button')].map(b=>(b.innerText||'').trim()).filter(Boolean).slice(0,6)})); + const body=(document.body.innerText||'').replace(/\\s+/g,' '); + return JSON.stringify({dlgs:dlgs.slice(0,2), empty:/暂无数据/.test(body)});})()`); +console.log('导入产品:', S(String(o)).slice(0,1000)); +try{ await c.shot('/tmp/ms_ip2.jpg'); console.log('shot ok'); }catch(e){} +process.exit(0);