refactor: React 前端重构,新旧平台合并为莞易学
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
"""抓包:把页面 XHR/fetch 落成 data/capture-*.json。"""
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
|
||||
from study_tool import store
|
||||
from study_tool.config import *
|
||||
from study_tool.runtime import RUNS, log
|
||||
|
||||
# ------------------------------------------------------- 抓包(排查平台行为)
|
||||
CAPTURES = {}
|
||||
|
||||
|
||||
def capture_worker(key, cookies, minutes=10):
|
||||
"""开一个有头浏览器,把这期间所有 /train/** 请求和响应记下来。
|
||||
|
||||
用于搞不清「某个状态到底由哪一发请求写成」:手动走一遍(点课程 → 播几秒 → 交评价),
|
||||
再看抓到的接口和响应,就能定位该自动补哪一步。
|
||||
"""
|
||||
try:
|
||||
from playwright.sync_api import sync_playwright
|
||||
except Exception as e:
|
||||
log(key, "抓包需要 playwright:%s" % e)
|
||||
return
|
||||
recs = CAPTURES.setdefault(key, [])
|
||||
log(key, "抓包开始:浏览器里手动走一遍(点课程 → 播几秒 → 交评价),"
|
||||
"完事点「停止抓包」,最多 %d 分钟" % minutes)
|
||||
|
||||
def on_resp(r):
|
||||
try:
|
||||
if r.request.resource_type not in ("xhr", "fetch"):
|
||||
return
|
||||
ct = (r.headers or {}).get("content-type", "")
|
||||
body = ""
|
||||
if "json" in ct:
|
||||
try:
|
||||
body = r.text()[:4000]
|
||||
except Exception:
|
||||
body = ""
|
||||
recs.append({"t": time.strftime("%H:%M:%S"), "method": r.request.method,
|
||||
"url": r.url, "req": (r.request.post_data or "")[:1000],
|
||||
"status": r.status, "resp": body})
|
||||
u = urlsplit(r.url)
|
||||
log(key, " · %s %s%s → %s" % (r.request.method, u.netloc, u.path, r.status))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
with sync_playwright() as p:
|
||||
b = p.chromium.launch(headless=False)
|
||||
ctx = b.new_context()
|
||||
for c in cookies:
|
||||
if "dgjy" in (c.get("domain") or ""):
|
||||
try:
|
||||
ctx.add_cookies([{"name": c["name"], "value": c.get("value") or "",
|
||||
"domain": (c.get("domain") or "").lstrip("."),
|
||||
"path": c.get("path") or "/"}])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 平台点课程/视频是 window.open 新开标签,必须把新页面也挂上监听,否则只抓到第一页
|
||||
hooked = set()
|
||||
|
||||
def hook(page):
|
||||
if id(page) in hooked:
|
||||
return
|
||||
hooked.add(id(page))
|
||||
page.on("response", on_resp)
|
||||
|
||||
ctx.on("page", hook)
|
||||
pg = ctx.new_page()
|
||||
hook(pg)
|
||||
# /training/ 根路径没有路由,会落到 404;直接开「我的培训」列表页
|
||||
pg.goto(STUDY + "/training/myTrain", wait_until="domcontentloaded", timeout=60000)
|
||||
t0 = time.time()
|
||||
while time.time() - t0 < minutes * 60:
|
||||
if (RUNS.get(key) or {}).get("capture_stop"):
|
||||
break
|
||||
pg.wait_for_timeout(1000)
|
||||
except Exception as e:
|
||||
log(key, "抓包异常:%s" % str(e)[:150])
|
||||
finally:
|
||||
path = ""
|
||||
if recs:
|
||||
try:
|
||||
path = os.path.join(store.DATA_DIR,
|
||||
"capture-%s-%s.json" % (key, time.strftime("%Y%m%d-%H%M%S")))
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
json.dump(recs, f, ensure_ascii=False, indent=1)
|
||||
except Exception as e:
|
||||
log(key, "抓包结果保存失败:%s" % e)
|
||||
set_state(key, capturing=False, capture_stop=False, capture_file=path)
|
||||
log(key, "抓包结束:%d 条请求%s" % (len(recs), (",已存 " + path) if path else ""))
|
||||
Reference in New Issue
Block a user