#!/usr/bin/env python3 # -*- coding: utf-8 -*- """探测任务中心(taskCenter):结构、任务项状态、下载链路。并测试整表页的导出图标(hover tooltip)。""" import json, urllib.request, base64, time, os D = "http://127.0.0.1:10086/command"; S = "2haohr" def call(a, args, timeout=120): b = json.dumps({"action": a, "args": args, "session": S}).encode() r = urllib.request.Request(D, data=b, headers={"Content-Type": "application/json"}) return json.loads(urllib.request.urlopen(r, timeout=timeout).read().decode()) def ev(code, timeout=120): try: return call("evaluate", {"code": code}, timeout).get("data", {}).get("value") except Exception as e: return "EXC:" + str(e)[:80] HOOK = r"""(()=>{window.__cap=[];const ac=HTMLAnchorElement.prototype.click; HTMLAnchorElement.prototype.click=function(){try{const h=this.href||'';if(h&&/prv-cdn|attname=|\.xlsx|\.xls|\.docx|\.doc|\.zip/i.test(h))window.__cap.push(h);}catch(e){}return ac.apply(this,arguments);};return 'ok';})()""" # 读取任务中心:定位 taskCenter 容器,列出每个任务项(名称/状态/是否有下载) TASKS = r"""(()=>{ const tc=document.querySelector('[class*=taskCenter]'); if(!tc)return 'NO_TASKCENTER'; const items=[]; // 任务项通常是含 info_ 名称 + right_ 状态 的行 tc.querySelectorAll('[class*=info_]').forEach(info=>{ const row=info.closest('[class*=item],li,tr')||info.parentElement; const name=(info.innerText||'').replace(/\n+/g,' ').trim().slice(0,40); let dl='';const a=row&&row.querySelector('a'); const stat=row?(row.innerText||'').replace(/\n+/g,'|').slice(0,40):''; items.push({name:name,row:stat}); }); return JSON.stringify({open:getComputedStyle(tc).display,cnt:items.length,items:items.slice(0,10)}); })()""" # 点击任务中心里第 idx 个“下载”链接 CLICK_TASK_DL = r"""(function(idx){ const tc=document.querySelector('[class*=taskCenter]');if(!tc)return 'NO_TC'; const dls=[...tc.querySelectorAll('a')].filter(a=>(a.innerText||'').trim()==='下载'); if(idx>=dls.length)return 'IDX_OOB len='+dls.length; dls[idx].click();return 'clicked '+idx+'/'+dls.length; })(%d)""" FETCH_LAST = r"""(()=>{try{if(!window.__cap.length)return 'NO_HREF'; const u=window.__cap[window.__cap.length-1];const x=new XMLHttpRequest();x.open('GET',u,false); x.overrideMimeType('text/plain;charset=x-user-defined');x.send();if(x.status!==200)return 'HTTP'+x.status; const s=x.responseText;let out='';const CH=8192;for(let i=0;i