From b171ed515ecd364d392aedde4f3570d5ce11ec60 Mon Sep 17 00:00:00 2001 From: NianBroken Date: Sat, 28 Jun 2025 18:39:11 +0800 Subject: [PATCH] =?UTF-8?q?fix(api):=20=E4=BF=AE=E5=A4=8D=E5=9B=A0?= =?UTF-8?q?=E7=BC=BA=E5=B0=91=E2=80=9C=E7=94=B5=E5=AD=90=E9=82=AE=E7=AE=B1?= =?UTF-8?q?=E2=80=9D=E5=AD=97=E6=AE=B5=E5=AF=BC=E8=87=B4=E7=9A=84=20KeyErr?= =?UTF-8?q?or?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在 `_get_info` 函数中,当解析的网页不包含“电子邮箱”等可选字段时, `pending_result` 字典中会缺少对应的键。 旧代码的逻辑 `("无" if pending_result.get("电子邮箱:") == "" else pending_result["电子邮箱:"])` 存在缺陷: 当键不存在时,`.get()` 返回 `None`,导致条件判断为 `False`, 进而执行 `else` 分支中的 `pending_result["电子邮箱:"]`, 这种不安全的方括号访问方式直接引发了 `KeyError` 异常,导致程序崩溃。 本次提交通过将所有类似的数据提取逻辑统一修改为更健壮的 `pending_result.get(key) or "无"` 模式, --- scripts/zfn_api.py | 63 +++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/scripts/zfn_api.py b/scripts/zfn_api.py index 11f2043..f2a637f 100644 --- a/scripts/zfn_api.py +++ b/scripts/zfn_api.py @@ -284,45 +284,55 @@ class Client: key = pq(content).find("label.col-sm-4.control-label").text() value = pq(content).find("div.col-sm-8 p.form-control-static").text() # 到这一步,解析到的数据基本就是一个键值对形式的html数据了,比如"[学号:]:123456" - pending_result[key] = value + if key: # 确保key不是空的,避免无效数据 + pending_result[key] = value # 学生学籍信息,其他信息,联系方式 for ul_item in doc.find("div.col-sm-4").items(): content = pq(ul_item).find("div.form-group") key = pq(content).find("label.col-sm-4.control-label").text() value = pq(content).find("div.col-sm-8 p.form-control-static").text() # 到这一步,解析到的数据基本就是一个键值对形式的html数据了,比如"[学号:]:123456" - pending_result[key] = value + if key: # 确保key不是空的,避免无效数据 + pending_result[key] = value if pending_result.get("学号:") == "": return { "code": 1014, "msg": "当前学年学期无学生时盒数据,您可能已经毕业了。\n\n如果是专升本同学,请使用专升本后的新学号登录~", } + + # 使用 pending_result.get(key) or "无" 的模式。 + # .get(key) 在键不存在时返回 None。 + # 在Python中,None 和空字符串 "" 都被视为 "falsy"(布尔值为False)。 + # 所以 `falsy_value or "无"` 会返回 "无"。 + # 如果 .get(key) 返回一个非空字符串("truthy"),则表达式返回该字符串。 + # 这种方式简洁且能同时处理键不存在和键值为空字符串两种情况。 result = { - "sid": pending_result["学号:"], - "name": pending_result["姓名:"], - # "birthday": "无" if pending_result.get("出生日期:") == '' else pending_result["出生日期:"], - # "id_number": "无" if pending_result.get("证件号码:") == '' else pending_result["证件号码:"], - # "candidate_number": "无" if pending_result.get("考生号:") == '' else pending_result["考生号:"], - # "status": "无" if pending_result.get("学籍状态:") == '' else pending_result["学籍状态:"], - # "entry_date": "无" if pending_result.get("入学日期:") == '' else pending_result["入学日期:"], - # "graduation_school": "无" if pending_result.get("毕业中学:") == '' else pending_result["毕业中学:"], - "domicile": ("无" if pending_result.get("籍贯:") == "" else pending_result["籍贯:"]), - "phone_number": ("无" if pending_result.get("手机号码:") == "" else pending_result["手机号码:"]), - "parents_number": "无", - "email": ("无" if pending_result.get("电子邮箱:") == "" else pending_result["电子邮箱:"]), - "political_status": ("无" if pending_result.get("政治面貌:") == "" else pending_result["政治面貌:"]), - "national": ("无" if pending_result.get("民族:") == "" else pending_result["民族:"]), - # "education": "无" if pending_result.get("培养层次:") == '' else pending_result["培养层次:"], - # "postal_code": "无" if pending_result.get("邮政编码:") == '' else pending_result["邮政编码:"], - # "grade": int(pending_result["学号:"][0:4]), + "sid": pending_result.get("学号:") or "无", + "name": pending_result.get("姓名:") or "无", + "class_name": pending_result.get("班级名称:") or "无", + "birthday": pending_result.get("出生日期:") or "无", + "id_number": pending_result.get("证件号码:") or "无", + "candidate_number": pending_result.get("考生号:") or "无", + "status": pending_result.get("学籍状态:") or "无", + "entry_date": pending_result.get("入学日期:") or "无", + "graduation_school": pending_result.get("毕业中学:") or "无", + "domicile": pending_result.get("籍贯:") or "无", + "phone_number": pending_result.get("手机号码:") or "无", + "parents_number": "无", # 此字段似乎未解析,保持原样 + "email": pending_result.get("电子邮箱:") or "无", + "political_status": pending_result.get("政治面貌:") or "无", + "national": pending_result.get("民族:") or "无", + # "education": pending_result.get("培养层次:") or "无", + # "postal_code": pending_result.get("邮政编码:") or "无", + # "grade": int(pending_result["学号:"][0:4]), # 注意:如果学号可能为空 } if pending_result.get("学院名称:") is not None: # 如果在个人信息页面获取到了学院班级 result.update( { - "college_name": ("无" if pending_result.get("学院名称:") == "" else pending_result["学院名称:"]), - "major_name": ("无" if pending_result.get("专业名称:") == "" else pending_result["专业名称:"]), - "class_name": ("无" if pending_result.get("班级名称:") == "" else pending_result["班级名称:"]), + "college_name": pending_result.get("学院名称:") or "无", + "major_name": pending_result.get("专业名称:") or "无", + "class_name": pending_result.get("班级名称:") or "无", } ) else: @@ -346,12 +356,13 @@ class Client: key = pq(content).find("label.col-sm-4.control-label").text() + ":" # 为了保持格式一致,这里加个冒号 value = pq(content).find("div.col-sm-8 label.control-label").text() # 到这一步,解析到的数据基本就是一个键值对形式的html数据了,比如"[学号:]:123456" - pending_result[key] = value + if key: # 确保key不是空的 + pending_result[key] = value result.update( { - "college_name": ("无" if pending_result.get("学院:") is None else pending_result["学院:"]), - "major_name": ("无" if pending_result.get("专业:") is None else pending_result["专业:"]), - "class_name": ("无" if pending_result.get("班级:") is None else pending_result["班级:"]), + "college_name": pending_result.get("学院:") or "无", + "major_name": pending_result.get("专业:") or "无", + "class_name": pending_result.get("班级:") or "无", } ) return {"code": 1000, "msg": "获取个人信息成功", "data": result}