import asyncio,json,urllib.parse,random,os,time import cdp EX=r'''JSON.stringify([...document.querySelectorAll("a")].filter(a=>/item\.taobao\.com\/item|detail\.tmall\.com\/item/.test(a.href)&&/¥/.test(a.innerText)).slice(0,24).map(a=>{const id=(a.href.match(/[?&]id=(\d+)/)||[])[1];const t=a.innerText.split("\n").map(s=>s.trim()).filter(Boolean);const i=t.indexOf("¥");let p="";if(i>=0){p=t[i+1]||"";if(t[i+2]&&/^\.\d+$/.test(t[i+2]))p+=t[i+2];}const sales=t.find(s=>/人付款|人收货|已售/.test(s))||"";return {id,tmall:/tmall/.test(a.href),title:t[0],price:p,sales,shop:t[t.length-1],tags:t.slice(1,i).join("/")};}))''' async def main(): Q=json.load(open('queries.json',encoding='utf-8')) out=json.load(open('tb.json',encoding='utf-8')) if os.path.exists('tb.json') else {} ws=await cdp.open_ws() for n,x in enumerate(Q): if x['sid'] in out and out[x['sid']]['items']: continue await cdp.send(ws,'Page.navigate',{'url':'https://s.taobao.com/search?q='+urllib.parse.quote(x['q'])}) items=[] for k in range(40): await asyncio.sleep(1) v=await cdp.ev(ws,EX) items=json.loads(v) if v else [] if len(items)>=8 or (items and k>10): break if k==20 and not items: txt=await cdp.ev(ws,'document.body.innerText.slice(0,300)+location.href') print('NO ITEMS/CAPTCHA?',x['q'],(txt or '')[:200].replace('\n',' '),flush=True) for w in range(100): await asyncio.sleep(3); v=await cdp.ev(ws,EX); items=json.loads(v) if v else [] if items: break if w==30: await cdp.send(ws,'Page.navigate',{'url':'https://s.taobao.com/search?q='+urllib.parse.quote(x['q'])}) break out[x['sid']]={'q':x['q'],'items':items,'ts':time.time()} json.dump(out,open('tb.json','w',encoding='utf-8'),ensure_ascii=False,indent=1) print(n,x['sid'],x['q'],len(items),items[0]['price'] if items else '',flush=True) await asyncio.sleep(30) asyncio.run(main())