Gofor5's picture
Update app.py
84336be verified
raw
history blame
15.5 kB
import json
import os
from pathlib import Path
import re
import threading
import time
from tkinter import filedialog
import traceback
import gradio as gr
import requests
from tqdm import tqdm
import tempfile
lock = threading.Lock()
event = threading.Event()
requests.packages.urllib3.disable_warnings()
reference_subject = {
'语文': '01',
'历史': '12',
'数学': '02',
'生物': '13',
'英语': '03',
'通用技术': '102',
'信息技术': '26',
'物理': '05',
'政治': '27',
'化学': '06',
'地理':"14"
}
subject_codes={
'01': '语文',
'12': '历史',
'02': '数学',
'13': '生物',
'03': '英语',
'102': '通用技术',
'26': '信息技术',
'05': '物理',
'27': '政治',
'06': '化学',
'14':'地理'
}
headers = [
{
"Accept": "application/json, text/plain, */*",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"Host": "www.zhixue.com",
"Referer": "https://www.zhixue.com/middlehomework/web-student/views/",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
"appName": "com.iflytek.zxzy.web.zx.stu",
"sec-ch-ua": '"Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"'
},
{
"Host": "www.zhixue.com",
"sucOriginAppKey": "zhixue_student",
"User-Agent": "zhixue_student/1.0.2026 (iPhone; iOS 16.2; Scale/3.00)",
"appName": "com.zhixue.student",
"Connection": "keep-alive",
"Accept-Language": "zh-Hans-CN;q=1, zh-Hant-CN;q=0.9, en-CN;q=0.8",
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br"
},
{
"Host": "mhw.zhixue.com",
"Content-Type": "application/json",
"Accept": "application/json, text/plain, */*",
"appName": "com.zhixue.student",
"sucOriginAppKey": "zhixue_student",
"Accept-Language": "zh-CN,zh-Hans;q=0.9",
"Origin": "https://mhw.zhixue.com",
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko)",
"Referer": "https://mhw.zhixue.com/zhixuestudent/views/homeworkReport/homework-report.html",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive"
}
]
def get_token():
global token
response = requests.get("https://www.zhixue.com/middleweb/newToken", headers=headers[0], verify=False)
response.encoding = "utf-8"
response = response.json()
result = response["result"]["token"]
if result:
token = result
return True
else:
print("获取 token 失败。")
return False
def format_time(timestamp):
return time.strftime("%Y-%m-%d %H:%M", time.localtime(timestamp // 1000))
def get(url):
headers[1].update({"Host": url.split("/")[2], "sucUserToken": token})
response = requests.get(url, headers=headers[1], verify=False)
response.encoding = "utf-8"
return response.json()
def post(url, data):
headers[2].update({
"Host": url.split("/")[2],
"Origin": f'https://{url.split("/")[2]}',
"sucUserToken": token,
"Authorization": token
})
response = requests.post(url, headers=headers[2], json=data, verify=False)
response.encoding = "utf-8"
return response.json()
def parse_range(s, max_value):
result = []
for item in s.split():
if "-" in item:
l = item.split("-")
if len(l) == 2 and l[0].isdigit() and l[1].isdigit():
begin = int(l[0]) - 1
end = int(l[1]) - 1
if not (begin < 0 and end < 0 or begin >= max_value and end >= max_value):
step = -1 if begin > end else 1
for i in range(begin, end + step, step):
if 0 <= i < max_value and not i in result:
result.append(i)
elif item.isdigit():
n = int(item) - 1
if 0 <= n < max_value and not n in result:
result.append(n)
return result
def to_file(file, source_type, name=""):
result = ({"name": name or Path(file).name, "path": file, "is_text": bool(name)} if isinstance(file, str) else
{"name": name, "path": file["description"], "is_text": True} if file["fileType"] == 5 else
{"name": file.get("name", "") or Path(file["path"]).name, "path": file["path"], "is_text": False})
result["name"] = re.sub('[\\\\/:*?"<>|]', "_", result["name"])
result["type"] = source_type
return result
# 修改点1:添加uid参数
def analyze_homework(homework, include_text, uid):
hwId = homework["hwId"]
hwType = homework["hwType"]
stuHwId = homework["stuHwId"]
file_list = []
data = {"base": {"appId": "APP"}, "params": {"hwId": hwId, "stuHwId": stuHwId, "studentId": uid}} # 使用传入的uid值
if hwType == 102:
response = post("https://mhw.zhixue.com/hwreport/question/getStuReportDetail", data)
if "result" in response:
result = response["result"]
file_list.append(to_file(result["hwDescription"], "题目", result["hwTitle"] + "_说明.txt"))
for problem in result["mainTopics"]:
content = problem["content"] + problem["answerHtml"] + problem["analysisHtml"]
file_list += [to_file(path, "题目") for path in re.findall('bigger="(.+?)"', content)]
file_list += [to_file(path, "提交") for item in problem["subTopics"] for path in item["answerResList"]]
elif hwType == 105:
response = post("https://mhw.zhixue.com/hw/homework/attachment/list", data)
file_list += [to_file(item, "题目") for item in response["result"]]
response = post("https://mhw.zhixue.com/hwreport/question/getStuReportDetail", data)
if "result" in response:
result = response["result"]
file_list.append(to_file(result["hwDescription"], "题目", result["hwTitle"] + "_说明.txt"))
file_list += [to_file(item, "答案") for item in result.get("answerAttachList", [])]
for problem in result["mainTopics"]:
file_list += [to_file(path, "提交") for item in problem["subTopics"] for path in item["answerResList"]]
elif hwType == 107:
response = post("https://mhw.zhixue.com/hw/clock/answer/getClockHomeworkDetail", data)
result = response["result"]
file_list.append(to_file(result["description"], "题目", result["title"] + "_说明.txt"))
file_list += ([to_file(item, "题目") for item in result.get("hwTopicAttachments", [])]
+ [to_file(item, "答案") for item in result.get("hwAnswerAttachments", [])]
+ [to_file(item, "答案") for item in
result["hwClockRecordPreviewResponses"][0].get("teacherAnswerAttachments", [])]
+ [to_file(item, "提交", result["title"] + "_提交.txt") for item in
result["hwClockRecordPreviewResponses"][0].get("answerAttachments", [])])
file_list = [file for file in file_list if file["path"] and (include_text or not file["is_text"])]
return file_list
def query_homework(uid, tlsysSessionId, subject, status, max_count):
headers[0].update({"Cookie": f"tlsysSessionId={tlsysSessionId}"})
successful = get_token()
if not successful:
return "获取 token 失败",""
page_size = max_count
if subject == ["语文", "数学", "英语", "物理", "化学", "生物", "地理", "历史", "政治",'通用技术', '信息技术']:
subjects = ["-1"]
else:
subjects = [reference_subject[i] for i in subject]
if status == "全部":
status = ""
elif status == "已完成":
status = "1"
else:
status = "0"
fetch_list = []
if status != "1":
fetch_list += [{"subject": subject, "status": 0} for subject in subjects]
if status != "0":
fetch_list += [{"subject": subject, "status": 1} for subject in subjects]
global homework_list
homework_list = []
timestamps = [int(time.time() * 1000)] * len(fetch_list)
finished = [False] * len(fetch_list)
while not all(finished):
print("\x9B1F\x9B0J", end="")
index = len(homework_list)
for i in tqdm(range(len(fetch_list)), unit=""):
if finished[i]:
continue
response = get("https://mhw.zhixue.com/homework_middle_service/stuapp/getStudentHomeWorkList"
f'?completeStatus={fetch_list[i]["status"]}&createTime={timestamps[i]}&pageIndex=2'
f'&pageSize={page_size}&subjectCode={fetch_list[i]["subject"]}&token={token}')
if response["code"] != 200:
raise RuntimeError("获取作业列表失败")
result_list = response["result"]["list"]
homework_list += result_list
if len(result_list) < page_size:
finished[i] = True
if result_list:
timestamps[i] = result_list[-1]["beginTime"]
print("\x9B1F\x9B0J", end="")
homework_list_temp=[]
global homework_list_oringin
homework_list_oringin = homework_list
for i in range(index, len(homework_list)):
begin_time = format_time(homework_list[i]["beginTime"])
end_time = format_time(homework_list[i]["endTime"])
homework_list_temp.append(f"[{homework_list[i]['subjectName']}]|{homework_list[i]['hwTitle']}|{begin_time}-{end_time}")
homework_list = homework_list_temp
return token, gr.update(choices=homework_list, value=[])
# 修改点2:添加uid参数
def parse_homework(token, include_text, homework_selection, uid):
result = []
for i in homework_selection:
for j in range(len(homework_list)):
if i == homework_list[j]:
result.append(j)
selected_homework = result
file_list = []
for i in tqdm(selected_homework, unit=""):
# 修改点3:传递uid参数
file_list += analyze_homework(homework_list_oringin[i], include_text, uid)
global file_list_output
file_list_output = [file["name"] for file in file_list]
global homework_downloaded_path
homework_downloaded_path = [file["path"] for file in file_list]
global homework_is_text
homework_is_text = [file["is_text"] for file in file_list]
return gr.update(choices=file_list_output, value=[])
def download_file(token, homework_view):
download_list = []
for i in homework_view:
for j in range(len(file_list_output)):
if i == file_list_output[j]:
if not homework_is_text[j]:
download_list.append(homework_downloaded_path[j])
else:
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".txt") as f:
f.write(homework_downloaded_path[j])
temp_path = f.name
download_list.append(temp_path)
return download_list
with gr.Blocks(title="智学网作业获取器") as demo:
gr.Markdown("# 🚀 智学网作业获取器")
gr.Markdown("## Backfront Created by Levrium,UI Design by Start_ten")
gr.Markdown("操作说明请见https://zhuanlan.zhihu.com/p/691808543")
with gr.Row():
with gr.Column():
gr.Markdown("### 📝 查询作业")
uid = gr.Textbox(
label="uid",
placeholder="请输入uid...",
)
tlsysSessionId = gr.Textbox(
label="tlsysSessionId",
placeholder="请输入tlsysSessionId...",
)
with gr.Row():
subject = gr.CheckboxGroup(
choices=["语文", "数学", "英语", "物理", "化学", "生物", "地理", "历史", "政治",'通用技术', '信息技术'],
label="具体学科",
value=["语文", "数学", "英语", "物理", "化学", "生物", "地理", "历史", "政治",'通用技术', '信息技术']
)
with gr.Column():
all_chosen = gr.Button(
value="全选",
variant="secondary"
)
all_chosen.click(
fn=lambda: ["语文", "数学", "英语", "物理", "化学", "生物", "地理", "历史", "政治",'通用技术', '信息技术'],
inputs=[],
outputs=[subject]
)
all_clear = gr.Button(
value="全不选",
variant="secondary"
)
all_clear.click(
fn=lambda: [],
inputs=[],
outputs=[subject]
)
status = gr.Radio(
choices=["全部", "已完成", "未完成"],
label="作业状态",
value="全部"
)
max_count = gr.Slider(
label="最大请求作业数",
value=10,
minimum=1,
maximum=50,
step=1
)
with gr.Column():
token = gr.Textbox(
label="TOKEN",
interactive=False
)
homework_selection = gr.CheckboxGroup(
label="作业列表(可多选)",
choices=[],
interactive=True
)
submit_btn = gr.Button("查询作业", variant="primary")
submit_btn.click(
fn=query_homework,
inputs=[uid, tlsysSessionId, subject, status, max_count],
outputs=[token, homework_selection ]
)
gr.Markdown("---")
with gr.Row():
with gr.Column():
gr.Markdown("### 📄 解析作业并下载")
text_parse = gr.Checkbox(
label="是否解析题目、提交的文本?",
value=False
)
homework_view = gr.CheckboxGroup(
label="作业内容",
choices=[],
interactive=True
)
submit_btn = gr.Button("解析作业", variant="primary")
# 修改点4:添加uid输入
submit_btn.click(
fn=parse_homework,
inputs=[token, text_parse, homework_selection, uid], # 添加uid输入
outputs=[homework_view, ]
)
with gr.Column():
file_output = gr.File(label="作业文件", interactive=False)
download_btn = gr.Button("下载作业", variant="primary")
download_btn.click(
fn=download_file,
inputs=[token, homework_view],
outputs=[file_output]
)
if __name__ == "__main__":
demo.launch()