处理一个报告:用了线程,因为实验报告每部分字比较多,所以 按报告结构分成4个部分提交的,从结果看,一个学生7份报告费时10分钟~~~
import requests
import json
import traceback
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
import threading
# 百度文心一言 API 配置(请替换为实际可用的密钥)
API_KEY = "yo76sSr****g9Tsdz6y" # 请确认这是有效的API Key
SECRET_KEY = "UawrTm*****6jA6X2AFgXbA" # 请确认这是有效的Secret Key
API_URL = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token="
# 全局变量用于Token管理
token_lock = threading.Lock()
current_token = None
token_expiry_time = 0
TOKEN_REFRESH_THRESHOLD = 300 # 提前5分钟刷新token
MAX_RETRIES = 3 # 最大重试次数
PARALLEL_REPORTS = 3 # 并行处理的报告数量
class TokenManager:
"""Token管理器,负责获取和刷新访问令牌"""
@staticmethod
def get_access_token():
"""获取百度文心一言 API 的访问令牌"""
global current_token, token_expiry_time
start_time = time.time()
url = f"https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={API_KEY}&client_secret={SECRET_KEY}"
print(f"正在获取access_token,请求URL: {url}")
try:
response = requests.get(url)
print(f"响应状态码: {response.status_code}")
print(f"响应内容: {response.text}")
response.raise_for_status()
data = response.json()
print(f"解析后的token数据: {data}")
# 计算Token过期时间(假设30天后过期,实际应根据返回的expires_in字段)
expires_in = data.get("expires_in", 2592000) # 默认30天
token_expiry_time = start_time + expires_in - TOKEN_REFRESH_THRESHOLD
current_token = data.get("access_token")
# 计算并输出耗时
elapsed_time = time.time() - start_time
print(f"获取access_token耗时: {elapsed_time:.2f}秒\n")
return current_token
except Exception as e:
elapsed_time = time.time() - start_time
print(f"获取访问令牌失败(耗时: {elapsed_time:.2f}秒): {e}")
traceback.print_exc()
return None
@staticmethod
def get_valid_token():
"""获取有效的访问令牌,如果即将过期则自动刷新"""
global current_token, token_expiry_time
with token_lock:
# 如果当前没有token或者token即将过期,则获取新token
if not current_token or time.time() >= token_expiry_time:
return TokenManager.get_access_token()
return current_token
def call_wenxin_api_with_retry(access_token, content, action_name, max_retries=MAX_RETRIES):
"""
调用百度文心一言API,带有重试机制
参数:
access_token: API访问令牌
content: 请求内容
action_name: 操作名称(用于日志)
max_retries: 最大重试次数
"""
start_time = time.time()
last_error = None
for attempt in range(1, max_retries + 1):
attempt_start = time.time()
if not access_token:
print("访问令牌无效,无法调用API")
return None
url = API_URL + access_token
headers = {
"Content-Type": "application/json"
}
payload = {
"messages": [
{"role": "user", "content": content}
]
}
print(f"\n=== {action_name} API调用调试信息 (尝试 {attempt}/{max_retries}) ===")
print(f"请求URL: {url}")
print(f"请求头: {headers}")
print(f"请求体: {json.dumps(payload, indent=2)}")
try:
response = requests.post(url, headers=headers, data=json.dumps(payload), timeout=60)
print(f"响应状态码: {response.status_code}")
print(f"响应内容: {response.text}")
response.raise_for_status()
result = response.json()
print(f"解析后的响应: {result}")
# 计算耗时
elapsed_time = time.time() - start_time
attempt_elapsed = time.time() - attempt_start
print(f"{action_name} API调用成功 (总耗时: {elapsed_time:.2f}秒, 本次尝试: {attempt_elapsed:.2f}秒)")
if isinstance(result, dict) and "result" in result:
return result["result"]
else:
print("警告: 响应中未找到'result'字段")
return None
except requests.exceptions.RequestException as e:
attempt_elapsed = time.time() - attempt_start
print(f"{action_name} API调用失败 (本次尝试耗时: {attempt_elapsed:.2f}秒): {e}")
last_error = e
# 如果是认证错误,尝试刷新token
if hasattr(e, 'response') and e.response is not None and e.response.status_code == 401:
print("检测到认证错误,尝试刷新access_token...")
with token_lock:
access_token = TokenManager.get_access_token()
continue
# 如果是最后一次尝试,不再重试
if attempt == max_retries:
break
# 指数退避等待
wait_time = min(2 ** attempt, 10) # 最大等待10秒
print(f"等待 {wait_time} 秒后重试...")
time.sleep(wait_time)
elapsed_time = time.time() - start_time
print(f"{action_name} API调用最终失败 (总耗时: {elapsed_time:.2f}秒): {last_error}")
return None
def process_report(report, report_index):
"""
处理单个实验报告
参数:
report - 实验报告字典对象
report_index - 报告索引(用于日志)
"""
# 记录单份报告处理开始时间
report_start_time = time.time()
print(f"\n===== 开始处理第 {report_index} 份报告 =====")
# 获取有效token
access_token = TokenManager.get_valid_token()
if not access_token:
print("访问令牌无效,无法处理报告")
return report, 0
# 获取报告前4个条目的键(排除最后一个评阅意见条目)
report_items = list(report.keys())[:4]
feedbacks = []
# 遍历处理前4个条目
for item in report_items:
item_start_time = time.time()
print(f"正在处理报告的:{item}")
# 构建提示词
prompt = f"请评价以下实验报告中的'{item}'部分,并给出专业的改进建议,供后续综合评分使用:{report[item]}"
# 调用API,传入操作名称
feedback = call_wenxin_api_with_retry(access_token, prompt, f"处理{item}")
if feedback:
feedbacks.append(f"【{item}评价】{feedback}")
print("处理完成")
else:
print("处理失败")
# 计算条目处理耗时
item_elapsed = time.time() - item_start_time
print(f"{item}处理总耗时: {item_elapsed:.2f}秒")
print("-" * 80)
# 生成指导教师评阅意见和评分
final_feedback = None
if feedbacks:
final_start_time = time.time()
print("正在生成指导教师评阅意见和评分...")
prompt = f"基于以下对实验报告各部分的评价,请综合给出指导教师评阅意见和评分(满分100分):\n{chr(10).join(feedbacks)}"
final_feedback = call_wenxin_api_with_retry(access_token, prompt, "生成评阅意见")
final_elapsed = time.time() - final_start_time
print(f"评阅意见生成总耗时: {final_elapsed:.2f}秒")
if final_feedback:
report["指导教师评阅意见和评分"] = final_feedback
print("评阅意见生成完成")
else:
print("评阅意见生成失败")
else:
print("没有足够的评价信息,无法生成评阅意见")
# 计算单份报告总耗时
report_elapsed = time.time() - report_start_time
print(f"\n===== 第 {report_index} 份报告处理完成,耗时: {report_elapsed:.2f}秒 =====")
return report, report_elapsed
def process_all_reports(reports):
"""
并行处理所有实验报告
参数: reports - 实验报告列表
"""
# 记录总开始时间
total_start_time = time.time()
total_reports = len(reports)
processed_reports = []
report_times = []
if total_reports == 0:
print("没有需要处理的报告")
return [], 0
# 获取初始访问令牌
TokenManager.get_valid_token()
# 使用线程池并行处理报告
with ThreadPoolExecutor(max_workers=PARALLEL_REPORTS) as executor:
futures = []
for i, report in enumerate(reports, 1):
futures.append(executor.submit(process_report, report, i))
# 等待所有任务完成并收集结果
for future in as_completed(futures):
try:
processed_report, report_time = future.result()
processed_reports.append(processed_report)
report_times.append(report_time)
except Exception as e:
print(f"处理报告时发生错误: {e}")
traceback.print_exc()
# 计算总耗时
total_elapsed = time.time() - total_start_time
print(f"\n===== 所有报告处理完成!共处理 {total_reports} 份报告 =====")
if report_times:
print(f"单份报告平均处理时间: {sum(report_times) / len(report_times):.2f}秒")
print(f"批量处理总耗时: {total_elapsed:.2f}秒")
return processed_reports, total_elapsed
def main():
# 记录主程序开始时间
main_start_time = time.time()
# 示例:创建包含多个实验报告的集合
reports = [
{
"实验目的及要求": "使学生在环境下学会创建角色、为角色授权、将角色授予用户和其他角色、回收角色权限以及删除角色,深入理解角色在数据库权限管理中的作用和优势",
"实验使用的主要设备及要求": "安装有Gaussdb(for mysql)数据库的计算机,并已安装Navicat数据库管理工具;学生已掌握基本的Gaussdb(for mysql)语句,熟悉实验5的操作内容。",
"实验操作内容及步骤": "创建角色:打开Navicat连接到Gaussdb(for mysql)数据库;在查询窗口中,使用`CREATE ROLE`语句",
"实验结果与分析总结": "通过本次实验我学会了在环境下学会创建角色、为角色授权、将角色授予用户和其他角色、回收角色权限以及删除角色,深入理解角色在数据库权限管理中的作用和优势。",
"指导教师评阅意见和评分": ""
},
{
"实验目的及要求": "掌握数据库用户管理基本操作,包括创建用户、修改用户权限、删除用户等,理解用户权限控制在数据库安全中的重要性",
"实验使用的主要设备及要求": "安装有Gaussdb(for mysql)数据库的计算机,Navicat数据库管理工具;学生需掌握SQL基本语法,了解数据库安全基础知识。",
"实验操作内容及步骤": "创建用户:使用CREATE USER语句创建新用户;授权操作:使用GRANT语句为用户分配权限;查看权限:使用SHOW GRANTS语句验证权限分配结果",
"实验结果与分析总结": "通过实验成功完成了用户创建与权限分配操作,验证了不同权限对数据库操作的影响,理解了最小权限原则在数据库安全管理中的应用。",
"指导教师评阅意见和评分": ""
},
{
"实验目的及要求": "学习数据库索引的创建和使用,理解索引对查询性能的影响",
"实验使用的主要设备及要求": "安装有Gaussdb(for mysql)数据库的计算机,Navicat数据库管理工具;学生需掌握SQL基本语法,了解基本的数据库性能概念。",
"实验操作内容及步骤": "创建索引:使用CREATE INDEX语句创建不同类型索引;性能测试:对比使用索引和不使用索引的查询性能",
"实验结果与分析总结": "通过实验理解了索引的工作原理,掌握了索引创建方法,并验证了索引对查询性能的显著提升。",
"指导教师评阅意见和评分": ""
}
]
# 调用批量处理方法
processed_reports, total_time = process_all_reports(reports)
# 打印所有处理后的报告
print("\n===== 所有处理完成的实验报告 =====")
for i, report in enumerate(processed_reports, 1):
print(f"\n----- 第 {i} 份报告 -----")
for key, value in report.items():
print(f"{key}:{value}")
# 打印总耗时
print(f"\n程序运行总耗时: {time.time() - main_start_time:.2f}秒")
print(f"批量处理核心耗时: {total_time:.2f}秒")
if __name__ == "__main__":
main()
我们通过reports = [] # 存储所有实验报告,
import time
from showContent import extract_experiment_reports
from report_processor import process_all_reports
def main():
# 记录整个程序的开始时间
start_time = time.time()
# 设置文档路径(根据实际情况修改)
doc_path = "report/华为HCIA-GaussDB应用开发22计科本六21106080900204纪容超.docx" # 可以是docx、pdf等支持的格式
print(f"开始处理文档: {doc_path}")
try:
# 从文档中提取实验报告数据
reports = extract_experiment_reports(doc_path)
if not reports:
print("未从文档中提取到任何实验报告数据")
return
print(f"成功提取 {len(reports)} 份实验报告")
# 批量处理所有实验报告
processed_reports, total_time = process_all_reports(reports)
# 处理完成后的操作(可根据需要扩展)
print("\n===== 实验报告处理流程全部完成 =====")
print(f"总共处理 {len(processed_reports)} 份报告")
print(f"整个程序运行总耗时: {time.time() - start_time:.2f}秒")
# 这里可以添加保存处理结果到文件的代码
# 例如保存为JSON文件
# import json
# with open("处理完成的实验报告.json", "w", encoding="utf-8") as f:
# json.dump(processed_reports, f, ensure_ascii=False, indent=2)
# print("处理结果已保存到 JSON 文件")
except Exception as e:
print(f"程序执行过程中发生错误: {str(e)}")
# 打印详细错误信息便于调试
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()
运行结果:
.....
===== 第 7 份报告处理完成,耗时: 210.81秒 =====
===== 所有报告处理完成!共处理 7 份报告 =====
单份报告平均处理时间: 192.77秒
批量处理总耗时: 557.93秒
....
4111

被折叠的 条评论
为什么被折叠?



