fix(api): 修复因缺少“电子邮箱”字段导致的 KeyError

在 `_get_info` 函数中,当解析的网页不包含“电子邮箱”等可选字段时,
`pending_result` 字典中会缺少对应的键。

旧代码的逻辑 `("无" if pending_result.get("电子邮箱:") == "" else pending_result["电子邮箱:"])` 存在缺陷:
当键不存在时,`.get()` 返回 `None`,导致条件判断为 `False`,
进而执行 `else` 分支中的 `pending_result["电子邮箱:"]`,
这种不安全的方括号访问方式直接引发了 `KeyError` 异常,导致程序崩溃。

本次提交通过将所有类似的数据提取逻辑统一修改为更健壮的 `pending_result.get(key) or "无"` 模式,
This commit is contained in:
NianBroken
2025-06-28 18:39:11 +08:00 Unverified
parent 5a5303b616
commit b171ed515e
+34 -23
View File
@@ -284,6 +284,7 @@ class Client:
key = pq(content).find("label.col-sm-4.control-label").text() key = pq(content).find("label.col-sm-4.control-label").text()
value = pq(content).find("div.col-sm-8 p.form-control-static").text() value = pq(content).find("div.col-sm-8 p.form-control-static").text()
# 到这一步,解析到的数据基本就是一个键值对形式的html数据了,比如"[学号:]:123456" # 到这一步,解析到的数据基本就是一个键值对形式的html数据了,比如"[学号:]:123456"
if key: # 确保key不是空的,避免无效数据
pending_result[key] = value pending_result[key] = value
# 学生学籍信息,其他信息,联系方式 # 学生学籍信息,其他信息,联系方式
for ul_item in doc.find("div.col-sm-4").items(): for ul_item in doc.find("div.col-sm-4").items():
@@ -291,38 +292,47 @@ class Client:
key = pq(content).find("label.col-sm-4.control-label").text() key = pq(content).find("label.col-sm-4.control-label").text()
value = pq(content).find("div.col-sm-8 p.form-control-static").text() value = pq(content).find("div.col-sm-8 p.form-control-static").text()
# 到这一步,解析到的数据基本就是一个键值对形式的html数据了,比如"[学号:]:123456" # 到这一步,解析到的数据基本就是一个键值对形式的html数据了,比如"[学号:]:123456"
if key: # 确保key不是空的,避免无效数据
pending_result[key] = value pending_result[key] = value
if pending_result.get("学号:") == "": if pending_result.get("学号:") == "":
return { return {
"code": 1014, "code": 1014,
"msg": "当前学年学期无学生时盒数据,您可能已经毕业了。\n\n如果是专升本同学,请使用专升本后的新学号登录~", "msg": "当前学年学期无学生时盒数据,您可能已经毕业了。\n\n如果是专升本同学,请使用专升本后的新学号登录~",
} }
# 使用 pending_result.get(key) or "无" 的模式。
# .get(key) 在键不存在时返回 None。
# 在Python中,None 和空字符串 "" 都被视为 "falsy"(布尔值为False)。
# 所以 `falsy_value or "无"` 会返回 "无"。
# 如果 .get(key) 返回一个非空字符串("truthy"),则表达式返回该字符串。
# 这种方式简洁且能同时处理键不存在和键值为空字符串两种情况。
result = { result = {
"sid": pending_result["学号:"], "sid": pending_result.get("学号:") or "",
"name": pending_result["姓名:"], "name": pending_result.get("姓名:") or "",
# "birthday": "无" if pending_result.get("出生日期:") == '' else pending_result["出生日期:"], "class_name": pending_result.get("班级名称:") or "",
# "id_number": "无" if pending_result.get("证件号码:") == '' else pending_result["证件号码:"], "birthday": pending_result.get("出生日期:") or "",
# "candidate_number": "无" if pending_result.get("考生号:") == '' else pending_result["考生号:"], "id_number": pending_result.get("证件号码:") or "",
# "status": "无" if pending_result.get("学籍状态:") == '' else pending_result["学籍状态:"], "candidate_number": pending_result.get("考生号:") or "",
# "entry_date": "无" if pending_result.get("入学日期:") == '' else pending_result["入学日期:"], "status": pending_result.get("学籍状态:") or "",
# "graduation_school": "无" if pending_result.get("毕业中学:") == '' else pending_result["毕业中学:"], "entry_date": pending_result.get("入学日期:") or "",
"domicile": ("" if pending_result.get("籍贯") == "" else pending_result["籍贯:"]), "graduation_school": pending_result.get("毕业中学") or "",
"phone_number": ("" if pending_result.get("手机号码") == "" else pending_result["手机号码:"]), "domicile": pending_result.get("籍贯") or "",
"parents_number": "", "phone_number": pending_result.get("手机号码:") or "",
"email": ("" if pending_result.get("电子邮箱:") == "" else pending_result["电子邮箱:"]), "parents_number": "", # 此字段似乎未解析,保持原样
"political_status": ("" if pending_result.get("政治面貌") == "" else pending_result["政治面貌:"]), "email": pending_result.get("电子邮箱") or "",
"national": ("" if pending_result.get("民族") == "" else pending_result["民族:"]), "political_status": pending_result.get("政治面貌") or "",
# "education": "无" if pending_result.get("培养层次:") == '' else pending_result["培养层次:"], "national": pending_result.get("民族:") or "",
# "postal_code": "无" if pending_result.get("邮政编码:") == '' else pending_result["邮政编码:"], # "education": pending_result.get("培养层次:") or "无",
# "grade": int(pending_result["学号:"][0:4]), # "postal_code": pending_result.get("邮政编码:") or "无",
# "grade": int(pending_result["学号:"][0:4]), # 注意:如果学号可能为空
} }
if pending_result.get("学院名称:") is not None: if pending_result.get("学院名称:") is not None:
# 如果在个人信息页面获取到了学院班级 # 如果在个人信息页面获取到了学院班级
result.update( result.update(
{ {
"college_name": ("" if pending_result.get("学院名称:") == "" else pending_result["学院名称:"]), "college_name": pending_result.get("学院名称:") or "",
"major_name": ("" if pending_result.get("专业名称:") == "" else pending_result["专业名称:"]), "major_name": pending_result.get("专业名称:") or "",
"class_name": ("" if pending_result.get("班级名称:") == "" else pending_result["班级名称:"]), "class_name": pending_result.get("班级名称:") or "",
} }
) )
else: else:
@@ -346,12 +356,13 @@ class Client:
key = pq(content).find("label.col-sm-4.control-label").text() + "" # 为了保持格式一致,这里加个冒号 key = pq(content).find("label.col-sm-4.control-label").text() + "" # 为了保持格式一致,这里加个冒号
value = pq(content).find("div.col-sm-8 label.control-label").text() value = pq(content).find("div.col-sm-8 label.control-label").text()
# 到这一步,解析到的数据基本就是一个键值对形式的html数据了,比如"[学号:]:123456" # 到这一步,解析到的数据基本就是一个键值对形式的html数据了,比如"[学号:]:123456"
if key: # 确保key不是空的
pending_result[key] = value pending_result[key] = value
result.update( result.update(
{ {
"college_name": ("" if pending_result.get("学院:") is None else pending_result["学院:"]), "college_name": pending_result.get("学院:") or "",
"major_name": ("" if pending_result.get("专业:") is None else pending_result["专业:"]), "major_name": pending_result.get("专业:") or "",
"class_name": ("" if pending_result.get("班级:") is None else pending_result["班级:"]), "class_name": pending_result.get("班级:") or "",
} }
) )
return {"code": 1000, "msg": "获取个人信息成功", "data": result} return {"code": 1000, "msg": "获取个人信息成功", "data": result}