chore: 批量新增各类工具脚本与配置文件

1. 新增音频录制、下载、上传相关脚本
2. 新增数据库操作、API调用工具
3. 新增Excel数据处理脚本
4. 新增弱密码检测脚本
This commit is contained in:
2026-06-14 17:47:15 +08:00
parent aac9f5934d
commit 2d8c1ea8f9
46 changed files with 11644 additions and 829 deletions
+4
View File
@@ -11,6 +11,10 @@ dist/
*.egg-info
*.pyc
*.jar
*.csv
*.wav
*.json
*/output/
build/
out/
__pycache__/
+90
View File
@@ -0,0 +1,90 @@
import subprocess
import time
from datetime import datetime
import os
# RTSP 流地址
rtsp_url = "rtsp://10.68.66.174/audio"
# 录制时长(分钟)
duration_minutes = 60
output_filename = f"rtsp_recording_{datetime.now().strftime('%Y%m%d_%H%M%S')}.wav"
print(f"开始录制 RTSP 音频流...")
print(f"RTSP 地址: {rtsp_url}")
print(f"录制时长: {duration_minutes} 分钟")
print(f"保存路径: {output_filename}")
print(f"按 Ctrl+C 停止录制")
print("-" * 50)
# 转换为秒
duration_seconds = duration_minutes * 60
try:
# 使用 ffmpeg 录制 RTSP 流
# -rtsp_transport tcp 使用 TCP 协议,更稳定
# -t 指定录制时长
# -acodec pcm_s16le 输出 PCM WAV 格式
cmd = [
'ffmpeg',
'-rtsp_transport', 'tcp',
'-i', rtsp_url,
'-t', str(duration_seconds),
'-acodec', 'pcm_s16le',
'-ar', '16000', # 采样率
'-ac', '1', # 单声道
'-y', # 覆盖已存在的文件
output_filename
]
print(f"执行命令: {' '.join(cmd)}")
print("开始录制...")
# 执行 ffmpeg 命令
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True
)
# 用于跟踪进度的变量
start_time = time.time()
last_size = 0
# 实时输出 ffmpeg 的日志
for line in iter(process.stdout.readline, ''):
if line:
# 检查文件大小变化
if os.path.exists(output_filename):
current_size = os.path.getsize(output_filename)
if current_size != last_size:
elapsed = time.time() - start_time
size_mb = current_size / (1024 * 1024)
progress = (elapsed / duration_seconds) * 100 if duration_seconds > 0 else 0
print(f"进度: {int(elapsed)}秒 / {duration_seconds}秒 ({progress:.1f}%), 大小: {size_mb:.2f}MB", end='\r')
last_size = current_size
process.wait()
# 录制完成
elapsed = time.time() - start_time
if os.path.exists(output_filename):
size_mb = os.path.getsize(output_filename) / (1024 * 1024)
print(f"\n\n录制完成!")
print(f"总时长: {int(elapsed)}秒 ({elapsed/60:.1f}分钟)")
print(f"文件大小: {size_mb:.2f}MB")
print(f"保存路径: {os.path.abspath(output_filename)}")
else:
print("\n录制失败,文件未生成")
except KeyboardInterrupt:
print(f"\n\n录制已手动停止")
if os.path.exists(output_filename):
size_mb = os.path.getsize(output_filename) / (1024 * 1024)
elapsed = time.time() - start_time
print(f"已录制: {int(elapsed)}")
print(f"文件大小: {size_mb:.2f}MB")
print(f"保存路径: {os.path.abspath(output_filename)}")
except Exception as e:
print(f"\n错误: {e}")
+137
View File
@@ -0,0 +1,137 @@
from langchain_openai import ChatOpenAI
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_core.tools import StructuredTool, Tool
from langchain.agents import create_agent
import asyncio
def normalize_base_url(url):
"""标准化base_url,移除反引号和首尾空格,去除末尾斜杠"""
if url:
url = url.strip().strip('`').rstrip('/')
return url
# OpenAI配置
api_key = "sk-8d657b8b7efe0cb6c141a30d9cee97f726efb9b18ea72bb1e8cfb080b42c140d"
base_url = normalize_base_url("https://console.pivotbak.cfd/v1")
model_name = "MiniMax-M2.7-highspeed"
# MCP配置
mcp_server_url = normalize_base_url("http://192.168.0.10:9999/admin/mcp/sse")
# 全局参数 - 每次对话都要传递
team_id = 19
token = "f1d23a59-479c-44a8-94b5-2344e4672ffd"
# 初始化LLM,每次请求都会携带teamId和token
llm = ChatOpenAI(
model=model_name,
openai_api_key=api_key,
openai_api_base=base_url,
temperature=0.7,
max_tokens=4096,
extra_body={
"teamId": team_id,
"token": token
}
)
# 示例工具函数
def get_current_time():
"""获取当前时间"""
from datetime import datetime
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
def calculate(a: float, b: float, operation: str = "add") -> float:
"""
简单计算器
:param a: 第一个数
:param b: 第二个数
:param operation: 操作类型,可选 add, sub, mul, div
"""
if operation == "add":
return a + b
elif operation == "sub":
return a - b
elif operation == "mul":
return a * b
elif operation == "div":
if b == 0:
return "错误:除数不能为零"
return a / b
else:
return f"未知操作: {operation}"
# 定义工具
tools = [
Tool(
name="get_current_time",
func=get_current_time,
description="获取当前时间"
),
StructuredTool.from_function(calculate)
]
# 从MCP加载工具
async def load_mcp_tools():
mcp_client = MultiServerMCPClient(
{"server": {"url": mcp_server_url, "transport": "sse"}}
)
try:
mcp_tools = await mcp_client.get_tools()
print(f"从MCP服务器加载到 {len(mcp_tools)} 个工具:")
for tool in mcp_tools:
print(f" - {tool.name}: {tool.description}")
return mcp_tools
except Exception as e:
print(f"连接MCP服务器失败: {e}")
print("将继续使用本地工具")
return []
# 创建Agent
def create_my_agent(all_tools):
agent = create_agent(
model=llm,
tools=all_tools,
system_prompt="你是一个有用的助手,使用提供的工具来回答问题。"
)
return agent
# 测试示例
async def main():
print("=" * 60)
print("LangChain + MCP 测试")
print(f"模型: {model_name}")
print(f"API地址: {base_url}")
print(f"MCP地址: {mcp_server_url}")
print(f"Team ID: {team_id}")
print(f"Token: {token[:10]}..." if len(token) > 10 else token)
print("=" * 60)
# 加载MCP工具
mcp_tools = await load_mcp_tools()
all_tools = tools + mcp_tools
# 创建Agent
agent = create_my_agent(all_tools)
# 测试1: 直接对话
print("\n--- 测试1: 直接对话 ---")
response = llm.invoke("你好,介绍一下自己")
print(response.content)
# 测试2: 使用工具
print("\n--- 测试2: 使用工具 - 获取当前时间 ---")
result = await agent.ainvoke({
"messages": [("user", "现在几点了?")]
})
print(result["messages"][-1].content)
# 测试3: 使用计算器
print("\n--- 测试3: 使用工具 - 计算 ---")
result = await agent.ainvoke({
"messages": [("user", "计算 100 乘以 50 等于多少?")]
})
print(result["messages"][-1].content)
if __name__ == "__main__":
asyncio.run(main())
+221
View File
@@ -0,0 +1,221 @@
from flask import Flask, jsonify, request
import subprocess
import threading
import time
import os
from datetime import datetime
import schedule
app = Flask(__name__)
# 配置参数
RTSP_URL = "rtsp://10.68.66.174/audio"
RECORD_DURATION_MINUTES = 60 # 录制时长(分钟)
REST_DURATION_MINUTES = 20 # 休息时长(分钟)
START_HOUR = 8 # 开始时间(小时)
END_HOUR = 20 # 结束时间(小时)
OUTPUT_DIR = "./" # 输出目录
# 录制状态
recording_state = {
"is_recording": False,
"current_file": None,
"start_time": None,
"total_recorded": 0,
"schedule_next": None
}
def get_output_path():
"""生成带时间戳的文件名"""
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
return os.path.join(OUTPUT_DIR, f"rtsp_{timestamp}.wav")
def is_within_schedule():
"""检查当前是否在有效时间段内"""
current_hour = datetime.now().hour
return START_HOUR <= current_hour < END_HOUR
def record_audio():
"""执行音频录制"""
if recording_state["is_recording"]:
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 正在录制中,跳过本次录制")
return
if not is_within_schedule():
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 不在有效时间段内(8:00-20:00),跳过本次录制")
return
output_file = get_output_path()
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 开始录制: {output_file}")
recording_state["is_recording"] = True
recording_state["current_file"] = output_file
recording_state["start_time"] = datetime.now()
try:
# 使用 ffmpeg 录制
cmd = [
'ffmpeg',
'-rtsp_transport', 'tcp',
'-i', RTSP_URL,
'-t', str(RECORD_DURATION_MINUTES * 60),
'-acodec', 'pcm_s16le',
'-ar', '16000',
'-ac', '1',
'-y',
output_file
]
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True
)
# 监控录制进度
start_time = time.time()
while process.poll() is None:
if os.path.exists(output_file):
size_mb = os.path.getsize(output_file) / (1024 * 1024)
elapsed = time.time() - start_time
print(f"\r进度: {int(elapsed)}秒 / {RECORD_DURATION_MINUTES * 60}秒, 大小: {size_mb:.2f}MB", end='')
time.sleep(1)
print() # 换行
# 录制完成
if os.path.exists(output_file):
size_mb = os.path.getsize(output_file) / (1024 * 1024)
recording_state["total_recorded"] += 1
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 录制完成: {output_file} ({size_mb:.2f}MB)")
else:
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 录制失败")
except Exception as e:
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 录制错误: {e}")
finally:
recording_state["is_recording"] = False
recording_state["current_file"] = None
recording_state["start_time"] = None
# 录制完成后,在有效时间段内等待 REST_DURATION_MINUTES 分钟
if is_within_schedule():
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 进入休息模式,等待 {REST_DURATION_MINUTES} 分钟...")
time.sleep(REST_DURATION_MINUTES * 60)
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 休息结束")
else:
# 不在有效时间段,等待到下一个有效时间段
now = datetime.now()
if now.hour >= END_HOUR:
# 等待到明天早上 8 点
from datetime import timedelta
next_day = now + timedelta(days=1)
target = next_day.replace(hour=START_HOUR, minute=0, second=0, microsecond=0)
else:
# 等待到今天早上 8 点
target = now.replace(hour=START_HOUR, minute=0, second=0, microsecond=0)
wait_seconds = (target - now).total_seconds()
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 不在有效时间段,等待 {wait_seconds/3600:.1f} 小时...")
time.sleep(wait_seconds)
def schedule_recording():
"""定时录制任务"""
thread = threading.Thread(target=record_audio, daemon=True)
thread.start()
def run_scheduler():
"""运行定时器"""
# 设置定时任务:每小时整点录制
schedule.every().hour.at(":00").do(schedule_recording)
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 定时录制服务已启动")
print(f" - 录制时长: {RECORD_DURATION_MINUTES} 分钟")
print(f" - 休息时长: {REST_DURATION_MINUTES} 分钟")
print(f" - 有效时段: {START_HOUR}:00 - {END_HOUR}:00")
print("-" * 50)
while True:
schedule.run_pending()
time.sleep(1)
# Flask 路由
@app.route('/')
def index():
"""主页"""
return jsonify({
"service": "RTSP Audio Recorder",
"status": "running" if recording_state["is_recording"] else "idle",
"config": {
"rtsp_url": RTSP_URL,
"record_duration": f"{RECORD_DURATION_MINUTES} minutes",
"rest_duration": f"{REST_DURATION_MINUTES} minutes",
"schedule": f"{START_HOUR}:00 - {END_HOUR}:00"
}
})
@app.route('/status')
def status():
"""获取录制状态"""
return jsonify({
"is_recording": recording_state["is_recording"],
"current_file": recording_state["current_file"],
"start_time": recording_state["start_time"].isoformat() if recording_state["start_time"] else None,
"total_recorded": recording_state["total_recorded"],
"current_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
"is_in_schedule": is_within_schedule()
})
@app.route('/start')
def start_recording():
"""手动开始录制"""
if recording_state["is_recording"]:
return jsonify({"status": "error", "message": "正在录制中"})
thread = threading.Thread(target=record_audio, daemon=True)
thread.start()
return jsonify({"status": "success", "message": "开始录制"})
@app.route('/stop')
def stop_recording():
"""手动停止录制(终止 ffmpeg 进程)"""
if not recording_state["is_recording"]:
return jsonify({"status": "error", "message": "当前没有在录制"})
# 查找并终止 ffmpeg 进程
try:
subprocess.run(['taskkill', '/f', '/im', 'ffmpeg.exe'], capture_output=True)
recording_state["is_recording"] = False
return jsonify({"status": "success", "message": "已停止录制"})
except Exception as e:
return jsonify({"status": "error", "message": str(e)})
@app.route('/files')
def list_files():
"""列出已录制的文件"""
files = []
for f in os.listdir(OUTPUT_DIR):
if f.endswith('.wav') and f.startswith('rtsp_'):
path = os.path.join(OUTPUT_DIR, f)
files.append({
"name": f,
"size": os.path.getsize(path),
"modified": datetime.fromtimestamp(os.path.getmtime(path)).isoformat()
})
return jsonify({"files": files})
if __name__ == '__main__':
# 确保输出目录存在
os.makedirs(OUTPUT_DIR, exist_ok=True)
# 启动定时器线程
scheduler_thread = threading.Thread(target=run_scheduler, daemon=True)
scheduler_thread.start()
# 启动 Flask 服务
print(f"\n{'='*50}")
print(f"RTSP 音频录制服务")
print(f"{'='*50}")
app.run(host='0.0.0.0', port=5000, debug=False, use_reloader=False)
+232
View File
@@ -0,0 +1,232 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import subprocess
import threading
import time
import os
import sys
from datetime import datetime, timedelta
# 配置参数
RTSP_URL = "rtsp://10.68.66.174/audio"
RECORD_DURATION_MINUTES = 60 # 录制时长(分钟)
REST_DURATION_MINUTES = 20 # 休息时长(分钟)
START_HOUR = 8 # 开始时间(小时)
END_HOUR = 20 # 结束时间(小时)
OUTPUT_DIR = "./" # 输出目录
# 录制状态
recording_state = {
"is_recording": False,
"current_file": None,
"start_time": None,
"total_recorded": 0
}
def log(msg):
"""带时间戳的日志输出"""
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {msg}")
sys.stdout.flush()
def check_dependencies():
"""检查依赖是否满足"""
errors = []
# 检查 Python 版本
if sys.version_info[0] < 3:
errors.append("需要 Python 3.x")
# 检查 ffmpeg
try:
result = subprocess.run(['ffmpeg', '-version'], capture_output=True, text=True, timeout=5)
if result.returncode != 0:
errors.append("ffmpeg 未正确安装")
else:
log("ffmpeg 已安装: " + result.stdout.split('\n')[0])
except FileNotFoundError:
errors.append("未找到 ffmpeg,请安装: yum install ffmpeg 或 apt install ffmpeg")
except Exception as e:
errors.append(f"检查 ffmpeg 时出错: {e}")
return errors
def get_output_path():
"""生成带时间戳的文件名"""
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
return os.path.join(OUTPUT_DIR, f"rtsp_{timestamp}.wav")
def is_within_schedule():
"""检查当前是否在有效时间段内"""
current_hour = datetime.now().hour
return START_HOUR <= current_hour < END_HOUR
def do_record(output_file):
"""执行 ffmpeg 录制"""
cmd = [
'ffmpeg',
'-rtsp_transport', 'tcp',
'-i', RTSP_URL,
'-t', str(RECORD_DURATION_MINUTES * 60),
'-acodec', 'pcm_s16le',
'-ar', '16000',
'-ac', '1',
'-y',
output_file
]
log(f"执行命令: {' '.join(cmd)}")
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True
)
# 监控录制进度
start_time = time.time()
last_size = 0
while process.poll() is None:
if os.path.exists(output_file):
current_size = os.path.getsize(output_file)
if current_size != last_size:
size_mb = current_size / (1024 * 1024)
elapsed = time.time() - start_time
progress = (elapsed / (RECORD_DURATION_MINUTES * 60)) * 100
print(f"\r进度: {int(elapsed)}秒 / {RECORD_DURATION_MINUTES * 60}秒 ({progress:.1f}%), 大小: {size_mb:.2f}MB", end='')
sys.stdout.flush()
last_size = current_size
time.sleep(1)
print() # 换行
# 检查进程返回码
if process.returncode != 0:
log(f"ffmpeg 返回错误码: {process.returncode}")
remaining = process.stdout.read()
if remaining:
log(f"ffmpeg 输出: {remaining[:500]}")
return process.returncode, output_file
def record_audio(check_schedule=True):
"""执行音频录制
check_schedule: 是否检查时间段限制
"""
if recording_state["is_recording"]:
log("正在录制中,跳过本次录制")
return
if check_schedule and not is_within_schedule():
log(f"不在有效时间段内({START_HOUR}:00-{END_HOUR}:00),跳过本次录制")
return
output_file = get_output_path()
log(f"开始录制: {output_file}")
recording_state["is_recording"] = True
recording_state["current_file"] = output_file
recording_state["start_time"] = datetime.now()
try:
returncode, file_path = do_record(output_file)
# 录制完成
if os.path.exists(file_path):
size_mb = os.path.getsize(file_path) / (1024 * 1024)
recording_state["total_recorded"] += 1
log(f"录制完成: {file_path} ({size_mb:.2f}MB)")
else:
log("录制失败,文件未生成")
except FileNotFoundError as e:
log(f"命令未找到: {e}")
log("请确保 ffmpeg 已安装并可在 PATH 中访问")
except Exception as e:
log(f"录制错误: {e}")
import traceback
traceback.print_exc()
finally:
recording_state["is_recording"] = False
recording_state["current_file"] = None
recording_state["start_time"] = None
def handle_rest():
"""处理休息时间"""
if is_within_schedule():
log(f"进入休息模式,等待 {REST_DURATION_MINUTES} 分钟...")
time.sleep(REST_DURATION_MINUTES * 60)
log("休息结束")
else:
# 计算到下一个有效时间段
now = datetime.now()
if now.hour >= END_HOUR:
next_day = now + timedelta(days=1)
target = next_day.replace(hour=START_HOUR, minute=0, second=0, microsecond=0)
else:
target = now.replace(hour=START_HOUR, minute=0, second=0, microsecond=0)
wait_seconds = (target - now).total_seconds()
log(f"不在有效时间段,等待 {wait_seconds/3600:.1f} 小时到 {START_HOUR}:00...")
time.sleep(wait_seconds)
def run_scheduler():
"""运行定时器"""
log("定时录制服务已启动")
log(f" - 录制时长: {RECORD_DURATION_MINUTES} 分钟")
log(f" - 休息时长: {REST_DURATION_MINUTES} 分钟")
log(f" - 有效时段: {START_HOUR}:00 - {END_HOUR}:00")
log("-" * 50)
# 启动时立即开始录制(无视时间段)
log("启动脚本,立即开始录制(本次无视时间段)")
record_audio(check_schedule=False)
# 录制完成后处理休息
if recording_state["total_recorded"] > 0:
handle_rest()
while True:
now = datetime.now()
# 检查是否在有效时间段内
if is_within_schedule():
# 每小时整点开始录制
if now.minute == 0 and now.second == 0:
log("整点时间到,开始录制")
record_audio(check_schedule=True)
time.sleep(1)
def main():
"""主函数"""
print("=" * 50)
print("RTSP 音频录制服务")
print("=" * 50)
# 检查依赖
log("检查系统依赖...")
errors = check_dependencies()
if errors:
log("发现以下问题:")
for error in errors:
log(f" - {error}")
log("请修复上述问题后重试")
sys.exit(1)
# 确保输出目录存在
os.makedirs(OUTPUT_DIR, exist_ok=True)
log(f"输出目录: {os.path.abspath(OUTPUT_DIR)}")
# 启动定时器
try:
run_scheduler()
except KeyboardInterrupt:
log("收到停止信号,正在退出...")
sys.exit(0)
if __name__ == '__main__':
main()
+10
View File
@@ -0,0 +1,10 @@
from requests import get
url = "http://10.68.66.174/mix.wav"
output_path = "mix.wav"
response = get(url)
with open(output_path, "wb") as f:
f.write(response.content)
print(f"文件已下载到: {output_path}")
+58
View File
@@ -0,0 +1,58 @@
import oss2
from pathlib import Path
class AliyunOSSUploader:
def __init__(self):
self.access_key_id = "LTAI5tGTySgnmBWAzQMtKDSS"
self.secret_access_key = "V3c7TI4KfK9ks8ReZGhSbADjX6avT0"
self.endpoint = "oss-cn-beijing.aliyuncs.com"
self.bucket_name = "remote-xtl"
auth = oss2.Auth(self.access_key_id, self.secret_access_key)
self.bucket = oss2.Bucket(auth, self.endpoint, self.bucket_name)
def _progress_callback(self, consumed_bytes, total_bytes):
if total_bytes:
rate = int(consumed_bytes * 100 / total_bytes)
print(f"\r上传进度: {rate}% ({consumed_bytes}/{total_bytes} bytes)", end="")
def upload(self, file_path, oss_object_name=None):
file_path = Path(file_path)
if not file_path.exists():
raise FileNotFoundError(f"文件不存在: {file_path}")
if oss_object_name is None:
oss_object_name = file_path.name
print(f"正在上传: {file_path}")
print(f"目标: oss://{self.bucket_name}/{oss_object_name}")
self.bucket.put_object_from_file(
oss_object_name,
str(file_path),
progress_callback=self._progress_callback
)
print(f"\n上传成功!")
url = f"https://{self.bucket_name}.{self.endpoint}/{oss_object_name}"
print(f"访问地址: {url}")
return url
if __name__ == "__main__":
uploader = AliyunOSSUploader()
print("=" * 50)
print("阿里云 OSS 文件上传工具")
print("=" * 50)
file_path = input("\n请输入文件绝对路径: ").strip().strip('"').strip("'")
try:
uploader.upload(file_path)
except FileNotFoundError as e:
print(f"\n错误: {e}")
except Exception as e:
print(f"\n上传失败: {e}")
-76
View File
@@ -1,76 +0,0 @@
import socket
import threading
from queue import Queue
import time
# 定义要检查的IP范围和端口
IP_BASE = "192.168.10."
START_IP = 1
END_IP = 255
TARGET_PORT = 5555
# 线程数量,可根据需要调整
THREAD_COUNT = 30
def check_port(ip, port, result_queue):
"""检查指定IP的端口是否开放"""
try:
# 创建socket对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置超时时间为1秒
sock.settimeout(1)
# 尝试连接
result = sock.connect_ex((ip, port))
if result == 0:
result_queue.put(ip)
sock.close()
except Exception:
pass
def worker(ip_queue, result_queue):
"""工作线程,从队列中获取IP并检查端口"""
while not ip_queue.empty():
ip = ip_queue.get()
check_port(ip, TARGET_PORT, result_queue)
ip_queue.task_done()
if __name__ == "__main__":
start_time = time.time()
print(f"开始扫描 {IP_BASE}{START_IP}{IP_BASE}{END_IP}{TARGET_PORT} 端口...")
# 创建IP队列
ip_queue = Queue()
for i in range(START_IP, END_IP + 1):
ip = f"{IP_BASE}{i}"
ip_queue.put(ip)
# 创建存储开放端口IP的队列
result_queue = Queue()
# 创建并启动线程
threads = []
for _ in range(THREAD_COUNT):
thread = threading.Thread(target=worker, args=(ip_queue, result_queue))
thread.start()
threads.append(thread)
# 等待所有IP都被处理
ip_queue.join()
# 收集结果
open_ips = []
while not result_queue.empty():
open_ips.append(result_queue.get())
# 排序结果
open_ips.sort(key=lambda x: int(x.split(".")[-1]))
# 输出结果
print("\n扫描完成!")
print(f"耗时: {time.time() - start_time:.2f}")
print(f"发现 {len(open_ips)} 个设备的 {TARGET_PORT} 端口开放:")
for ip in open_ips:
print(f" {ip}:{TARGET_PORT}")
-50
View File
@@ -1,50 +0,0 @@
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['port.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='port',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='port',
)
+114
View File
@@ -0,0 +1,114 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "fee9c5bf",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"401\n",
"{'code': 'INVALID_API_KEY', 'message': 'Invalid API key'}\n"
]
}
],
"source": [
"import requests\n",
"\n",
"base_url = \"https://console.pivotbak.cfd/v1\"\n",
"api_key = \"sk-e5246cf15eed1c8c1b94f172c95115de3ae5413eaa5b0366810fa7842de6ada1\"\n",
"\n",
"resp = requests.get(\n",
" f\"{base_url}/models\",\n",
" headers={\n",
" \"Authorization\": f\"Bearer {api_key}\",\n",
" \"Content-Type\": \"application/json\",\n",
" },\n",
" timeout=30,\n",
")\n",
"\n",
"print(resp.status_code)\n",
"print(resp.json())"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "c479e82c",
"metadata": {},
"outputs": [
{
"ename": "ModuleNotFoundError",
"evalue": "No module named 'curl_cffi'",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[11], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mos\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mcurl_cffi\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m requests\n\u001b[0;32m 4\u001b[0m BASE_URL \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhttps://console.pivotbak.cfd/v1\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 5\u001b[0m API_KEY \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msk-e5246cf15eed1c8c1b94f172c95115de3ae5413eaa5b0366810fa7842de6ada1\u001b[39m\u001b[38;5;124m\"\u001b[39m\n",
"\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'curl_cffi'"
]
}
],
"source": [
"import os\n",
"from curl_cffi import requests\n",
"\n",
"BASE_URL = \"https://console.pivotbak.cfd/v1\"\n",
"API_KEY = \"sk-e5246cf15eed1c8c1b94f172c95115de3ae5413eaa5b0366810fa7842de6ada1\"\n",
"\n",
"headers = {\n",
" \"Authorization\": f\"Bearer {API_KEY}\",\n",
" \"x-api-key\": API_KEY,\n",
" \"Accept\": \"*/*\",\n",
" \"Content-Type\": \"application/json\",\n",
" \"sec-ch-ua-platform\": '\"Windows\"',\n",
" \"sec-ch-ua\": '\"Not-A.Brand\";v=\"24\", \"Chromium\";v=\"146\"',\n",
" \"sec-ch-ua-mobile\": \"?0\",\n",
" \"x-title\": \"Cherry Studio\",\n",
" \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) CherryStudio/1.9.9 Chrome/146.0.7680.188 Electron/41.2.1 Safari/537.36\",\n",
" \"HTTP-Referer\": \"https://cherry-ai.com\",\n",
" \"Sec-Fetch-Site\": \"cross-site\",\n",
" \"Sec-Fetch-Mode\": \"cors\",\n",
" \"Sec-Fetch-Dest\": \"empty\",\n",
" \"Accept-Encoding\": \"gzip, deflate, br, zstd\",\n",
" \"Accept-Language\": \"zh-CN\",\n",
" \"Priority\": \"u=1, i\",\n",
"}\n",
"\n",
"resp = requests.get(\n",
" f\"{BASE_URL}/models\",\n",
" headers=headers,\n",
" impersonate=\"chrome136\",\n",
" timeout=30,\n",
")\n",
"\n",
"print(\"status:\", resp.status_code)\n",
"print(resp.text)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
File diff suppressed because one or more lines are too long
+30
View File
@@ -0,0 +1,30 @@
"input": "最近一次考试是什么?",
"input": "最近一次数学考试的成绩情况",
"input": "最近一次英语考试各班考得怎么样",
"input": "最近一次语文考试全年级的平均分",
"input": "最近一次考试是谁发布的?",
"input": "帮我查一下期中相关的成绩批次",
"input": "帮我看看最近一次数学考试的数据结构",
"input": "帮我分析最近一次数学考试各班成绩情况",
"input": "帮我看看最近一次数学考试整个年级的成绩概况",
"input": "帮我分析最近一次数学考试的分数分布情况",
"input": "帮我对比分析最近一次考试语文数学英语三个科目的成绩情况",
"input": "帮我查一下白若耶是哪位学生",
"input": "帮我看看白若耶最近整体成绩怎么样",
"input": "把白若耶最近几次数学成绩列出来",
"input": "白若耶最近10次数学考试的成绩趋势怎么样",
"input": "只分析语文数学英语这三科,帮我看白若耶哪科强哪科弱",
"input": "只看语文数学英语三科,白若耶偏科吗?",
"input": "白若耶最近有没有退步预警?",
"input": "帮我看看白若耶最近一次考试的成绩详情",
"input": "先给我看看趋势分析有哪些可用参数和批次",
"input": "帮我看一班最近几次数学考试的均分走势",
"input": "帮我看最近几次数学考试整体均分变化",
"input": "白若耶这次考试比上次是进步还是退步?",
"input": "白若耶最近一次考试排第几名?",
"input": "最近一次数学考试分段分析有哪些可用配置?",
"input": "帮我看最近一次数学考试各分段人数分布",
"input": "帮我看最近一次数学考试高分段有哪些学生",
"input": "帮我比较最近两次数学考试各分数段人数变化",
"input": "帮我对比分析语文数学英语三个科目在不同批次的成绩情况,按班级分组",
"input": "帮我对比分析白若耶在语文数学英语三个科目的跨批次成绩"
+184
View File
@@ -0,0 +1,184 @@
const BASE_URL = process.env.LANGGRAPH_URL || "http://192.168.0.100:2026";
const ASSISTANT_ID = process.env.ASSISTANT_ID || "student_score";
const QUESTION = process.env.QUESTION || "白若耶最近10次数学考试的成绩趋势怎么样";
const CONTEXT = {
team_id: process.env.TEAM_ID || "19",
env: process.env.AGENT_ENV || "dev",
};
function parseJson(text) {
try {
return JSON.parse(text);
} catch {
return text;
}
}
async function createThread() {
const response = await fetch(`${BASE_URL}/threads`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({}),
});
if (!response.ok) {
throw new Error(`create thread failed: ${response.status} ${await response.text()}`);
}
const thread = await response.json();
return thread.thread_id;
}
function pickFinalAnswer(data) {
if (!data || typeof data !== "object" || Array.isArray(data)) {
return "";
}
const renderAnswer = data.render_answer;
if (renderAnswer && typeof renderAnswer.answer === "string") {
return renderAnswer.answer;
}
if (typeof data.answer === "string") {
return data.answer;
}
return "";
}
function pickReasoning(data) {
if (!data || typeof data !== "object" || Array.isArray(data)) {
return "";
}
const renderAnswer = data.render_answer;
if (renderAnswer && typeof renderAnswer.reasoning === "string") {
return renderAnswer.reasoning;
}
if (typeof data.reasoning === "string") {
return data.reasoning;
}
return "";
}
function handleEvent(eventName, dataText, answerParts, finalAnswers) {
const data = parseJson(dataText);
if (eventName === "updates") {
const finalAnswer = pickFinalAnswer(data);
const reasoning = pickReasoning(data);
if (data && typeof data === "object" && !Array.isArray(data)) {
console.log(`\n[updates] ${Object.keys(data).join(", ")}`);
} else {
console.log("\n[updates]", data);
}
if (reasoning) {
console.log("\n[reasoning]");
console.log(reasoning);
}
if (finalAnswer) {
finalAnswers.push(finalAnswer);
console.log("\n[final.answer]");
console.log(finalAnswer);
}
return;
}
if (eventName === "messages") {
const messageChunk = Array.isArray(data) ? data[0] : undefined;
const content = messageChunk && typeof messageChunk.content === "string" ? messageChunk.content : "";
if (content) {
answerParts.push(content);
process.stdout.write(content);
}
return;
}
if (eventName) {
console.log(`\n[${eventName}]`, data);
}
}
async function readSse(response) {
if (!response.body) {
throw new Error("response body is empty");
}
const reader = response.body.getReader();
const decoder = new TextDecoder("utf-8");
const answerParts = [];
const finalAnswers = [];
let buffer = "";
while (true) {
const { value, done } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const events = buffer.split(/\r?\n\r?\n/);
buffer = events.pop() || "";
for (const rawEvent of events) {
let eventName = "";
const dataLines = [];
for (const line of rawEvent.split(/\r?\n/)) {
if (line.startsWith("event:")) {
eventName = line.slice("event:".length).trim();
} else if (line.startsWith("data:")) {
dataLines.push(line.slice("data:".length).trimStart());
}
}
handleEvent(eventName, dataLines.join("\n"), answerParts, finalAnswers);
}
}
if (buffer.trim()) {
handleEvent("", buffer.trim(), answerParts, finalAnswers);
}
return finalAnswers.at(-1) || answerParts.join("");
}
async function main() {
const threadId = await createThread();
const endpoint = `${BASE_URL}/threads/${threadId}/runs/stream`;
const started = Date.now();
console.log("=== LangGraph fetch stream test ===");
console.log(`base_url: ${BASE_URL}`);
console.log(`assistant_id: ${ASSISTANT_ID}`);
console.log(`thread_id: ${threadId}`);
console.log("");
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "text/event-stream",
},
body: JSON.stringify({
assistant_id: ASSISTANT_ID,
input: { question: QUESTION },
context: CONTEXT,
stream_mode: ["updates", "messages-tuple"],
}),
});
if (!response.ok) {
throw new Error(`stream request failed: ${response.status} ${await response.text()}`);
}
const answer = await readSse(response);
const elapsed = ((Date.now() - started) / 1000).toFixed(2);
console.log(`\n\n=== done: ${elapsed}s, answer length: ${answer.length} ===`);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
+108
View File
@@ -0,0 +1,108 @@
from __future__ import annotations
import asyncio
import os
import sys
from typing import Any
from langgraph_sdk import get_client
BASE_URL = os.getenv("LANGGRAPH_URL", "http://192.168.0.100:2026")
ASSISTANT_ID = "student_score"
QUESTION = "帮我看看白若耶同学的信息"
CONTEXT = {
"team_id": "19",
"env": "dev",
}
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(encoding="utf-8")
def event_data(event: Any) -> Any:
if isinstance(event, dict):
return event.get("data")
return getattr(event, "data", None)
def event_name(event: Any) -> str:
if isinstance(event, dict):
return str(event.get("event") or "")
return str(getattr(event, "event", ""))
def pick_final_answer(data: Any) -> str:
if not isinstance(data, dict):
return ""
render_answer = data.get("render_answer")
if isinstance(render_answer, dict) and isinstance(render_answer.get("answer"), str):
return render_answer["answer"]
answer = data.get("answer")
return answer if isinstance(answer, str) else ""
def pick_answer_source(data: Any) -> str:
if not isinstance(data, dict):
return ""
render_answer = data.get("render_answer")
if isinstance(render_answer, dict) and isinstance(render_answer.get("answer_source"), str):
return render_answer["answer_source"]
answer_source = data.get("answer_source")
return answer_source if isinstance(answer_source, str) else ""
async def main() -> None:
client = get_client(url=BASE_URL)
thread = await client.threads.create()
answer_parts: list[str] = []
final_answers: list[str] = []
print("=== LangGraph updates + messages-tuple 流式调用 ===", flush=True)
print("[updates] 节点进度;[messages] 最终 Markdown token。", flush=True)
print("", flush=True)
async for event in client.runs.stream(
thread_id=thread["thread_id"],
assistant_id=ASSISTANT_ID,
input={"question": QUESTION},
context=CONTEXT,
stream_mode=["updates", "messages-tuple"],
):
name = event_name(event)
data = event_data(event)
if name == "updates":
final_answer = pick_final_answer(data)
answer_source = pick_answer_source(data)
if isinstance(data, dict):
print(f"\n[updates] {', '.join(data.keys())}", flush=True)
render_answer = data.get("render_answer")
if isinstance(render_answer, dict):
print(f"[render_answer.keys] {', '.join(render_answer.keys())}", flush=True)
else:
print(f"\n[updates] {data}", flush=True)
if answer_source:
print(f"[answer_source] {answer_source}", flush=True)
if final_answer:
final_answers.append(final_answer)
print("\n[final.answer]", flush=True)
print(final_answer, flush=True)
continue
if name == "messages":
if isinstance(data, list) and data:
message_chunk = data[0]
content = message_chunk.get("content") if isinstance(message_chunk, dict) else ""
if isinstance(content, str) and content:
answer_parts.append(content)
print(content, end="", flush=True)
continue
print("\n\n=== 最终 Markdown 长度 ===", flush=True)
print(len(final_answers[-1] if final_answers else "".join(answer_parts)), flush=True)
if __name__ == "__main__":
asyncio.run(main())
+58
View File
@@ -0,0 +1,58 @@
import requests
import time
from datetime import datetime
url = "http://10.68.66.174/mix.wav"
duration_minutes = 60 # 录制时长(分钟)
output_file = f"recording_{datetime.now().strftime('%Y%m%d_%H%M%S')}.wav"
duration_seconds = duration_minutes * 60
print(f"开始录制音频流...")
print(f"录制时长: {duration_minutes} 分钟")
print(f"保存路径: {output_file}")
start_time = time.time()
chunk_size = 8192
total_bytes = 0
last_print_time = 0
try:
response = requests.get(url, stream=True, timeout=60)
response.raise_for_status()
with open(output_file, 'wb') as f:
for chunk in response.iter_content(chunk_size=chunk_size):
if chunk:
f.write(chunk)
total_bytes += len(chunk)
elapsed = time.time() - start_time
# 每10秒打印一次进度
if int(elapsed) - last_print_time >= 10:
last_print_time = int(elapsed)
size_mb = total_bytes / (1024 * 1024)
remaining = int(duration_seconds - elapsed)
print(f"已录制: {int(elapsed)}秒 / {duration_seconds}秒 ({elapsed/duration_seconds*100:.1f}%), 大小: {size_mb:.2f}MB, 剩余: {remaining}")
# 达到指定时长后自动停止
if elapsed >= duration_seconds:
print(f"\n已达到指定录制时长 {duration_minutes} 分钟")
break
elapsed = time.time() - start_time
size_mb = total_bytes / (1024 * 1024)
print(f"\n录制完成!")
print(f"总时长: {int(elapsed)}秒 ({elapsed/60:.1f}分钟)")
print(f"文件大小: {size_mb:.2f}MB")
print(f"保存路径: {output_file}")
except KeyboardInterrupt:
elapsed = time.time() - start_time
size_mb = total_bytes / (1024 * 1024)
print(f"\n录制已手动停止")
print(f"总时长: {int(elapsed)}秒 ({elapsed/60:.1f}分钟)")
print(f"文件大小: {size_mb:.2f}MB")
print(f"保存路径: {output_file}")
except Exception as e:
print(f"错误: {e}")
+84 -27
View File
@@ -20,7 +20,7 @@
"port=3306,\n",
"user='root',\n",
"password='Abcd@123456',\n",
"database='hongxx_video',\n",
"database='hongxx',\n",
"charset='utf8'\n",
")\n",
"# 创建游标对象\n",
@@ -50,17 +50,17 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 26,
"id": "b717043a",
"metadata": {},
"outputs": [],
"source": [
"sql = 'select * from video_info'"
"sql = 'select * from sys_user where dept_id=100'\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 27,
"id": "b4b373b8",
"metadata": {},
"outputs": [],
@@ -72,46 +72,103 @@
},
{
"cell_type": "code",
"execution_count": 8,
"id": "84652b4b",
"execution_count": 28,
"id": "394495d3",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[2,\n",
" 3,\n",
" 4,\n",
" 6,\n",
" 24,\n",
" 31,\n",
" 308,\n",
" 909,\n",
" 917,\n",
" 918,\n",
" 1145,\n",
" 3690,\n",
" 3698,\n",
" 3828,\n",
" 3842,\n",
" 3843,\n",
" 3844,\n",
" 3895,\n",
" 3899,\n",
" 3912,\n",
" 3913,\n",
" 3935,\n",
" 3936,\n",
" 3988,\n",
" 5440,\n",
" 5492,\n",
" 7696,\n",
" 7713,\n",
" 7714,\n",
" 7723,\n",
" 7728,\n",
" 2059454179031199746]"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[i[\"user_id\"] for i in result]\n"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "325e4664",
"metadata": {},
"outputs": [],
"source": [
"result\n",
"# http://192.168.0.244:88/record/original-files/video/522e4c55fc804decafdd0a62e5a1bf74.mp4\n",
"for item in result:\n",
" if item[\"video_url\"].startswith(\"http://192.168.0.244:88\"):\n",
" video_url = item[\"video_url\"].replace(\"http://192.168.0.244:88\",\"/mp4\")\n",
" sql = f\"update video_info set video_url='{video_url}' where id={item['id']}\"\n",
" cursor.execute(sql)"
" userid = item[\"user_id\"]\n",
" \n",
" sql2 = f\"update sys_user set dept_id=100, team_user_type ='BACKEND' where user_id={userid}\"\n",
" cursor.execute(sql2)\n",
"connection.commit()"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "f62b4e7d",
"metadata": {},
"outputs": [],
"source": [
"for item in result:\n",
" userid = item[\"user_id\"]\n",
" sql2 = f\"update sys_user_dept set dept_id=100, person_type='hx_sys' where user_id={userid}\"\n",
" cursor.execute(sql2)\n",
"connection.commit()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0b4381f4",
"id": "7dcf47b8",
"metadata": {},
"outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31m在当前单元格或上一个单元格中执行代码时 Kernel 崩溃。\n",
"\u001b[1;31m请查看单元格中的代码,以确定故障的可能原因。\n",
"\u001b[1;31m单击<a href='https://aka.ms/vscodeJupyterKernelCrash'>此处</a>了解详细信息。\n",
"\u001b[1;31m有关更多详细信息,请查看 Jupyter <a href='command:jupyter.viewOutput'>log</a>。"
]
}
],
"outputs": [],
"source": [
"for item in result:\n",
" userid = item[\"user_id\"]\n",
" sql2 = f\"update sys_user_role set dept_id=100 where user_id={userid}\"\n",
" cursor.execute(sql2)\n",
"connection.commit()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
+116
View File
@@ -0,0 +1,116 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"id": "42e17205",
"metadata": {},
"outputs": [],
"source": [
"# %%\n",
"import pymysql\n",
"\n",
"# %%\n",
"\n",
"# 创建数据库连接\n",
"connection = pymysql.connect(\n",
"host='192.168.0.244',\n",
"port=3300,\n",
"user='root',\n",
"password='hxyd1109',\n",
"database='school_server',\n",
"charset='utf8'\n",
")\n",
"cursor = connection.cursor()\n",
"# %%\n",
"def create_table(cursor,result):\n",
" \n",
" data = []\n",
" for i in result:\n",
" list_list = list(i)\n",
" des=cursor.description # 获取表详情,字段名,长度,属性等\n",
" t = \",\".join([item[0] for item in des])\n",
" table_head = t.split(',') # # 查询表列名 用,分割\n",
" \n",
" dict_result = dict(zip(table_head, list_list)) # 打包为元组的列表 再转换为字典\n",
" data.append(dict_result) # 将字典添加到list_result中\n",
" return data\n",
"\n",
"# %%\n",
"\n",
"# %%\n",
"\n",
"# %%\n",
"sql1 = \"select * from teacher where id=828\"\n",
"cursor.execute(sql1)\n",
"result=cursor.fetchall()\n",
"table_app = create_table(cursor,result)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "54db4116",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'id': 828,\n",
" 'tea_name': '彭兰英',\n",
" 'sex': 2,\n",
" 'phone': '15198039323',\n",
" 'type': 6,\n",
" 'grade_id': None,\n",
" 'class_id': None,\n",
" 'user_name': 'ptszxbr9023',\n",
" 'team_id': '110',\n",
" 'pid': None,\n",
" 'serial_no': '1336827486',\n",
" 'openid': None,\n",
" 'tea_no': 'ptszxbr9023',\n",
" 'wx_phone': '15198039323',\n",
" 'user_id': None,\n",
" 'department_id': None,\n",
" 'zt_teacher_uuid': None,\n",
" 'hire': '职工',\n",
" 'power': '门卫安保',\n",
" 'class_type_name': None,\n",
" 'hire_id': 98,\n",
" 'flag': None,\n",
" 'state': 1,\n",
" 'sync_source': 'local'}]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"table_app"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
+46
View File
@@ -0,0 +1,46 @@
import pymysql
import random
import datetime
import random
# 创建数据库连接
connection = pymysql.connect(
host='192.168.0.244',
port=3300,
user='root',
password='hxyd1109',
database='school_server',
charset='utf8'
)
# 创建游标对象
cursor = connection.cursor()
orgianl = {'id': 828,
'tea_name': '彭兰英',
'sex': 2,
'phone': '15198039323',
'type': 6,
'grade_id': None,
'class_id': None,
'user_name': 'ptszxbr9023',
'team_id': '110',
'pid': None,
'serial_no': '1336827486',
'openid': None,
'tea_no': 'ptszxbr9023',
'wx_phone': '15198039323',
'user_id': None,
'department_id': None,
'zt_teacher_uuid': None,
'hire': '职工',
'power': '门卫安保',
'class_type_name': None,
'hire_id': 98,
'flag': None,
'state': 1,
'sync_source': 'local'}
sql = f"""
UPDATE `school_server`.`teacher` SET `tea_name` = '彭兰英' WHERE `id` = 828;
"""
cursor.execute(sql)
connection.commit()
cursor.close()
connection.close()
+2 -2
View File
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 1,
"id": "b82fd271",
"metadata": {},
"outputs": [],
@@ -27,7 +27,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 2,
"id": "759c550a",
"metadata": {},
"outputs": [],
+206
View File
@@ -0,0 +1,206 @@
# %%
import pymysql
import pandas as pd
import snowflake
import random
# %%
# 创建数据库连接
connection = pymysql.connect(
host='100.64.0.36',
user='root',
password='@HXYD1109mysql',
database='school_server',
charset='utf8'
)
# 创建游标对象
cursor = connection.cursor()
sql="select id,stu_name from student where team_id=19"
cursor.execute(sql)
result=cursor.fetchall()
# %%
def create_table(cursor,result):
data = []
for i in result:
list_list = list(i)
des=cursor.description # 获取表详情,字段名,长度,属性等
t = ",".join([item[0] for item in des])
table_head = t.split(',') # # 查询表列名 用,分割
dict_result = dict(zip(table_head, list_list)) # 打包为元组的列表 再转换为字典
data.append(dict_result) # 将字典添加到list_result中
return data
# %%
table = create_table(cursor,result)
# %%
# %%
sql1 = "select user_name from account"
cursor.execute(sql1)
result=cursor.fetchall()
table_app = create_table(cursor,result)
# %%
# %%
from requests import get,post
import pandas as pd
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
import threading
# %%
# 常用弱密码列表
WEAK_PASSWORDS = [
"123456a",
"123456",
"admin123",
"password",
"admin@123",
"root123",
"12345678",
"123456789",
"888888",
"666666",
"123123",
"111111",
"qwerty",
"abc123",
"1q2w3e",
"1qaz2wsx",
"a123456",
"Aa123456",
"@123456",
"Abcd1234",
"Abcd@123",
"admin",
"123321",
"000000",
"1234",
"12345",
"test123",
"pass123",
"1234567",
"1234567890",
]
BASE_URL = "http://band.hxzhxy.cn"
# 先用一个已知弱密码账号验证接口是否通畅
print("=" * 50)
print("验证接口是否通畅...")
test_param = {
"username": "zhongwei",
"password": "123456a",
"client_id": "client",
"grant_type": "password",
"client_secret": "123456",
}
try:
test_resp = get(url=f"{BASE_URL}/oauth/token", params=test_param, timeout=10).json()
if "access_token" in test_resp:
print("接口通畅,已获取测试 token")
else:
print(f"接口返回: {test_resp}")
except Exception as e:
print(f"接口请求异常: {e}")
# %%
# 线程安全的检测结果
weak_accounts = []
total_attempts = [0]
lock = threading.Lock()
def try_account_password(account_idx, username):
"""尝试单个账号的所有弱密码,返回找到的弱密码或 None"""
for pwd in WEAK_PASSWORDS:
param = {
"username": username,
"password": pwd,
"client_id": "client",
"grant_type": "password",
"client_secret": "123456",
}
with lock:
total_attempts[0] += 1
attempt = total_attempts[0]
try:
resp = get(url=f"{BASE_URL}/oauth/token", params=param, timeout=10)
data = resp.json()
if "access_token" in data:
print(f"[弱密码] 账号#{account_idx}: {username} | 密码: {pwd} | token: {data['access_token'][:20]}...")
return {
"username": username,
"password": pwd,
"token": data["access_token"],
}
except Exception as e:
print(f" [异常] #{account_idx} {username} / {pwd} -> {e}")
return None
print("=" * 50)
print(f"开始检测 {len(table_app)} 个账号的弱密码...")
print(f"弱密码列表 ({len(WEAK_PASSWORDS)} 个): {WEAK_PASSWORDS}")
print(f"线程数: 3")
print("-" * 50)
start_time = time.time()
completed = [0]
with ThreadPoolExecutor(max_workers=3) as executor:
futures = {}
for i, account in enumerate(table_app, 1):
username = account['user_name']
future = executor.submit(try_account_password, i, username)
futures[future] = i
for future in as_completed(futures):
result = future.result()
with lock:
completed[0] += 1
if completed[0] % 10 == 0:
elapsed = time.time() - start_time
print(f"[进度] 已检测 {completed[0]}/{len(table_app)} | 用时 {elapsed:.1f}s | 发现弱密码: {len(weak_accounts)}")
if result:
with lock:
weak_accounts.append(result)
elapsed_total = time.time() - start_time
# %%
# 输出检测结果
print("=" * 50)
print("检测完成!")
print(f"累计尝试 {total_attempts[0]} 次请求")
print(f"耗时: {elapsed_total:.1f}")
print(f"发现 {len(weak_accounts)} 个弱密码账号:")
print("=" * 50)
if weak_accounts:
df_weak = pd.DataFrame(weak_accounts)
# token 太长,截断显示
df_weak["token_preview"] = df_weak["token"].str[:30] + "..."
df_display = df_weak[["username", "password", "token_preview"]]
print(df_display.to_string(index=False))
# 可选:导出到 Excel
# df_weak.to_excel("weak_password_accounts.xlsx", index=False)
# print("\n结果已导出到 weak_password_accounts.xlsx")
else:
print("未发现弱密码账号")
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+15
View File
@@ -0,0 +1,15 @@
# %%
import os
os.add_dll_directory(os.getcwd())
from pctoken import get_token
from requests import get,post
# %%
BASE_URL = 'http://net2.hxzhxy.cn:5092'
USERNAME = 'xiatianle'
PASSWORD = 'Xia123456'
TOKEN = get_token(BASE_URL, USERNAME, PASSWORD)["access_token"]
# %%
print(TOKEN)
+1 -1
View File
@@ -27,7 +27,7 @@ def get_token(base_url: str, username: str, password: str) -> dict:
oauth_client = 'hongxapp:hongxplapp'
enc_password = encrypt_password(password, enc_key)
print(enc_password)
url = f"{base_url.rstrip('/')}/auth/oauth2/token"
params = {
'username': username,
+238 -32
View File
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 2,
"id": "70c9ccec",
"metadata": {},
"outputs": [],
@@ -15,7 +15,7 @@
},
{
"cell_type": "code",
"execution_count": 24,
"execution_count": null,
"id": "379f4db2",
"metadata": {},
"outputs": [
@@ -23,81 +23,287 @@
"name": "stdout",
"output_type": "stream",
"text": [
"342e75d2-dd64-4d6b-9316-da51fdce642d\n"
"bN7Xn9xVdkyg\n"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31m在当前单元格或上一个单元格中执行代码时 Kernel 崩溃。\n",
"\u001b[1;31m请查看单元格中的代码,以确定故障的可能原因。\n",
"\u001b[1;31m单击<a href='https://aka.ms/vscodeJupyterKernelCrash'>此处</a>了解详细信息。\n",
"\u001b[1;31m有关更多详细信息,请查看 Jupyter <a href='command:jupyter.viewOutput'>log</a>。"
]
}
],
"source": [
"BASE_URL = \"http://192.168.0.244:9999\"\n",
"data = get_token(BASE_URL, \"admin\", \"123456\")\n",
"TOKEN = data.get(\"access_token\", \"\")\n",
"print(TOKEN)\n",
"headers = {\n",
" \"Authorization\": f\"Bearer {TOKEN}\",\n",
" \"hx-client\": \"hongxapp\",\n",
"}"
"BASE_URL = 'http://192.168.0.10:9999'\n",
"USERNAME = '00000001CDSPTSZX'\n",
"PASSWORD = 'xia123456'\n",
"TOKEN = get_token(BASE_URL, USERNAME, PASSWORD)[\"access_token\"]\n"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "820f6d23",
"execution_count": 5,
"id": "dcf475eb",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'{\"timestamp\":\"2026-02-27 15:36:51\",\"status\":500,\"error\":\"Internal Server Error\",\"path\":\"/videoInfoStream/page\"}'"
"'ee5552cb-7dd8-46b4-b54a-e8cf57e90ddc'"
]
},
"execution_count": 31,
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"TOKEN"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "820f6d23",
"metadata": {},
"outputs": [],
"source": [
"headers = {\n",
" \"Authorization\": f\"Bearer {TOKEN}\",\n",
" \"HX-CLIENT\": \"hongxapp\",\n",
" 'H-SV-CODE':'video',\n",
" 'Host': '192.168.0.111:5173',\n",
" 'Referer': 'http://192.168.0.111:5173/'\n",
"}\n",
"get( \" http://192.168.0.244:9999/video/videoInfoStream/page?current=1&size=10&descs=&ascs=\",headers=headers).text"
" 'hx-p-type':'WEB',\n",
" 'hx-t-type':'PLATFORM',\n",
"}\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2c7227e6",
"execution_count": 27,
"id": "dd5eb589",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'{\"timestamp\":\"2026-02-27 15:34:24\",\"status\":500,\"error\":\"Internal Server Error\",\"path\":\"/podPhoto/pageInfoBySections\"}'"
"{'Authorization': 'Bearer 295b20e2-1ce0-44ab-8d74-384cdefc16bb',\n",
" 'HX-CLIENT': 'hongxapp',\n",
" 'hx-p-type': 'WEB',\n",
" 'hx-t-type': 'PLATFORM'}"
]
},
"execution_count": 21,
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": []
"source": [
"headers"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1822efb2",
"id": "869391ea",
"metadata": {},
"outputs": [],
"source": [
" # \"Accept\": 'application/json, text/plain, */*',\n",
"# 'Connection': 'keep-alive',\n",
"# 'H-SV-CODE':'video',\n",
"# 'HX-CLIENT':'hongxapp',\n",
"# 'Host': '192.168.0.111:5173',\n",
"# 'Referer': 'http://192.168.0.111:5173/'"
"post('http://192.168.0.10:8888/api/admin/user/v1/exist/add', headers=headers, json={\"userId\":\"2\",\"deptId\":\"19\",\"roleId\":\"2053724615032193025\"})\n",
"{\"userId\":\"2\",\"deptId\":\"110\",\"roleId\":\"2055118564695838722\"}\n",
"{\"userId\":\"2\",\"deptId\":\"119\",\"roleId\":\"2059515940711231489\"}"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "7006382d",
"metadata": {},
"outputs": [],
"source": [
"user_ids = [\n",
" 3,\n",
" 4,\n",
" 6,\n",
" 24,\n",
" 31,\n",
" 308,\n",
" 909,\n",
" 917,\n",
" 918,\n",
" 1145,\n",
" 3690,\n",
" 3698,\n",
" 3828,\n",
" 3842,\n",
" 3843,\n",
" 3844,\n",
" 3895,\n",
" 3899,\n",
" 3912,\n",
" 3913,\n",
" 3935,\n",
" 3936,\n",
" 3988,\n",
" 5440,\n",
" 5492,\n",
" 7696,\n",
" 7713,\n",
" 7714,\n",
" 7723,\n",
" 7728,\n",
" 2059454179031199746]"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "0e7366e2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"==================================================\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"==================================================\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"==================================================\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"{\"code\":1,\"msg\":\"用户不存在\",\"data\":null,\"ok\":false}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"{\"code\":0,\"msg\":null,\"data\":true,\"ok\":true}\n",
"==================================================\n"
]
}
],
"source": [
"for user_id in user_ids:\n",
" resp = post('http://192.168.0.10:9999/admin/user/v1/exist/add', headers=headers, json={\"userId\":str(user_id),\"deptId\":\"110\",\"roleId\":\"2055118564695838722\"}).text\n",
" resp1 = post('http://192.168.0.10:9999/admin/user/v1/exist/add', headers=headers, json={\"userId\":str(user_id),\"deptId\":\"119\",\"roleId\":\"2059515940711231489\"}).text\n",
" resp2 = post('http://192.168.0.10:9999/admin/user/v1/exist/add', headers=headers, json={\"userId\":str(user_id),\"deptId\":\"19\",\"roleId\":\"2053724615032193025\"}).text\n",
" print(resp)\n",
" print(resp1)\n",
" print(resp2)\n",
" print(\"=\"*50)\n"
]
}
],
File diff suppressed because one or more lines are too long
+30 -16
View File
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 18,
"execution_count": 1,
"id": "d9c14718",
"metadata": {},
"outputs": [],
@@ -29,7 +29,7 @@
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": 2,
"id": "1673af54",
"metadata": {},
"outputs": [],
@@ -43,7 +43,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 3,
"id": "4cf83c82",
"metadata": {},
"outputs": [],
@@ -56,7 +56,7 @@
},
{
"cell_type": "code",
"execution_count": 21,
"execution_count": 4,
"id": "1790800e",
"metadata": {},
"outputs": [],
@@ -66,7 +66,7 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 5,
"id": "34f18ca5",
"metadata": {},
"outputs": [],
@@ -77,7 +77,7 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": 6,
"id": "7cf83679",
"metadata": {},
"outputs": [
@@ -87,7 +87,7 @@
"0"
]
},
"execution_count": 23,
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
@@ -120,17 +120,17 @@
},
{
"cell_type": "code",
"execution_count": 24,
"execution_count": 8,
"id": "e706bbb0",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<paho.mqtt.client.MQTTMessageInfo at 0x1b6a5f5e0c0>"
"<paho.mqtt.client.MQTTMessageInfo at 0x1f295d5cef0>"
]
},
"execution_count": 24,
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
@@ -146,10 +146,10 @@
"metadata": {},
"outputs": [],
"source": [
"for item in data[0:1]:\n",
"for item in data:\n",
" print(item)\n",
" mac=item[\"mac\"]\n",
" topic=f\"cmd/publicizeBanpai/08E60E75E09E/control\"\n",
" topic=f\"cmd/publicizeBanpai/{mac}/cmd\"\n",
" message={\n",
" \"type\":\"info\"\n",
" }\n",
@@ -158,17 +158,31 @@
},
{
"cell_type": "code",
"execution_count": 31,
"execution_count": 11,
"id": "3da280f9",
"metadata": {},
"outputs": [],
"source": [
"for item in data:\n",
" mac=item[\"mac\"]\n",
" topic=f\"cmd/publicizeBanpai/{mac}/cmd\"\n",
" message=\"reboot -p\"\n",
" client.publish(topic, message)\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "82403f63",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<paho.mqtt.client.MQTTMessageInfo at 0x1b6a5c2bec0>"
"<paho.mqtt.client.MQTTMessageInfo at 0x1f295d5c360>"
]
},
"execution_count": 31,
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
@@ -204,7 +218,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "undefined.undefined.undefined"
"version": "3.12.4"
}
},
"nbformat": 4,
+29 -36
View File
@@ -1,42 +1,35 @@
from requests import get, post, put, delete
import random
from requests import get, post
import time
ip = "http://192.168.0.209:8100"
param = {
"username": "zhongwei",
"password": "123456a",
"client_id": "client",
"grant_type": "password",
"client_secret": "123456",
}
data = get(url=f"{ip}/oauth/token", params=param).json()
token = data["access_token"]
header = {
"content-type": "application/json",
"authorization": f"Bearer {token}",
}
teamId = 110
year = 2026
month = 3
# v1.jinrishici.com/all.json
def apiSentence():
data = get("https://v1.hitokoto.cn").json()
return data
data1 = get(f"{ip}/classAttend/screen/summary", headers=header, params={"teamId": teamId, "year": year, "month": month}).text
print("summary:", data1, end="\n\n")
data2 = get(f"{ip}/classAttend/screen/dailyTrend", headers=header, params={"teamId": teamId, "year": year, "month": month}).text
print("dailyTrend:", data2, end="\n\n")
def cat():
data = get("https://api.thecatapi.com/v1/images/search?size=full").json()
result = data[0]["url"]
return result
data3 = get(f"{ip}/classAttend/screen/statusPie", headers=header, params={"teamId": teamId, "year": year, "month": month}).text
print("statusPie:", data3, end="\n\n")
data4 = get(f"{ip}/classAttend/screen/gradeRanking", headers=header, params={"teamId": teamId, "year": year, "month": month}).text
print("gradeRanking:", data4, end="\n\n")
def dog():
data = get("https://api.thedogapi.com/v1/images/search?size=full").json()
result = data[0]["url"]
return result
def pic():
data = get("https://api.vvhan.com/api/bing?type=json&rand=sj").json()
result = data["data"]["url"]
return result
def randomPic():
func = random.choice([cat])
data = func()
return data
def getEmoji():
data = get("https://api.vvhan.com/api/emoji?type=json").json()
return data
def getShi():
data = post("http://v1.jinrishici.com/all.json").json()
return data
data5 = get(f"{ip}/classAttend/screen/studentRanking", headers=header, params={"teamId": teamId, "year": year, "month": month}).text
print("studentRanking:", data5, end="\n\n")
+35
View File
@@ -0,0 +1,35 @@
from requests import get,post
import time
ip = "http://192.168.0.209:8100"
param = {
"username": "zhongwei",
"password": "123456a",
"client_id": "client",
"grant_type": "password",
"client_secret": "123456",
}
data = get(url=f"{ip}/oauth/token",params=param).json()
token = data["access_token"]
header = {
"content-type": "application/json",
"authorization": f"Bearer {token}",
}
teamId=110
month=5
data1= get(f"{ip}/counseling/screen/stats",headers=header,params={"teamId":teamId,"year":2026,"month":month}).text
print(data1,end="\n\n")
data2=get(f"{ip}/counseling/screen/trend",headers=header,params={"teamId":teamId,"year":2026,"month":month}).text
print(data2,end="\n\n")
data3=get(f"{ip}/counseling/screen/statusDistribution",headers=header,params={"teamId":teamId,"year":2026,"month":month}).text
print(data3,end="\n\n")
data4=get(f"{ip}/counseling/screen/gradeStats",headers=header,params={"teamId":teamId,"year":2026,"month":month}).text
print(data4,end="\n\n")
data5=get(f"{ip}/counseling/screen/projectStats",headers=header,params={"teamId":teamId,"year":2026,"month":month}).text
print(data5,end="\n\n")
data6=get(f"{ip}/counseling/screen/completionStats",headers=header,params={"teamId":teamId,"year":2026,"month":month}).text
print(data6,end="\n\n")
File diff suppressed because one or more lines are too long
+17
View File
@@ -0,0 +1,17 @@
from requests import post
tem = post("http://11.1.1.106:8082/api",json={
"service_name": "operate_plate",
"data": [
{
"departName": "百仁",
"authType": 30000,
"plateNumber": "鄂A1234569",
"personName": "夏天乐测试",
"plateIdStr": "test-plate-id-001",
"opType": 1,
"beginTime": "2026-05-18 17:53:44",
"endTime": "2027-05-18 17:53:44"
}
]
}).text
print(tem)
@@ -0,0 +1,288 @@
from requests import get, post
from faker import Faker
import random
import time
import uuid
import json
from datetime import datetime, timedelta
fake = Faker('zh_CN')
ip = "http://band.hxzhxy.cn"
param = {
"username": "xtl",
"password": "xia123456",
"client_id": "client",
"grant_type": "password",
"client_secret": "123456",
}
def get_token():
data = get(url=f"{ip}/oauth/token", params=param).json()
return data["access_token"]
token = get_token()
header = {
"content-type": "application/json",
"authorization": f"Bearer {token}",
}
teamId = 106
def generate_leave_data(stu_id, stu_name, stu_no, grade_name, class_name, grade_id, class_id, phone=None):
leave_types = ["事假", "病假"]
leave_type = random.choice(leave_types)
is_cycle = random.choice([1, 2, 3])
begin_date = datetime.now() - timedelta(days=random.randint(0,15))
end_date = begin_date + timedelta(days=random.randint(0, 120))
begin_section = random.randint(1, 6)
end_section = random.randint(begin_section, 12)
leave_reasons = [
"身体不适,需要休息",
"家中有事需要处理",
"去医院检查身体",
"发烧感冒,需要就医",
"参加重要家庭活动",
"个人事务需要处理",
"肠胃不适,需要就医",
"头痛发热,请假休息",
"参加校外培训活动",
"家庭紧急事务",
]
disease_date = begin_date.strftime("%Y-%m-%d")
if is_cycle == 3:
week_days = ["周一", "周二", "周三", "周四", "周五"]
selected_day = random.choice(week_days)
sections = random.sample(range(1, 13), random.randint(2, 4))
sections.sort()
week_info = json.dumps({selected_day: ",".join(str(s) for s in sections)})
end_date = begin_date
else:
week_info = None
data = {
"stuId": str(stu_id),
"leaveType": leave_type,
"isCycle": is_cycle,
"leaveReason": random.choice(leave_reasons),
"beginDate": begin_date.strftime("%Y-%m-%d"),
"endDate": end_date.strftime("%Y-%m-%d"),
"beginSection": str(begin_section),
"endSection": str(end_section),
"diseaseDate": disease_date,
"symptom": "",
"fever": "",
"hospital": "",
"treatmentDate": "",
"imgUrl": "[]",
"weekInfo": week_info,
}
return data
def get_grade_list():
url = f"{ip}/uc/grade/listSelect/{teamId}?access_token={token}"
response = get(url, headers=header)
result = response.json()
if result.get('code') == 0:
return result.get('data', [])
return []
def get_class_list(grade_id):
url = f"{ip}/uc/class/listClass"
params = {
"access_token": token,
"teamId": teamId,
"gradeId": grade_id
}
response = get(url, params=params, headers=header)
result = response.json()
if result.get('code') == 0:
return result.get('data', [])
return []
def get_students_from_db(grade_id=None, class_id=None):
import pymysql
conn = pymysql.connect(
host='192.168.0.244',
port=3306,
user='root',
password='Abcd@123456',
database='school_server',
charset='utf8'
)
cursor = conn.cursor()
sql = """
SELECT s.id, s.stu_no, s.stu_name, s.phone,
g.grade_name, c.class_name
FROM student s
LEFT JOIN grade g ON s.grade_id = g.id
LEFT JOIN tclass c ON s.class_id = c.id
WHERE s.team_id = %s
"""
params = [str(teamId)]
if grade_id:
sql += " AND s.grade_id = %s"
params.append(grade_id)
if class_id:
sql += " AND s.class_id = %s"
params.append(class_id)
sql += " ORDER BY RAND() LIMIT 100"
cursor.execute(sql, params)
students = cursor.fetchall()
conn.close()
return students
def add_leave_record(leave_data):
url = f"{ip}/studentLeave/add"
leave_data["access_token"] = token
response = post(url, json=leave_data, headers=header)
return response.json()
def batch_add_leaves(count=10):
print(f"正在获取年级列表...")
grades = get_grade_list()
if not grades:
print("未获取到年级数据,请检查 teamId 或 token")
return
grade = random.choice(grades)
grade_id = grade.get('id', grade.get('gradeId'))
grade_name = grade.get('gradeName', grade.get('name', ''))
print(f"随机选择年级: {grade_name}")
print(f"正在获取 [{grade_name}] 的班级列表...")
classes = get_class_list(grade_id)
if not classes:
print("未获取到班级数据")
return
cls = random.choice(classes)
class_id = cls.get('id', cls.get('classId'))
class_name = cls.get('className', cls.get('name', ''))
print(f"随机选择班级: {class_name}")
print(f"\n正在从数据库获取 [{grade_name} {class_name}] 的学生数据...")
students = get_students_from_db(grade_id, class_id)
print(f"获取到 {len(students)} 名学生")
if not students:
print("未获取到学生数据,请检查数据库连接")
return
success_count = 0
fail_count = 0
for i in range(min(count, len(students))):
stu = students[i]
stu_id, stu_no, stu_name, phone, db_grade_name, db_class_name = stu
leave_data = generate_leave_data(
stu_id, stu_name, stu_no,
grade_name, class_name, grade_id, class_id, phone
)
print(f"\n[{i+1}/{min(count, len(students))}] 为学生 {stu_name}({stu_no}) 添加请假记录...")
print(f" 请假类型: {leave_data['leaveType']}")
print(f" 请假时间: {leave_data['beginDate']} ~ {leave_data['endDate']}")
print(f" 请假节次: 第{leave_data['beginSection']}节 ~ 第{leave_data['endSection']}")
print(f" 请假事由: {leave_data['leaveReason']}")
try:
result = add_leave_record(leave_data)
if result.get('code') == 0:
print(f" ✓ 添加成功")
success_count += 1
else:
print(f" ✗ 添加失败: {result.get('msg', '未知错误')}")
fail_count += 1
except Exception as e:
print(f" ✗ 请求异常: {e}")
fail_count += 1
time.sleep(0.5)
print(f"\n{'='*50}")
print(f"批量添加完成!")
print(f"成功: {success_count}")
print(f"失败: {fail_count}")
def generate_fake_students(count=20):
students = []
for i in range(count):
stu = {
"id": i + 1,
"stu_no": f"2024{str(i+1).zfill(4)}",
"stu_name": fake.name(),
"phone": fake.phone_number(),
"grade_name": random.choice(["初一", "初二", "初三", "高一", "高二", "高三"]),
"class_name": f"{random.randint(1, 10)}",
}
students.append(stu)
return students
def batch_add_leaves_with_fake_students(count=10):
print(f"使用 Faker 生成 {count} 条请假记录...")
students = generate_fake_students(count)
success_count = 0
fail_count = 0
for i, stu in enumerate(students):
leave_data = generate_leave_data(
stu['id'], stu['stu_name'], stu['stu_no'],
stu['grade_name'], stu['class_name'],
None, None, stu['phone']
)
print(f"\n[{i+1}/{count}] 为学生 {stu['stu_name']}({stu['stu_no']}) 添加请假记录...")
print(f" 请假类型: {leave_data['leaveType']}")
print(f" 请假时间: {leave_data['beginDate']} ~ {leave_data['endDate']}")
print(f" 请假节次: 第{leave_data['beginSection']}节 ~ 第{leave_data['endSection']}")
print(f" 请假事由: {leave_data['leaveReason']}")
try:
result = add_leave_record(leave_data)
if result.get('code') == 0:
print(f" ✓ 添加成功")
success_count += 1
else:
print(f" ✗ 添加失败: {result.get('msg', '未知错误')}")
fail_count += 1
except Exception as e:
print(f" ✗ 请求异常: {e}")
fail_count += 1
time.sleep(0.5)
print(f"\n{'='*50}")
print(f"批量添加完成!")
print(f"成功: {success_count}")
print(f"失败: {fail_count}")
if __name__ == "__main__":
print("="*50)
print("批量添加学生请假信息")
print("="*50)
print("1. 从数据库获取学生并添加请假记录")
print("2. 使用 Faker 生成虚拟学生并添加请假记录")
print("="*50)
choice = input("请选择模式 (1/2): ").strip()
count = int(input("请输入要生成的请假记录数量: ").strip() or "10")
if choice == "1":
batch_add_leaves(count)
elif choice == "2":
batch_add_leaves_with_fake_students(count)
else:
print("无效选择")
@@ -0,0 +1,288 @@
from requests import get, post
from faker import Faker
import random
import time
import uuid
import json
from datetime import datetime, timedelta
fake = Faker('zh_CN')
ip = "http://band.hxzhxy.cn"
param = {
"username": "xtl",
"password": "xia123456",
"client_id": "client",
"grant_type": "password",
"client_secret": "123456",
}
def get_token():
data = get(url=f"{ip}/oauth/token", params=param).json()
return data["access_token"]
token = get_token()
header = {
"content-type": "application/json",
"authorization": f"Bearer {token}",
}
teamId = 106
def generate_leave_data(stu_id, stu_name, stu_no, grade_name, class_name, grade_id, class_id, phone=None):
leave_types = ["事假", "病假"]
leave_type = random.choice(leave_types)
is_cycle = random.choice([1, 2, 3])
begin_date = datetime.now() - timedelta(days=random.randint(0,15))
end_date = begin_date + timedelta(days=random.randint(0, 120))
begin_section = random.randint(1, 6)
end_section = random.randint(begin_section, 12)
leave_reasons = [
"身体不适,需要休息",
"家中有事需要处理",
"去医院检查身体",
"发烧感冒,需要就医",
"参加重要家庭活动",
"个人事务需要处理",
"肠胃不适,需要就医",
"头痛发热,请假休息",
"参加校外培训活动",
"家庭紧急事务",
]
disease_date = begin_date.strftime("%Y-%m-%d")
if is_cycle == 3:
week_days = ["周一", "周二", "周三", "周四", "周五"]
selected_day = random.choice(week_days)
sections = random.sample(range(1, 13), random.randint(2, 4))
sections.sort()
week_info = json.dumps({selected_day: ",".join(str(s) for s in sections)})
end_date = begin_date
else:
week_info = None
data = {
"stuId": str(stu_id),
"leaveType": leave_type,
"isCycle": is_cycle,
"leaveReason": random.choice(leave_reasons),
"beginDate": begin_date.strftime("%Y-%m-%d"),
"endDate": end_date.strftime("%Y-%m-%d"),
"beginSection": str(begin_section),
"endSection": str(end_section),
"diseaseDate": disease_date,
"symptom": "",
"fever": "",
"hospital": "",
"treatmentDate": "",
"imgUrl": "[]",
"weekInfo": week_info,
}
return data
def get_grade_list():
url = f"{ip}/uc/grade/listSelect/{teamId}?access_token={token}"
response = get(url, headers=header)
result = response.json()
if result.get('code') == 0:
return result.get('data', [])
return []
def get_class_list(grade_id):
url = f"{ip}/uc/class/listClass"
params = {
"access_token": token,
"teamId": teamId,
"gradeId": grade_id
}
response = get(url, params=params, headers=header)
result = response.json()
if result.get('code') == 0:
return result.get('data', [])
return []
def get_students_from_db(grade_id=None, class_id=None):
import pymysql
conn = pymysql.connect(
host='100.64.0.36',
port=3306,
user='root',
password='@HXYD1109mysql',
database='school_server',
charset='utf8'
)
cursor = conn.cursor()
sql = """
SELECT s.id, s.stu_no, s.stu_name, s.phone,
g.grade_name, c.class_name
FROM student s
LEFT JOIN grade g ON s.grade_id = g.id
LEFT JOIN tclass c ON s.class_id = c.id
WHERE s.team_id = %s
"""
params = [str(teamId)]
if grade_id:
sql += " AND s.grade_id = %s"
params.append(grade_id)
if class_id:
sql += " AND s.class_id = %s"
params.append(class_id)
sql += " ORDER BY RAND() LIMIT 100"
cursor.execute(sql, params)
students = cursor.fetchall()
conn.close()
return students
def add_leave_record(leave_data):
url = f"{ip}/studentLeave/add"
leave_data["access_token"] = token
response = post(url, json=leave_data, headers=header)
return response.json()
def batch_add_leaves(count=10):
print(f"正在获取年级列表...")
grades = get_grade_list()
if not grades:
print("未获取到年级数据,请检查 teamId 或 token")
return
grade = random.choice(grades)
grade_id = grade.get('id', grade.get('gradeId'))
grade_name = grade.get('gradeName', grade.get('name', ''))
print(f"随机选择年级: {grade_name}")
print(f"正在获取 [{grade_name}] 的班级列表...")
classes = get_class_list(grade_id)
if not classes:
print("未获取到班级数据")
return
cls = random.choice(classes)
class_id = cls.get('id', cls.get('classId'))
class_name = cls.get('className', cls.get('name', ''))
print(f"随机选择班级: {class_name}")
print(f"\n正在从数据库获取 [{grade_name} {class_name}] 的学生数据...")
students = get_students_from_db(grade_id, class_id)
print(f"获取到 {len(students)} 名学生")
if not students:
print("未获取到学生数据,请检查数据库连接")
return
success_count = 0
fail_count = 0
for i in range(min(count, len(students))):
stu = students[i]
stu_id, stu_no, stu_name, phone, db_grade_name, db_class_name = stu
leave_data = generate_leave_data(
stu_id, stu_name, stu_no,
grade_name, class_name, grade_id, class_id, phone
)
print(f"\n[{i+1}/{min(count, len(students))}] 为学生 {stu_name}({stu_no}) 添加请假记录...")
print(f" 请假类型: {leave_data['leaveType']}")
print(f" 请假时间: {leave_data['beginDate']} ~ {leave_data['endDate']}")
print(f" 请假节次: 第{leave_data['beginSection']}节 ~ 第{leave_data['endSection']}")
print(f" 请假事由: {leave_data['leaveReason']}")
try:
result = add_leave_record(leave_data)
if result.get('code') == 0:
print(f" ✓ 添加成功")
success_count += 1
else:
print(f" ✗ 添加失败: {result.get('msg', '未知错误')}")
fail_count += 1
except Exception as e:
print(f" ✗ 请求异常: {e}")
fail_count += 1
time.sleep(0.5)
print(f"\n{'='*50}")
print(f"批量添加完成!")
print(f"成功: {success_count}")
print(f"失败: {fail_count}")
def generate_fake_students(count=20):
students = []
for i in range(count):
stu = {
"id": i + 1,
"stu_no": f"2024{str(i+1).zfill(4)}",
"stu_name": fake.name(),
"phone": fake.phone_number(),
"grade_name": random.choice(["初一", "初二", "初三", "高一", "高二", "高三"]),
"class_name": f"{random.randint(1, 10)}",
}
students.append(stu)
return students
def batch_add_leaves_with_fake_students(count=10):
print(f"使用 Faker 生成 {count} 条请假记录...")
students = generate_fake_students(count)
success_count = 0
fail_count = 0
for i, stu in enumerate(students):
leave_data = generate_leave_data(
stu['id'], stu['stu_name'], stu['stu_no'],
stu['grade_name'], stu['class_name'],
None, None, stu['phone']
)
print(f"\n[{i+1}/{count}] 为学生 {stu['stu_name']}({stu['stu_no']}) 添加请假记录...")
print(f" 请假类型: {leave_data['leaveType']}")
print(f" 请假时间: {leave_data['beginDate']} ~ {leave_data['endDate']}")
print(f" 请假节次: 第{leave_data['beginSection']}节 ~ 第{leave_data['endSection']}")
print(f" 请假事由: {leave_data['leaveReason']}")
try:
result = add_leave_record(leave_data)
if result.get('code') == 0:
print(f" ✓ 添加成功")
success_count += 1
else:
print(f" ✗ 添加失败: {result.get('msg', '未知错误')}")
fail_count += 1
except Exception as e:
print(f" ✗ 请求异常: {e}")
fail_count += 1
time.sleep(0.5)
print(f"\n{'='*50}")
print(f"批量添加完成!")
print(f"成功: {success_count}")
print(f"失败: {fail_count}")
if __name__ == "__main__":
print("="*50)
print("批量添加学生请假信息")
print("="*50)
print("1. 从数据库获取学生并添加请假记录")
print("2. 使用 Faker 生成虚拟学生并添加请假记录")
print("="*50)
choice = input("请选择模式 (1/2): ").strip()
count = int(input("请输入要生成的请假记录数量: ").strip() or "10")
if choice == "1":
batch_add_leaves(count)
elif choice == "2":
batch_add_leaves_with_fake_students(count)
else:
print("无效选择")
@@ -0,0 +1,128 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "318e7588",
"metadata": {},
"outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31m在当前单元格或上一个单元格中执行代码时 Kernel 崩溃。\n",
"\u001b[1;31m请查看单元格中的代码,以确定故障的可能原因。\n",
"\u001b[1;31m单击<a href='https://aka.ms/vscodeJupyterKernelCrash'>此处</a>了解详细信息。\n",
"\u001b[1;31m有关更多详细信息,请查看 Jupyter <a href='command:jupyter.viewOutput'>log</a>。"
]
}
],
"source": [
"from requests import get,post\n",
"import time\n",
"ip = \"http://192.168.0.244:8100\"\n",
"param = {\n",
" \"username\": \"jz97621\",\n",
" \"password\": \"123456a\",\n",
" \"client_id\": \"client\",\n",
" \"grant_type\": \"password\",\n",
" \"client_secret\": \"123456\",\n",
"}\n",
"data = get(url=f\"{ip}/oauth/token\",params=param).json()\n",
"token = data[\"access_token\"]\n",
"header = {\n",
" \"content-type\": \"application/json\",\n",
" \"authorization\": f\"Bearer {token}\",\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3c046d8d",
"metadata": {},
"outputs": [
{
"ename": "ReadTimeout",
"evalue": "HTTPConnectionPool(host='192.168.0.209', port=8100): Read timed out. (read timeout=600)",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mTimeoutError\u001b[0m Traceback (most recent call last)",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\urllib3\\connectionpool.py:534\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[1;34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001b[0m\n\u001b[0;32m 533\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 534\u001b[0m response \u001b[38;5;241m=\u001b[39m conn\u001b[38;5;241m.\u001b[39mgetresponse()\n\u001b[0;32m 535\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (BaseSSLError, \u001b[38;5;167;01mOSError\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\urllib3\\connection.py:565\u001b[0m, in \u001b[0;36mHTTPConnection.getresponse\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 564\u001b[0m \u001b[38;5;66;03m# Get the response from http.client.HTTPConnection\u001b[39;00m\n\u001b[1;32m--> 565\u001b[0m httplib_response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mgetresponse()\n\u001b[0;32m 567\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\http\\client.py:1428\u001b[0m, in \u001b[0;36mHTTPConnection.getresponse\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1427\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m-> 1428\u001b[0m response\u001b[38;5;241m.\u001b[39mbegin()\n\u001b[0;32m 1429\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mConnectionError\u001b[39;00m:\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\http\\client.py:331\u001b[0m, in \u001b[0;36mHTTPResponse.begin\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 330\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[1;32m--> 331\u001b[0m version, status, reason \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_read_status()\n\u001b[0;32m 332\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m status \u001b[38;5;241m!=\u001b[39m CONTINUE:\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\http\\client.py:292\u001b[0m, in \u001b[0;36mHTTPResponse._read_status\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 291\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_read_status\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[1;32m--> 292\u001b[0m line \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mstr\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfp\u001b[38;5;241m.\u001b[39mreadline(_MAXLINE \u001b[38;5;241m+\u001b[39m \u001b[38;5;241m1\u001b[39m), \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124miso-8859-1\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 293\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(line) \u001b[38;5;241m>\u001b[39m _MAXLINE:\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\socket.py:708\u001b[0m, in \u001b[0;36mSocketIO.readinto\u001b[1;34m(self, b)\u001b[0m\n\u001b[0;32m 707\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 708\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_sock\u001b[38;5;241m.\u001b[39mrecv_into(b)\n\u001b[0;32m 709\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m timeout:\n",
"\u001b[1;31mTimeoutError\u001b[0m: timed out",
"\nThe above exception was the direct cause of the following exception:\n",
"\u001b[1;31mReadTimeoutError\u001b[0m Traceback (most recent call last)",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\requests\\adapters.py:589\u001b[0m, in \u001b[0;36mHTTPAdapter.send\u001b[1;34m(self, request, stream, timeout, verify, cert, proxies)\u001b[0m\n\u001b[0;32m 588\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 589\u001b[0m resp \u001b[38;5;241m=\u001b[39m conn\u001b[38;5;241m.\u001b[39murlopen(\n\u001b[0;32m 590\u001b[0m method\u001b[38;5;241m=\u001b[39mrequest\u001b[38;5;241m.\u001b[39mmethod,\n\u001b[0;32m 591\u001b[0m url\u001b[38;5;241m=\u001b[39murl,\n\u001b[0;32m 592\u001b[0m body\u001b[38;5;241m=\u001b[39mrequest\u001b[38;5;241m.\u001b[39mbody,\n\u001b[0;32m 593\u001b[0m headers\u001b[38;5;241m=\u001b[39mrequest\u001b[38;5;241m.\u001b[39mheaders,\n\u001b[0;32m 594\u001b[0m redirect\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[0;32m 595\u001b[0m assert_same_host\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[0;32m 596\u001b[0m preload_content\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[0;32m 597\u001b[0m decode_content\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[0;32m 598\u001b[0m retries\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmax_retries,\n\u001b[0;32m 599\u001b[0m timeout\u001b[38;5;241m=\u001b[39mtimeout,\n\u001b[0;32m 600\u001b[0m chunked\u001b[38;5;241m=\u001b[39mchunked,\n\u001b[0;32m 601\u001b[0m )\n\u001b[0;32m 603\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (ProtocolError, \u001b[38;5;167;01mOSError\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m err:\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\urllib3\\connectionpool.py:841\u001b[0m, in \u001b[0;36mHTTPConnectionPool.urlopen\u001b[1;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[0m\n\u001b[0;32m 839\u001b[0m new_e \u001b[38;5;241m=\u001b[39m ProtocolError(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mConnection aborted.\u001b[39m\u001b[38;5;124m\"\u001b[39m, new_e)\n\u001b[1;32m--> 841\u001b[0m retries \u001b[38;5;241m=\u001b[39m retries\u001b[38;5;241m.\u001b[39mincrement(\n\u001b[0;32m 842\u001b[0m method, url, error\u001b[38;5;241m=\u001b[39mnew_e, _pool\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m, _stacktrace\u001b[38;5;241m=\u001b[39msys\u001b[38;5;241m.\u001b[39mexc_info()[\u001b[38;5;241m2\u001b[39m]\n\u001b[0;32m 843\u001b[0m )\n\u001b[0;32m 844\u001b[0m retries\u001b[38;5;241m.\u001b[39msleep()\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\urllib3\\util\\retry.py:474\u001b[0m, in \u001b[0;36mRetry.increment\u001b[1;34m(self, method, url, response, error, _pool, _stacktrace)\u001b[0m\n\u001b[0;32m 473\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m read \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m \u001b[38;5;129;01mor\u001b[39;00m method \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_is_method_retryable(method):\n\u001b[1;32m--> 474\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m reraise(\u001b[38;5;28mtype\u001b[39m(error), error, _stacktrace)\n\u001b[0;32m 475\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m read \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\urllib3\\util\\util.py:39\u001b[0m, in \u001b[0;36mreraise\u001b[1;34m(tp, value, tb)\u001b[0m\n\u001b[0;32m 38\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m value\u001b[38;5;241m.\u001b[39mwith_traceback(tb)\n\u001b[1;32m---> 39\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m value\n\u001b[0;32m 40\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\urllib3\\connectionpool.py:787\u001b[0m, in \u001b[0;36mHTTPConnectionPool.urlopen\u001b[1;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[0m\n\u001b[0;32m 786\u001b[0m \u001b[38;5;66;03m# Make the request on the HTTPConnection object\u001b[39;00m\n\u001b[1;32m--> 787\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_make_request(\n\u001b[0;32m 788\u001b[0m conn,\n\u001b[0;32m 789\u001b[0m method,\n\u001b[0;32m 790\u001b[0m url,\n\u001b[0;32m 791\u001b[0m timeout\u001b[38;5;241m=\u001b[39mtimeout_obj,\n\u001b[0;32m 792\u001b[0m body\u001b[38;5;241m=\u001b[39mbody,\n\u001b[0;32m 793\u001b[0m headers\u001b[38;5;241m=\u001b[39mheaders,\n\u001b[0;32m 794\u001b[0m chunked\u001b[38;5;241m=\u001b[39mchunked,\n\u001b[0;32m 795\u001b[0m retries\u001b[38;5;241m=\u001b[39mretries,\n\u001b[0;32m 796\u001b[0m response_conn\u001b[38;5;241m=\u001b[39mresponse_conn,\n\u001b[0;32m 797\u001b[0m preload_content\u001b[38;5;241m=\u001b[39mpreload_content,\n\u001b[0;32m 798\u001b[0m decode_content\u001b[38;5;241m=\u001b[39mdecode_content,\n\u001b[0;32m 799\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mresponse_kw,\n\u001b[0;32m 800\u001b[0m )\n\u001b[0;32m 802\u001b[0m \u001b[38;5;66;03m# Everything went great!\u001b[39;00m\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\urllib3\\connectionpool.py:536\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[1;34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001b[0m\n\u001b[0;32m 535\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (BaseSSLError, \u001b[38;5;167;01mOSError\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m--> 536\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_raise_timeout(err\u001b[38;5;241m=\u001b[39me, url\u001b[38;5;241m=\u001b[39murl, timeout_value\u001b[38;5;241m=\u001b[39mread_timeout)\n\u001b[0;32m 537\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\urllib3\\connectionpool.py:367\u001b[0m, in \u001b[0;36mHTTPConnectionPool._raise_timeout\u001b[1;34m(self, err, url, timeout_value)\u001b[0m\n\u001b[0;32m 366\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(err, SocketTimeout):\n\u001b[1;32m--> 367\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m ReadTimeoutError(\n\u001b[0;32m 368\u001b[0m \u001b[38;5;28mself\u001b[39m, url, \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRead timed out. (read timeout=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtimeout_value\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m)\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 369\u001b[0m ) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01merr\u001b[39;00m\n\u001b[0;32m 371\u001b[0m \u001b[38;5;66;03m# See the above comment about EAGAIN in Python 3.\u001b[39;00m\n",
"\u001b[1;31mReadTimeoutError\u001b[0m: HTTPConnectionPool(host='192.168.0.209', port=8100): Read timed out. (read timeout=600)",
"\nDuring handling of the above exception, another exception occurred:\n",
"\u001b[1;31mReadTimeout\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[2], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;241m35\u001b[39m,\u001b[38;5;241m36\u001b[39m):\n\u001b[1;32m----> 2\u001b[0m post(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mip\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m/classAttendStu/createThisWeek\u001b[39m\u001b[38;5;124m\"\u001b[39m,headers\u001b[38;5;241m=\u001b[39mheader,params\u001b[38;5;241m=\u001b[39m{\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mplanId\u001b[39m\u001b[38;5;124m\"\u001b[39m:i},timeout\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m600\u001b[39m)\u001b[38;5;241m.\u001b[39mtext\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\requests\\api.py:115\u001b[0m, in \u001b[0;36mpost\u001b[1;34m(url, data, json, **kwargs)\u001b[0m\n\u001b[0;32m 103\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mpost\u001b[39m(url, data\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, json\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[0;32m 104\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124mr\u001b[39m\u001b[38;5;124;03m\"\"\"Sends a POST request.\u001b[39;00m\n\u001b[0;32m 105\u001b[0m \n\u001b[0;32m 106\u001b[0m \u001b[38;5;124;03m :param url: URL for the new :class:`Request` object.\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 112\u001b[0m \u001b[38;5;124;03m :rtype: requests.Response\u001b[39;00m\n\u001b[0;32m 113\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 115\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m request(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mpost\u001b[39m\u001b[38;5;124m\"\u001b[39m, url, data\u001b[38;5;241m=\u001b[39mdata, json\u001b[38;5;241m=\u001b[39mjson, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\requests\\api.py:59\u001b[0m, in \u001b[0;36mrequest\u001b[1;34m(method, url, **kwargs)\u001b[0m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;66;03m# By using the 'with' statement we are sure the session is closed, thus we\u001b[39;00m\n\u001b[0;32m 56\u001b[0m \u001b[38;5;66;03m# avoid leaving sockets open which can trigger a ResourceWarning in some\u001b[39;00m\n\u001b[0;32m 57\u001b[0m \u001b[38;5;66;03m# cases, and look like a memory leak in others.\u001b[39;00m\n\u001b[0;32m 58\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m sessions\u001b[38;5;241m.\u001b[39mSession() \u001b[38;5;28;01mas\u001b[39;00m session:\n\u001b[1;32m---> 59\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m session\u001b[38;5;241m.\u001b[39mrequest(method\u001b[38;5;241m=\u001b[39mmethod, url\u001b[38;5;241m=\u001b[39murl, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\requests\\sessions.py:589\u001b[0m, in \u001b[0;36mSession.request\u001b[1;34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[0m\n\u001b[0;32m 584\u001b[0m send_kwargs \u001b[38;5;241m=\u001b[39m {\n\u001b[0;32m 585\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtimeout\u001b[39m\u001b[38;5;124m\"\u001b[39m: timeout,\n\u001b[0;32m 586\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mallow_redirects\u001b[39m\u001b[38;5;124m\"\u001b[39m: allow_redirects,\n\u001b[0;32m 587\u001b[0m }\n\u001b[0;32m 588\u001b[0m send_kwargs\u001b[38;5;241m.\u001b[39mupdate(settings)\n\u001b[1;32m--> 589\u001b[0m resp \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msend(prep, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39msend_kwargs)\n\u001b[0;32m 591\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m resp\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\requests\\sessions.py:703\u001b[0m, in \u001b[0;36mSession.send\u001b[1;34m(self, request, **kwargs)\u001b[0m\n\u001b[0;32m 700\u001b[0m start \u001b[38;5;241m=\u001b[39m preferred_clock()\n\u001b[0;32m 702\u001b[0m \u001b[38;5;66;03m# Send the request\u001b[39;00m\n\u001b[1;32m--> 703\u001b[0m r \u001b[38;5;241m=\u001b[39m adapter\u001b[38;5;241m.\u001b[39msend(request, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 705\u001b[0m \u001b[38;5;66;03m# Total elapsed time of the request (approximately)\u001b[39;00m\n\u001b[0;32m 706\u001b[0m elapsed \u001b[38;5;241m=\u001b[39m preferred_clock() \u001b[38;5;241m-\u001b[39m start\n",
"File \u001b[1;32md:\\Anaconda3\\Lib\\site-packages\\requests\\adapters.py:635\u001b[0m, in \u001b[0;36mHTTPAdapter.send\u001b[1;34m(self, request, stream, timeout, verify, cert, proxies)\u001b[0m\n\u001b[0;32m 633\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m SSLError(e, request\u001b[38;5;241m=\u001b[39mrequest)\n\u001b[0;32m 634\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(e, ReadTimeoutError):\n\u001b[1;32m--> 635\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m ReadTimeout(e, request\u001b[38;5;241m=\u001b[39mrequest)\n\u001b[0;32m 636\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(e, _InvalidHeader):\n\u001b[0;32m 637\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidHeader(e, request\u001b[38;5;241m=\u001b[39mrequest)\n",
"\u001b[1;31mReadTimeout\u001b[0m: HTTPConnectionPool(host='192.168.0.209', port=8100): Read timed out. (read timeout=600)"
]
},
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31m在当前单元格或上一个单元格中执行代码时 Kernel 崩溃。\n",
"\u001b[1;31m请查看单元格中的代码,以确定故障的可能原因。\n",
"\u001b[1;31m单击<a href='https://aka.ms/vscodeJupyterKernelCrash'>此处</a>了解详细信息。\n",
"\u001b[1;31m有关更多详细信息,请查看 Jupyter <a href='command:jupyter.viewOutput'>log</a>。"
]
}
],
"source": [
"for i in range(35,36):\n",
" post(f\"{ip}/classAttendStu/createThisWeek\",headers=header,params={\"planId\":i},timeout=600).text"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "343a9e44",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
+774 -11
View File
@@ -2,24 +2,787 @@
"cells": [
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"id": "83d3f4d5",
"metadata": {},
"outputs": [],
"source": [
"from requests import get,post\n",
"import pandas as pd\n",
"import time\n",
"teamId = 19\n",
"ip = \"http://192.168.0.209:8100\"\n",
"param = {\n",
" \"username\": \"zhongwei\",\n",
" \"password\": \"123456a\",\n",
" \"client_id\": \"client\",\n",
" \"grant_type\": \"password\",\n",
" \"client_secret\": \"123456\",\n",
"}\n",
"data = get(url=f\"{ip}/oauth/token\",params=param).json()\n",
"token = data[\"access_token\"]\n",
"header = {\n",
" \"content-type\": \"application/json\",\n",
" \"authorization\": f\"Bearer {token}\",\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "873025e5",
"metadata": {},
"outputs": [
{
"ename": "",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31m在当前单元格或上一个单元格中执行代码时 Kernel 崩溃。\n",
"\u001b[1;31m请查看单元格中的代码,以确定故障的可能原因。\n",
"\u001b[1;31m单击<a href='https://aka.ms/vscodeJupyterKernelCrash'>此处</a>了解详细信息。\n",
"\u001b[1;31m有关更多详细信息,请查看 Jupyter <a href='command:jupyter.viewOutput'>log</a>。"
]
"data": {
"text/plain": [
"{'scrawlMaxSize': 10485760,\n",
" 'videoMaxSize': 104857600,\n",
" 'imageInsertAlign': 'none',\n",
" 'catcherMaxSize': 10485760,\n",
" 'snapscreenUrlPrefix': '',\n",
" 'videoActionName': 'video',\n",
" 'fileActionName': 'file',\n",
" 'imageCompressBorder': 5000,\n",
" 'imageManagerUrlPrefix': '',\n",
" 'imageManagerAllowFiles': ['.jpg', '.png', '.jpeg'],\n",
" 'scrawlUrlPrefix': '',\n",
" 'scrawlFieldName': 'file',\n",
" 'imageMaxSize': 10485760,\n",
" 'imageAllowFiles': ['.jpg', '.png', '.jpeg'],\n",
" 'snapscreenActionName': 'snap',\n",
" 'fileMaxSize': 104857600,\n",
" 'catcherActionName': 'catch',\n",
" 'fileFieldName': 'file',\n",
" 'fileManagerAllowFiles': ['.zip', '.pdf', '.doc'],\n",
" 'fileManagerActionName': 'listFile',\n",
" 'snapscreenInsertAlign': 'none',\n",
" 'fileUrlPrefix': '',\n",
" 'scrawlActionName': 'crawl',\n",
" 'imageManagerInsertAlign': 'none',\n",
" 'videoFieldName': 'file',\n",
" 'catcherLocalDomain': ['127.0.0.1', 'localhost'],\n",
" 'fileManagerListSize': 20,\n",
" 'imageActionName': 'image',\n",
" 'imageCompressEnable': True,\n",
" 'imageFieldName': 'file',\n",
" 'imageUrlPrefix': '',\n",
" 'videoUrlPrefix': '',\n",
" 'scrawlInsertAlign': 'none',\n",
" 'fileAllowFiles': ['.zip', '.pdf', '.doc'],\n",
" 'catcherUrlPrefix': '',\n",
" 'imageManagerListSize': 20,\n",
" 'catcherFieldName': 'source',\n",
" 'fileManagerUrlPrefix': '',\n",
" 'catcherAllowFiles': ['.jpg', '.png', '.jpeg'],\n",
" 'videoAllowFiles': ['.mp4'],\n",
" 'formulaConfig': {'imageUrlTemplate': 'https://r.latexeasy.com/image.svg?{}'},\n",
" 'imageManagerActionName': 'listImage'}"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.to_excel('重新分班模板 (4).xlsx',index=False)"
"get(f\"{ip}/uc/project/ueditor\",headers=header).json()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c747c26d",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'success': True,\n",
" 'msg': '操作成功',\n",
" 'code': 0,\n",
" 'data': [{'id': 11365245,\n",
" 'stuName': '郭嘉欣',\n",
" 'serialNo': '0022681452',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776050001000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8864,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': None},\n",
" {'id': 11365248,\n",
" 'stuName': '雷江昊然',\n",
" 'serialNo': '0022681580',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': None,\n",
" 'endTime': None,\n",
" 'intoState': None,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8867,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': None},\n",
" {'id': 11365267,\n",
" 'stuName': '吴梓萌',\n",
" 'serialNo': '0022722732',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036853000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8886,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036842000},\n",
" {'id': 11365241,\n",
" 'stuName': '程柏涵',\n",
" 'serialNo': '0022795772',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036329000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8860,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036336000},\n",
" {'id': 11365249,\n",
" 'stuName': '李然壹',\n",
" 'serialNo': '0022795964',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776035905000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8868,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776035899000},\n",
" {'id': 11365274,\n",
" 'stuName': '杨雨嘉',\n",
" 'serialNo': '0022799916',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036401000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8893,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036382000},\n",
" {'id': 11365238,\n",
" 'stuName': '蔡雨芮',\n",
" 'serialNo': '0022822732',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776035453000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8857,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776035468000},\n",
" {'id': 11365265,\n",
" 'stuName': '魏俊洁',\n",
" 'serialNo': '0022830076',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036331000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8884,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036311000},\n",
" {'id': 11365277,\n",
" 'stuName': '姚祉玲',\n",
" 'serialNo': '0022834044',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036142000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8896,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036135000},\n",
" {'id': 11365260,\n",
" 'stuName': '汪昊涵',\n",
" 'serialNo': '3107628753',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': None,\n",
" 'endTime': None,\n",
" 'intoState': None,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8879,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': None},\n",
" {'id': 11365244,\n",
" 'stuName': '郭佳',\n",
" 'serialNo': '3108354337',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776035462000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8863,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776035455000},\n",
" {'id': 11365270,\n",
" 'stuName': '徐文昊',\n",
" 'serialNo': '3108354417',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036866000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8889,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036861000},\n",
" {'id': 11367018,\n",
" 'stuName': '唐悠雯',\n",
" 'serialNo': '3108388513',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': None,\n",
" 'endTime': None,\n",
" 'intoState': None,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 10981,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': None},\n",
" {'id': 11365259,\n",
" 'stuName': '万梓涵',\n",
" 'serialNo': '3108390097',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': None,\n",
" 'endTime': None,\n",
" 'intoState': None,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8878,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': None},\n",
" {'id': 11365279,\n",
" 'stuName': '朱泓安',\n",
" 'serialNo': '3108390369',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036955000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8898,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036996000},\n",
" {'id': 11365240,\n",
" 'stuName': '陈峻鑫',\n",
" 'serialNo': '3108390481',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036695000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8859,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036686000},\n",
" {'id': 11365242,\n",
" 'stuName': '代晋铭',\n",
" 'serialNo': '3108415505',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776047344000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8861,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776047354000},\n",
" {'id': 11365257,\n",
" 'stuName': '唐裕康',\n",
" 'serialNo': '3108415697',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036869000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8876,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036873000},\n",
" {'id': 11365253,\n",
" 'stuName': '吕仕瑞',\n",
" 'serialNo': '3108435409',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776035766000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8872,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036856000},\n",
" {'id': 11365255,\n",
" 'stuName': '彭雨绮',\n",
" 'serialNo': '3108435585',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036569000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8874,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036555000},\n",
" {'id': 11365256,\n",
" 'stuName': '孙婧琪',\n",
" 'serialNo': '3108441105',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036193000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8875,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036185000},\n",
" {'id': 11365258,\n",
" 'stuName': '涂凤扬',\n",
" 'serialNo': '3108442785',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036470000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8877,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036497000},\n",
" {'id': 11365246,\n",
" 'stuName': '何俊达',\n",
" 'serialNo': '3108460593',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036368000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8865,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036374000},\n",
" {'id': 11365271,\n",
" 'stuName': '徐梓轩',\n",
" 'serialNo': '3108464465',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776035922000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8890,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776035916000},\n",
" {'id': 11365278,\n",
" 'stuName': '张紫涵',\n",
" 'serialNo': '3108580737',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776035797000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8897,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776035794000},\n",
" {'id': 11365252,\n",
" 'stuName': '罗靖洁',\n",
" 'serialNo': '3108583121',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': None,\n",
" 'endTime': None,\n",
" 'intoState': None,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8871,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': None},\n",
" {'id': 11365261,\n",
" 'stuName': '王露静',\n",
" 'serialNo': '3108583313',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036402000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8880,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036386000},\n",
" {'id': 11365247,\n",
" 'stuName': '侯家鸿',\n",
" 'serialNo': '3108588801',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776035778000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8866,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776035778000},\n",
" {'id': 11365262,\n",
" 'stuName': '王洋梓桐',\n",
" 'serialNo': '3108598337',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776059188000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8881,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': None},\n",
" {'id': 11365268,\n",
" 'stuName': '夏紫萱',\n",
" 'serialNo': '3108601489',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036824000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8887,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036812000},\n",
" {'id': 11365250,\n",
" 'stuName': '刘鸿维',\n",
" 'serialNo': '3108601841',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036278000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8869,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036308000},\n",
" {'id': 11365276,\n",
" 'stuName': '姚谊诚',\n",
" 'serialNo': '3108603729',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': None,\n",
" 'endTime': None,\n",
" 'intoState': None,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8895,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776035945000},\n",
" {'id': 11365269,\n",
" 'stuName': '谢汶良',\n",
" 'serialNo': '3108605233',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036656000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8888,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036671000},\n",
" {'id': 11365273,\n",
" 'stuName': '杨佳颖',\n",
" 'serialNo': '3108606065',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036436000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8892,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036424000},\n",
" {'id': 11365239,\n",
" 'stuName': '曹雅莉',\n",
" 'serialNo': '3108606273',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036335000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8858,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036329000},\n",
" {'id': 11365251,\n",
" 'stuName': '刘蔚菘',\n",
" 'serialNo': '3108606433',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036055000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8870,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036089000},\n",
" {'id': 11365275,\n",
" 'stuName': '杨子涵',\n",
" 'serialNo': '3108607729',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': None,\n",
" 'endTime': None,\n",
" 'intoState': None,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8894,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036154000},\n",
" {'id': 11365243,\n",
" 'stuName': '符唐骏',\n",
" 'serialNo': '3108614209',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776035795000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8862,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776035802000},\n",
" {'id': 11365263,\n",
" 'stuName': '位云馨',\n",
" 'serialNo': '3108633697',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': None,\n",
" 'endTime': None,\n",
" 'intoState': None,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8882,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': None},\n",
" {'id': 11365266,\n",
" 'stuName': '吴琳楠',\n",
" 'serialNo': '3108635073',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036323000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8885,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036316000},\n",
" {'id': 11365272,\n",
" 'stuName': '杨丰瑞',\n",
" 'serialNo': '3108650865',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776036330000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8891,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776036322000},\n",
" {'id': 11365254,\n",
" 'stuName': '庞雨橦',\n",
" 'serialNo': '3108679985',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': 1776035795000,\n",
" 'endTime': None,\n",
" 'intoState': 1,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8873,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': 1776035786000},\n",
" {'id': 11365264,\n",
" 'stuName': '魏本杨',\n",
" 'serialNo': '3108682001',\n",
" 'gradeId': 126,\n",
" 'classId': 474,\n",
" 'startTime': None,\n",
" 'endTime': None,\n",
" 'intoState': None,\n",
" 'boarder': 2,\n",
" 'attendDate': 1776009600000,\n",
" 'stuId': 8883,\n",
" 'teamId': 119,\n",
" 'lockTime': None,\n",
" 'gateTime': None,\n",
" 'gateStartTime': None}]}"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"get(\n",
" f\"{ip}/classAttend/into/pre\",\n",
" headers=header,\n",
" params={\n",
" \"teamId\": 119,\n",
" \"dateTime\": 1776009600000,\n",
" \"teaName\": \"马靖\",\n",
" \"serial\": 9,\n",
" \"courseName\": \"26学部1班-班会\",\n",
" },\n",
").json()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3d80ee07",
"metadata": {},
"outputs": [],
"source": [
"attendDate: \"2026-04-13\"\n",
"classRoom: \"2510\"\n",
"color: \"#FB923C\"\n",
"courseName: \"26学部1班-班会\"\n",
"serial: \"第9节\"\n",
"serialnum: \"9\"\n",
"status: \"下节课\"\n",
"teaName: \"马靖\"\n",
"timeSlot: \"16:20-17:00\""
]
}
],
+27
View File
@@ -0,0 +1,27 @@
import pymysql
import snowflake
from faker import Faker
fake = Faker('zh_CN')
import random
# 创建数据库连接
conn = pymysql.connect(
host='11.1.1.5',
user='root',
password='@HXYD1109mysql',
database='school_server',
charset='utf8'
)
# 创建游标对象
cursor = conn.cursor()
def create_table(cursor,result):
data = []
for i in result:
list_list = list(i)
des=cursor.description # 获取表详情,字段名,长度,属性等
t = ",".join([item[0] for item in des])
table_head = t.split(',') # # 查询表列名 用,分割
dict_result = dict(zip(table_head, list_list)) # 打包为元组的列表 再转换为字典
data.append(dict_result) # 将字典添加到list_result中
return data
@@ -0,0 +1,216 @@
from requests import get
import time
import os
import pandas as pd
import tqdm
from datetime import datetime, timedelta
teamId = 19
ip = "http://band.hxzhxy.cn"
param = {
"username": "xtl",
"password": "xia123456",
"client_id": "client",
"grant_type": "password",
"client_secret": "123456",
}
data = get(url=f"{ip}/oauth/token", params=param).json()
token = data["access_token"]
header = {
"content-type": "application/json",
"authorization": f"Bearer {token}",
}
url = f"{ip}/pay/trads/findPayTtadsNews"
output_dir = r"e:\project\python\工具\智慧校园\本部\消费数据\24-26消费信息"
FIELD_MAP = {
"gradeName": "年级名称",
"termName": "交易地点",
"teamId": "团队ID",
"stuId": "学生ID",
"areaName": "设备区域名称",
"bagName": "交易账户",
"userNumb": "学号/工号",
"dealCount": "交易流水号/笔次",
"className": "班级名称",
"remark": "备注/充值类型",
"cardCode": "物理卡号",
"dealType": "消费方式",
"cardValue": "余额",
"userXm": "姓名",
"cardNo": "卡号",
"createDate": "入库时间",
"dealValue": "交易金额",
"recordType": "记录类型",
"id": "记录ID",
"recordId": "终端原始记录ID",
"userId": "用户唯一ID",
"dealTime": "交易时间"
}
OUTPUT_COLUMNS = list(FIELD_MAP.values())
def day_range(start_date, end_date):
current = start_date
while current <= end_date:
yield current
current += timedelta(days=1)
def month_range(start_date, end_date):
current = datetime(start_date.year, start_date.month, 1)
end_month = datetime(end_date.year, end_date.month, 1)
while current <= end_month:
yield current
if current.month == 12:
current = datetime(current.year + 1, 1, 1)
else:
current = datetime(current.year, current.month + 1, 1)
def to_timestamp_ms(dt):
return int(dt.timestamp() * 1000)
def fetch_day_records(day_dt):
day_start = datetime(day_dt.year, day_dt.month, day_dt.day, 0, 0, 0)
day_end = datetime(day_dt.year, day_dt.month, day_dt.day, 23, 59, 59)
begin_time = to_timestamp_ms(day_start)
end_time = to_timestamp_ms(day_end)
page_number = 0
page_size = 100
day_records = []
while True:
params = {
"teamId": teamId,
"pageNumber": page_number,
"pageSize": page_size,
"screen": 1,
"beginTime": begin_time,
"endTime": end_time,
"name": "",
"recordType": 1,
"termName": "",
"type": 1,
"classId": "",
"gradeId": ""
}
resp = get(url=url, params=params, headers=header, timeout=60)
resp.raise_for_status()
result = resp.json()
if not result.get("success"):
raise Exception(f"接口返回失败: {result}")
data = result.get("data") or {}
content = data.get("content") or []
total_pages = data.get("totalPages", 0)
total_elements = data.get("totalElements", 0)
day_records.extend(content)
print(
f"{day_dt.strftime('%Y-%m-%d')}{page_number + 1}/{max(total_pages, 1)} 页,"
f"当前页 {len(content)} 条,当天累计 {len(day_records)} 条,总计 {total_elements}"
)
page_number += 1
if page_number >= total_pages or total_pages == 0:
break
time.sleep(0.1)
return day_records
def parse_date(date_str):
return datetime.strptime(date_str, "%Y-%m-%d")
def convert_records_to_df(records):
rows = []
for record in records:
row = {}
for en_key, cn_key in FIELD_MAP.items():
row[cn_key] = record.get(en_key)
rows.append(row)
if not rows:
return pd.DataFrame(columns=OUTPUT_COLUMNS)
return pd.DataFrame(rows, columns=OUTPUT_COLUMNS)
def get_month_start_end(month_dt, start_date, end_date):
month_start = datetime(month_dt.year, month_dt.month, 1)
if month_dt.month == 12:
next_month = datetime(month_dt.year + 1, 1, 1)
else:
next_month = datetime(month_dt.year, month_dt.month + 1, 1)
month_end = next_month - timedelta(days=1)
if month_start < start_date:
month_start = start_date
if month_end > end_date:
month_end = end_date
return month_start, month_end
def save_month_excel(month_dt, records):
df = convert_records_to_df(records)
file_name = f"{month_dt.strftime('%Y%m')}_学生消费记录.xlsx"
file_path = os.path.join(output_dir, file_name)
df.to_excel(file_path, index=False)
return file_path, len(df)
def main():
print("开始拉取数据...")
start_date_str = os.getenv("START_DATE", "2024-01-01")
end_date_str = os.getenv("END_DATE", "2026-05-19")
start_date = parse_date(start_date_str)
end_date = parse_date(end_date_str)
all_month_list = list(month_range(start_date, end_date))
total_records = 0
success_months = 0
with tqdm.tqdm(all_month_list, desc="按月拉取消费记录") as month_pbar:
for month_dt in month_pbar:
try:
month_start, month_end = get_month_start_end(month_dt, start_date, end_date)
month_records = []
month_days = list(day_range(month_start, month_end))
for day_dt in month_days:
day_records = fetch_day_records(day_dt)
month_records.extend(day_records)
time.sleep(0.2)
file_path, count = save_month_excel(month_dt, month_records)
total_records += count
success_months += 1
month_pbar.set_postfix({
"month": month_dt.strftime("%Y-%m"),
"count": count,
"total": total_records
})
print(f"已输出: {file_path}")
except Exception as e:
print(f"{month_dt.strftime('%Y-%m')} 拉取失败: {e}")
print("\n完成")
print(f"成功月份: {success_months}")
print(f"总记录数: {total_records}")
print(f"输出目录: {output_dir}")
if __name__ == "__main__":
main()
@@ -0,0 +1,89 @@
import pandas as pd
import json
from datetime import datetime
# 读取Excel文件
file_path = r'e:\project\python\工具\智慧校园\本部\消费数据\2024学生.xlsx'
df = pd.read_excel(file_path)
print("=" * 80)
print("学生消费数据提取")
print("=" * 80)
# 1. 提取年级ID和班级ID(供用户查表)
grade_ids = sorted(df['gradeId'].unique().tolist())
class_ids = sorted(df['classId'].unique().tolist())
print(f"\n【年级ID列表】(共{len(grade_ids)}个):")
print(grade_ids)
print(f"\n【班级ID列表】(共{len(class_ids)}个):")
print(class_ids)
# 2. 提取学生消费信息
student_records = []
for _, row in df.iterrows():
record = {
'学号': str(row['stuNo']),
'姓名': row['stuName'],
'年级ID': row['gradeId'],
'班级ID': row['classId'],
'支付金额(元)': row['totalFee'] / 100, # 转换为元
'支付状态': '支付成功' if row['payState'] == 1 else '其他',
'创建时间': row['createTime'].strftime('%Y-%m-%d %H:%M:%S') if pd.notna(row['createTime']) else '',
'支付时间': row['payTime'].strftime('%Y-%m-%d %H:%M:%S') if pd.notna(row['payTime']) else '',
'物理卡号': str(row['serialNo']) if pd.notna(row['serialNo']) else '',
'teamId': row['teamId']
}
student_records.append(record)
# 3. 统计信息
print(f"\n【数据统计】")
print(f"总记录数: {len(student_records)}")
print(f"唯一学生数: {df['stuNo'].nunique()}")
print(f"总金额: {df['totalFee'].sum() / 100:.2f}")
# 4. 按年级统计
print(f"\n【按年级统计】")
grade_stats = df.groupby('gradeId').agg({
'stuNo': 'nunique',
'totalFee': 'sum'
}).reset_index()
grade_stats.columns = ['年级ID', '学生人数', '总金额(分)']
grade_stats['总金额(元)'] = grade_stats['总金额(分)'] / 100
print(grade_stats.to_string(index=False))
# 5. 按班级统计
print(f"\n【按班级统计】")
class_stats = df.groupby('classId').agg({
'stuNo': 'nunique',
'totalFee': 'sum'
}).reset_index()
class_stats.columns = ['班级ID', '学生人数', '总金额(分)']
class_stats['总金额(元)'] = class_stats['总金额(分)'] / 100
print(class_stats.to_string(index=False))
# 6. 保存详细记录到JSON
output_file = r'e:\project\python\工具\智慧校园\本部\消费数据\student_records.json'
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(student_records, f, ensure_ascii=False, indent=2)
print(f"\n【输出文件】")
print(f"详细记录已保存到: {output_file}")
# 7. 保存ID映射表(等待用户补充年级和班级名称)
id_mapping = {
'grade_ids': grade_ids,
'class_ids': class_ids,
'note': '请查询数据库补充年级名称和班级名称'
}
id_mapping_file = r'e:\project\python\工具\智慧校园\本部\消费数据\id_mapping.json'
with open(id_mapping_file, 'w', encoding='utf-8') as f:
json.dump(id_mapping, f, ensure_ascii=False, indent=2)
print(f"ID映射表已保存到: {id_mapping_file}")
print("\n请查询数据库,告诉我以下ID对应的名称:")
print(f"年级ID: {grade_ids}")
print(f"班级ID: {class_ids}")
@@ -0,0 +1,25 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "72fd36ef",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.12.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,38 @@
import pandas as pd
import json
# 读取Excel文件
df = pd.read_excel('e:/project/python/工具/智慧校园/本部/消费数据/2024学生.xlsx')
print("=== Excel文件基本信息 ===")
print(f"数据形状: {df.shape}")
print(f"\n列名: {df.columns.tolist()}")
print("\n=== 前10行数据 ===")
print(df.head(10))
print("\n=== 数据类型 ===")
print(df.dtypes)
# 提取唯一值
print("\n=== 唯一值统计 ===")
for col in df.columns:
unique_count = df[col].nunique()
print(f"{col}: {unique_count} 个唯一值")
if unique_count <= 20:
print(f" 值: {df[col].unique().tolist()}")
# 检查是否有年级和班级相关字段
grade_class_cols = [col for col in df.columns if any(keyword in col.lower() for keyword in ['年级', '班级', 'grade', 'class'])]
print(f"\n=== 年级/班级相关字段: {grade_class_cols} ===")
# 保存列名信息供后续使用
with open('e:/project/python/工具/智慧校园/本部/消费数据/excel_info.json', 'w', encoding='utf-8') as f:
info = {
'columns': df.columns.tolist(),
'shape': df.shape,
'sample_data': df.head(5).to_dict('records')
}
json.dump(info, f, ensure_ascii=False, indent=2)
print("\n=== 信息已保存到 excel_info.json ===")
@@ -0,0 +1,24 @@
import pandas as pd
import sys
# 读取Excel文件
file_path = r'e:\project\python\工具\智慧校园\本部\消费数据\2024学生.xlsx'
df = pd.read_excel(file_path)
print("数据形状:", df.shape)
print("\n列名:")
for i, col in enumerate(df.columns):
print(f"{i+1}. {col}")
print("\n前5行数据:")
print(df.head().to_string())
# 检查年级和班级相关字段
print("\n查找年级/班级相关字段...")
for col in df.columns:
if any(keyword in str(col) for keyword in ['年级', '班级', 'grade', 'class', 'Grade', 'Class']):
print(f"找到字段: {col}")
print(f"唯一值: {df[col].unique()[:10]}") # 只显示前10个唯一值
print("\n数据类型:")
print(df.dtypes)
@@ -0,0 +1,17 @@
import pandas as pd
# 读取年级表和班级表
grade_df = pd.read_excel(r'e:\project\python\工具\智慧校园\本部\消费数据\年级表.xlsx')
class_df = pd.read_excel(r'e:\project\python\工具\智慧校园\本部\消费数据\班级表.xlsx')
print("=== 年级表 ===")
print(f"形状: {grade_df.shape}")
print(f"列名: {grade_df.columns.tolist()}")
print("\n前10行:")
print(grade_df.head(10))
print("\n=== 班级表 ===")
print(f"形状: {class_df.shape}")
print(f"列名: {class_df.columns.tolist()}")
print("\n前10行:")
print(class_df.head(10))
@@ -0,0 +1,140 @@
import pandas as pd
from datetime import datetime
# 读取所有数据
print("正在读取数据...")
consumption_df = pd.read_excel(r'e:\project\python\工具\智慧校园\本部\消费数据\2024学生.xlsx')
grade_df = pd.read_excel(r'e:\project\python\工具\智慧校园\本部\消费数据\年级表.xlsx')
class_df = pd.read_excel(r'e:\project\python\工具\智慧校园\本部\消费数据\班级表.xlsx')
print(f"消费数据: {consumption_df.shape[0]} 条记录")
print(f"年级表: {grade_df.shape[0]} 个年级")
print(f"班级表: {class_df.shape[0]} 个班级")
# 创建年级ID到名称的映射
grade_map = dict(zip(grade_df['id'], grade_df['grade_name']))
# 创建班级ID到名称的映射
class_map = dict(zip(class_df['id'], class_df['class_name']))
# 创建班级ID到年级ID的映射(用于验证)
class_to_grade_map = dict(zip(class_df['id'], class_df['grade_id']))
print("\n正在处理消费数据...")
# 处理消费数据
processed_data = []
for _, row in consumption_df.iterrows():
grade_id = row['gradeId']
class_id = row['classId']
# 获取年级和班级名称
grade_name = grade_map.get(grade_id, f'未知年级({grade_id})')
class_name = class_map.get(class_id, f'未知班级({class_id})')
# 处理时间格式
create_time = row['createTime']
pay_time = row['payTime']
if pd.notna(create_time):
if isinstance(create_time, str):
create_time_str = create_time
else:
create_time_str = create_time.strftime('%Y-%m-%d %H:%M:%S')
else:
create_time_str = ''
if pd.notna(pay_time):
if isinstance(pay_time, str):
pay_time_str = pay_time
else:
pay_time_str = pay_time.strftime('%Y-%m-%d %H:%M:%S')
else:
pay_time_str = ''
# 处理支付状态
pay_state_map = {0: '确认中', 1: '支付成功', 2: '已取消', 3: '退款'}
pay_state = pay_state_map.get(row['payState'], f'未知状态({row["payState"]})')
# 处理充值状态
change_state_map = {0: '充值中', 1: '已取消', 2: '充值成功', 3: '充值失败'}
change_state = change_state_map.get(row['changeState'], f'未知状态({row["changeState"]})')
record = {
'学号': str(row['stuNo']),
'姓名': row['stuName'],
'年级ID': grade_id,
'年级名称': grade_name,
'班级ID': class_id,
'班级名称': class_name,
'支付金额(元)': row['totalFee'] / 100,
'支付状态': pay_state,
'充值状态': change_state,
'创建时间': create_time_str,
'支付时间': pay_time_str,
'物理卡号': str(int(row['serialNo'])) if pd.notna(row['serialNo']) else '',
'订单编号': row['outTradeNo'],
'微信订单号': row['transactionId'] if pd.notna(row['transactionId']) else '',
'支付手机号': str(row['wxPhone']),
'teamId': row['teamId']
}
processed_data.append(record)
# 创建DataFrame
result_df = pd.DataFrame(processed_data)
# 生成输出文件名
output_file = r'e:\project\python\工具\智慧校园\本部\消费数据\学生消费记录整理.xlsx'
# 写入Excel,使用多个sheet
with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
# Sheet 1: 详细记录
result_df.to_excel(writer, sheet_name='详细记录', index=False)
# Sheet 2: 按年级汇总
grade_summary = result_df.groupby(['年级ID', '年级名称']).agg({
'学号': 'nunique',
'支付金额(元)': 'sum',
'姓名': 'count'
}).reset_index()
grade_summary.columns = ['年级ID', '年级名称', '学生人数', '总金额(元)', '消费笔数']
grade_summary = grade_summary.sort_values('年级ID')
grade_summary.to_excel(writer, sheet_name='按年级汇总', index=False)
# Sheet 3: 按班级汇总
class_summary = result_df.groupby(['班级ID', '班级名称', '年级名称']).agg({
'学号': 'nunique',
'支付金额(元)': 'sum',
'姓名': 'count'
}).reset_index()
class_summary.columns = ['班级ID', '班级名称', '年级名称', '学生人数', '总金额(元)', '消费笔数']
class_summary = class_summary.sort_values(['年级名称', '班级ID'])
class_summary.to_excel(writer, sheet_name='按班级汇总', index=False)
# Sheet 4: 按学生汇总
student_summary = result_df.groupby(['学号', '姓名', '年级名称', '班级名称']).agg({
'支付金额(元)': 'sum',
'创建时间': 'count'
}).reset_index()
student_summary.columns = ['学号', '姓名', '年级名称', '班级名称', '总金额(元)', '消费笔数']
student_summary = student_summary.sort_values(['年级名称', '班级名称', '学号'])
student_summary.to_excel(writer, sheet_name='按学生汇总', index=False)
print(f"\n✅ 数据整理完成!")
print(f"📁 输出文件: {output_file}")
print(f"\n📊 统计信息:")
print(f" - 总记录数: {len(result_df)}")
print(f" - 唯一学生数: {result_df['学号'].nunique()}")
print(f" - 总金额: {result_df['支付金额(元)'].sum():.2f}")
print(f"\n📋 Excel包含以下工作表:")
print(f" 1. 详细记录 - 所有消费明细")
print(f" 2. 按年级汇总 - 各年级消费统计")
print(f" 3. 按班级汇总 - 各班级消费统计")
print(f" 4. 按学生汇总 - 各学生消费统计")
# 显示年级分布
print(f"\n🏫 年级分布:")
grade_dist = result_df.groupby('年级名称')['学号'].nunique().sort_values(ascending=False)
for grade, count in grade_dist.items():
print(f" {grade}: {count}")
@@ -0,0 +1,309 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "318e7588",
"metadata": {},
"outputs": [],
"source": [
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3c046d8d",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}'"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "27c18f0a",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 2,
"id": "343a9e44",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[]\n"
]
}
],
"source": [
"grade_id = [110,120,124, 126,127,128, 114,119,129]\n",
"sql = f'''\n",
"select \n",
" mm.id,\n",
" mm.stu_no,\n",
" mm.stu_name,\n",
" bb.student_id,\n",
" mm.plan_id -- 这里直接显示 plan_id\n",
"from (\n",
" select \n",
" s.id,\n",
" s.stu_no,\n",
" s.stu_name,\n",
" a.plan_id -- 子查询把 plan_id 带出来\n",
" from student s \n",
" inner join class_attend_stu a on s.id = a.student_id\n",
" where s.grade_id in ({\",\".join(map(str,grade_id))}) \n",
" and a.plan_id=41\n",
" group by s.id, s.stu_no, s.stu_name, a.plan_id\n",
") mm \n",
"left join (\n",
" select DISTINCT c.student_id \n",
" from class_attend c \n",
" where c.attend_date BETWEEN '2026-05-25' and '2026-05-31' \n",
" and c.student_id in (\n",
" select DISTINCT a.student_id \n",
" from class_attend_stu a \n",
" where a.plan_id=41\n",
" )\n",
") bb on mm.id = bb.student_id \n",
"WHERE bb.student_id is null\n",
"'''\n",
"cursor.execute(sql)\n",
"result = cursor.fetchall()\n",
"data = create_table(cursor,result)\n",
"print(data)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "2584e86a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n",
"{\"success\":true,\"msg\":\"操作成功\",\"code\":0,\"data\":null}\n"
]
}
],
"source": [
"for item in data:\n",
" res = post(f\"{ip}/classAttendStu/createThisWeekStu\",headers=header,params={\"stuId\":item[\"id\"],\"planId\":item[\"plan_id\"]},timeout=600).text\n",
" print(res)\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}