108 lines
3.9 KiB
Python
108 lines
3.9 KiB
Python
"""
|
|
生产工单查询 - 数据提取
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import json
|
|
import time
|
|
import datetime
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
from login import get_page, login, login_manual, log, dump_page_state
|
|
from config import OUTPUT_DIR
|
|
|
|
PAGE_URL = "https://yunmes.tftykj.cn/WorkOrdersQuery"
|
|
API_PATH = "WorkOrdersDetailed_SearchListAll_Proxy" # 精确匹配生产工单列表 API
|
|
|
|
# ── 导航到目标页面 ───────────────────────────────────────────────────────────
|
|
def navigate_to_page(page):
|
|
log("INFO", f"导航到生产工单查询页面...")
|
|
page.get(PAGE_URL)
|
|
# 等待数据表格区域出现
|
|
table = page.ele("xpath://table | .el-table__body", timeout=15)
|
|
if table:
|
|
log("OK", "页面已加载")
|
|
else:
|
|
log("WARN", "表格元素未找到,继续执行")
|
|
|
|
# ── 拦截并获取第 1 页数据 ───────────────────────────────────────────────
|
|
def fetch_page1(page) -> dict:
|
|
log("INFO", "开启网络监听...")
|
|
page.listen.start(API_PATH)
|
|
|
|
# 刷新页面触发自动加载请求
|
|
page.refresh()
|
|
|
|
log("INFO", "等待 API 响应...")
|
|
packet = page.listen.wait(timeout=30)
|
|
page.listen.stop()
|
|
|
|
if not packet:
|
|
log("ERR", "超时未收到响应")
|
|
dump_page_state(page, "监听超时")
|
|
return None
|
|
|
|
log("OK", f"拦截成功 → HTTP {packet.response.status} (URL: {packet.request.url})")
|
|
|
|
try:
|
|
body = packet.response.body
|
|
data = body if isinstance(body, (dict, list)) else json.loads(body)
|
|
|
|
if isinstance(data, dict):
|
|
result = data.get("result", {})
|
|
if isinstance(result, dict) and "totalCount" in result:
|
|
items = result.get("items", [])
|
|
total = result.get("totalCount", "?")
|
|
log("INFO", f"本页记录: {len(items)} 条 | 总计: {total} 条")
|
|
return data
|
|
except Exception as e:
|
|
log("WARN", f"解析 {packet.request.url} 失败: {e}")
|
|
|
|
log("ERR", "未解析到有效的数据结构")
|
|
return None
|
|
|
|
# ── 保存为 JSON ───────────────────────────────────────────────────────────────
|
|
def save_json(data, prefix: str = "work_orders") -> Path:
|
|
ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
path = OUTPUT_DIR / f"{prefix}_{ts}.json"
|
|
with open(path, "w", encoding="utf-8") as f:
|
|
json.dump(data, f, ensure_ascii=False, indent=2)
|
|
log("OK", f"已保存: {path}")
|
|
return path
|
|
|
|
# ── 主流程 ────────────────────────────────────────────────────────────────────
|
|
def run(manual: bool = False):
|
|
mode = "复用保活浏览器"
|
|
log("INFO", f"生产工单查询提取启动 [{mode}]")
|
|
|
|
# 使用已经登录的保活浏览器端口 9222
|
|
page = get_page(port=9222)
|
|
try:
|
|
# Step 1: 进入页面
|
|
navigate_to_page(page)
|
|
|
|
# Step 2: 获取第 1 页数据
|
|
data = fetch_page1(page)
|
|
if data is None:
|
|
log("ERR", "数据获取失败")
|
|
return
|
|
|
|
# Step 3: 保存 JSON
|
|
save_json(data, prefix="work_orders_page1")
|
|
log("OK", "完成!文件保存在 output/")
|
|
|
|
except KeyboardInterrupt:
|
|
log("INFO", "用户中断 (Ctrl+C)")
|
|
except Exception as e:
|
|
log("ERR", f"异常: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
finally:
|
|
# 复用浏览器的情况下不关闭浏览器
|
|
pass
|
|
|
|
if __name__ == "__main__":
|
|
run(manual="--manual" in sys.argv)
|