feat: 整站全量采集与订单写入接口契约补全
- GET 全量扫描 279 个接口并留档(HTTP200=90, 业务成功=76)
- POST 安全探测 24 个只读/计算接口(白名单制, 支付/短信/删除类零触碰)
- 订单写入接口契约经 chunk 源码静态分析补全:
orders CRUD / 创建订单{contract_id,drawing_data,pic_url} / windoor_default 保存
- 确认付费墙语义 code=10086 及到期/角色权限响应
- doc/API.md 新增整站采集结果章节, 更新订单模块契约表
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python3
|
||||
"""整站 GET 接口全量扫描:对接口清单逐一探测并留存响应。只读、限速。"""
|
||||
import json, os, re, time, urllib.request, urllib.error
|
||||
|
||||
BASE = "https://zzc-serv.thinkerx.com/api/"
|
||||
TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvenpjLXNlcnYudGhpbmtlcnguY29tXC9hcGlcL3dlY2hhdC1sb2dpbi13aXRoLXBob25lIiwiaWF0IjoxNzg5OTA5NTIwLCJleHAiOjE3ODk5OTU5MjAsIm5iZiI6MTc4OTkwOTUyMCwianRpIjoiTGVyV0J4VTZONTVOMlNwQSIsInN1YiI6MzU2Mjg1NiwicHJ2IjoiNTRjMjZlNjE2MjNhYTQzMzZkZTQ1YTcxNGIwYzdhYWIxZTJhYzA3NSJ9.MXBrpBh3gseq8I91EQklxsgLfHafUKwNxc24JdcUkcc"
|
||||
OUT = r"D:\Code\huamenchuang\data\full-site\get"
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
|
||||
def safe_name(ep):
|
||||
return re.sub(r'[^A-Za-z0-9_-]', '_', ep).strip('_') or 'root'
|
||||
|
||||
def fetch(ep, method="GET", body=None):
|
||||
req = urllib.request.Request(BASE + ep, method=method, headers={
|
||||
"Authorization": f"Bearer {TOKEN}",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
}, data=body)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=15) as r:
|
||||
return r.status, r.read().decode("utf-8", "replace")
|
||||
except urllib.error.HTTPError as e:
|
||||
return e.code, e.read().decode("utf-8", "replace")[:4000]
|
||||
except Exception as e:
|
||||
return -1, str(e)[:200]
|
||||
|
||||
endpoints = [l.strip() for l in open(r"D:\Code\huamenchuang\data\api-endpoint-inventory.txt", encoding="utf-8") if l.strip()]
|
||||
manifest = []
|
||||
ok200 = 0
|
||||
for i, ep in enumerate(endpoints):
|
||||
fn = safe_name(ep)
|
||||
status, body = fetch(ep)
|
||||
entry = {"endpoint": ep, "method": "GET", "status": status, "size": len(body)}
|
||||
if status == 200:
|
||||
ok200 += 1
|
||||
try:
|
||||
j = json.loads(body)
|
||||
entry["code"] = j.get("code") if isinstance(j, dict) else None
|
||||
entry["message"] = (j.get("message") or "")[:40] if isinstance(j, dict) else ""
|
||||
except Exception:
|
||||
entry["code"] = "RAW"
|
||||
json.dump({"endpoint": ep, "status": status, "body": body[:100000]},
|
||||
open(f"{OUT}\\{fn}.json", "w", encoding="utf-8"), ensure_ascii=False)
|
||||
manifest.append(entry)
|
||||
if (i + 1) % 40 == 0:
|
||||
print(f"进度 {i+1}/{len(endpoints)} 200数={ok200}", flush=True)
|
||||
time.sleep(0.25)
|
||||
|
||||
json.dump(manifest, open(r"D:\Code\huamenchuang\data\full-site\get-manifest.json", "w", encoding="utf-8"), ensure_ascii=False, indent=1)
|
||||
print(f"完成: {len(endpoints)} 个接口, HTTP200={ok200}")
|
||||
ok_valid = sum(1 for m in manifest if m.get("code") == 1)
|
||||
paywall = [m["endpoint"] for m in manifest if m.get("code") == "10086"]
|
||||
print(f"其中 code=1 业务成功: {ok_valid}; 付费墙拦截: {len(paywall)}")
|
||||
Reference in New Issue
Block a user