30 行
2.0 KiB
Python
30 行
2.0 KiB
Python
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())
|