hfut - 合工大教务接口文档¶
版本 v2.2.2.
功能特性¶
- 同时支持合肥校区和宣城校区的教务系统, 对应接口的使用方式完全相同
- 支持会话自动更新, 无需担心超过时间后访问接口会出错
- 支持非法参数检查, 你再也不用担心一不小心就被封了 IP 了
- 支持全局配置 HTML 解析器, 同时照顾了不会处理依赖编译的新手和对性能有要求的场景
- 使用简单, 只需声明一个
hfut.Student对象即可调用所有接口 - 接口丰富, 提供了所有学生能够使用的教务接口, 除此外还有正常情况下学生无法访问到的接口
- 可以灵活控制课表数据, 再也不需要各类上传个人隐私, 功能臃肿的课表软件了
- 数据能够轻松导出, 能够为基于工大教务数据的服务或应用提供强大的底层支持
- 提供了强大的选课功能, 你能轻松查询可选的课程, 查看教学班级选中人数, 批量提交增删课程数据
- 对开发友好, 每个接口返回的数据结构都提供了描述, 同时提供了用于继承的基类以及页面处理的函数和其他工具提升你的开发效率
- Python2/3 兼容, 代码在 2.7,3.3,3.4,3.5, pypy 五个版本上进行了测试
它能做什么?¶
- 学生微信后台服务支持
- 选课助手
- 学生数据分析
- OAuth 登陆服务
- 以及一切你能想到的与学生信息与教务数据有关的项目
快速上手¶
你只需要在命令行下输入一下代码便能安装好 hfut:
$ pip install hfut
如果你没有安装 pip , Python 安装包指南 能够指导你安装 PIP .
通用参数说明¶
参数与教务的网络请求参数基本一致
xqdm: 学期代码, 形如 ‘027’, ‘027’ 的字符串kcdm: 课程代码, 形如 ‘1400011B’ 的字符串zydm: 专业代码, 形如 ‘0120123111’ 的字符串jxbh: 教学班号, 形如 ‘0001’ 的字符串kcmc: 课程名称关键字jsh: 教师号, 形如 ‘12000198’ 的字符串kclx: 课程类型, 有 ‘x’(选修), ‘b’(必修), ‘jh’(本专业计划)三个选项
更新和发布历史¶
如果你想和社区以及开发版的 hfut 保持最新的联系, 这有几种方式:
发布历史¶
2.2.2 (20161128)¶
问题修复
- 修复
interface.GetClassStudents班级名称匹配的遗漏 - 修复
log.report_response遗漏的响应体内容 interface.SearchCourse在没有搜索结果时不再给出警告, 搜索行为本来就可以没有结果
2.2.1 (20161127)¶
功能和改进
- 现在所有接口
parse方法改为静态函数, 现在可以无需实例化便可解析响应了
问题修复
- 修复由于 Python 默认值陷阱导致
interface.BaseInterface下的send_kwarg,sextra_kwargs在未被重新声明时所有子类公用同一个对象的问题 - 有了全局非法字符检查后, 去除了
interface.EvaluateCourse冗余的检查过程 - 修复了
interface.BaseInterface中的文档错误
接口变动
- 由于所有接口
parse方法改为静态函数,interface.SetTelephone.parse由原来返回值为是否修改成功改为直接返回修改后的结果(可能没变), 但shortcut.Student#set_telephone的行为是没有变的
2.2.0 (20161125)¶
功能和改进
- 添加了请求参数校验功能, 避免因为错误的参数使 IP 被封, 通过设置
value.ENV['REQUEST_ARGUMENTS_CHECK']开启或关闭, 默认是开启的, 同时注意它只检查发往教务系统地址的请求 util.sort_hosts重构为通用的测速函数, 现在配置请求的路径及其他请求参数, 同时现在必须显式地提供hosts参数
问题修复
- 修复
interface.GetClassStudents班级名称匹配的遗漏, 调整了学生信息匹配的正则 - 修复了
examples/hfut_img.py
其他杂项
- 更新了文档
- 完善测试用例
2.1.0 (20161121)¶
功能和改进
- 添加了
parser.GlobalFeaturedSoup, 能够通过配置value.ENV['SOUP_FEATURES']属性来全局配置解析器, 目前在html.parser与lxml下进行了测试 - 添加了
log.report_response用来生成响应报告 - 添加了
shortcut.BaseShortcuts.request, 用来分离接口的请求与解析 - 有关请求的日志记录以及会话类更加友好
问题修复
- 修复 Python2 中对 Unicode 匹配不完整的问题
接口变动
- 原先使用
bs4.BeautifulSoup解析的接口统一改为parser.GlobalFeaturedSoup子类 HTML_PARSER重命名为SOUP_FEATURESvalue模块中的值全部添加到 ENV 字典中使其可变动interface.GetClassStudents不再因未匹配到班级名称或学期报错util.rank_host_speed重构为util.sort_hosts, 不再接受主机 ip 参数, 改为主机 地址参数, 同时不再删除错误请求地址, 而是统一将返回时间设为 INFINITY(10000000ms)
其他杂项
- 添加了使用
lxml作为解析器的测试, 完善了其他一些测试细节
2.0.0 (20161029)¶
功能和改进
- 重构了框架的核心部分, 对原先的接口进行了解耦, 实现细节更加清晰, 现在能够控制接口请求的请求生成, 响应获取, 响应解析的过程
- 添加了
parser.dict_list_2_matrix - 添加了
util.curriculum2schedule将课程表转换为上课时间表 - 添加了将上课时间表转换为 icalendar 协议文件并导出的例子
问题修复
- 修复
shortcut.Student#change_course旧版结果验证方法没有移除导致的问题 - 修复
shortcut.Student#change_course对教学班号错误的验证逻辑
接口变动
- 原来的
model模块中的会话类拆分到session,interface,shortcut三个模块, 具体改变可以阅读源码查看改动 - 原先使用
model.GuestSession,model.StudentSession快速调用接口现在改为使用shortcut.Guest,shortcut.Student即可, 接口调用方式与名字没有变化, 但是访问原先会话的属性需要从新类的session属性中获得 - 删除了属性验证相关的函数, 包括
value.validate_attrs,session.BaseSession.validate_campus,session.StudentSession.validate_account,session.StudentSession.validate_password - 原来会话类的
html_parser,site_encoding迁移到了value模块并改为HTML_PARSER,SITE_ENCODING - 一些不合法的参数将不再隐式地返回结果而是直接触发错误, 涉及到
shortcut.Student#change_password,interface.ChangePassword,interface.SetTelephone shortcut.Student#change_course: 当选课教学班号错误, 删除错误的课程时将不再触发错误, 而是得到一个警告
其他杂项
- 更新测试用例
- 更新文档
1.4.3 (20160829)¶
问题修复
- 修复
model.StudentSession#get_selectable_courses由于multiprocessing.dummy.Pool在 Python 2.7 下不支持 with 语句导致的错误
其他杂项
- 修正了
model.StudentSession#change_course中的文档错误 - 改进了测试脚本, 修复由于测试脚本没有判断程序结束状态码导致有时测试失败结果没有捕捉到的问题
1.4.2 (20160828)¶
功能和改进
- 优化了
model.StudentSession#get_selectable_courses多线程操作
问题修复
- 修复了
model.StudentSession#get_selectable_courses由于之前版本返回值的接口变动造成的错误 - 修复了
model.StudentSession#change_course由于之前版本返回值的接口变动造成的错误
接口变动
model.GuestSession#get_system_state->model.GuestSession#get_system_status(拼写错误这么久竟然没发现= =)- 去除了
log.unstable
1.4.1 (20160812)¶
接口变动
- 将当接口没有解析出结果时返回的 None 值改为相应的空的容器
问题修复
- 修复
model.GuestSession#get_class_info返回结果中的备注字段名中包含空格的错误 - 修复
model.GuestSession#get_class_students班级名称正则表达式匹配不完全导致的错误 - 修复
model.GuestSession#get_class_students在教学班没有学生时触发错误的问题
1.4.0 (20160812)¶
接口变动
- 包名由
hfut_stu_lib改为hfut - 删除了
APIResult, 使用model.BaseSession.histories(默认最大长度为10的双端队列)储存历史响应
问题修复
list本身是线程安全的, 去除了不必要的锁
1.3.3 (20160730)¶
问题修复
- 修复 Python2 下
urllib.unquote不接受编码参数的错误(model.StudentSession.login) - 修复 Python2 下
list对象缺少copy()方法的错误(util.filter_curriculum) - 修复时多线程时释放锁的方法名拼写错误
- 修复
model.StudentSession#get_selectable_courses文件名重复地添加’.json’后缀
其他杂项
- 重新配置了线上持续集成环境
1.3.2 (20160728)¶
功能和改进
- 重新实现了类的属性验证方式,
hfut.value.validate_attrs - 添加了对 model.StudentSession.account, hfut.model.BaseSession.campus 的验证
接口变动
exception中的 WrongPasswordPattern 改为了 ValidationError
问题修复
- 更新了新的学期名称匹配规则
1.3.1 (20160722)¶
问题修复
- 修复
util.get_point对成绩数据判断的不完整导致的错误 - 修复
model.StudentSession.get_optional_courses分片错误导致总是缺失一门课程的错误 - 修复
model.GuestSession.get_teaching_plan查询公选课时教务系统返回大量重复课程的错误 - 修复
model.GuestSession.search_course结果数据格式化不完整
接口变动
model.GuestSession.get_teaching_plan` 查询公选课时不再需要 `zydm参数- 删除了所有返回结果中含有的 序号 字段
1.3.0 (20160719)¶
功能和改进
- 添加了
model.StudentSession.get_unfinished_evaluation接口用来查询未完成的课程评价 - 添加了
model.StudentSession.evaluate_course接口用来进行课程评价 - 添加了登录时的密码格式验证
- 密码格式不正确时将会触发新增的
exception.WrongPasswordPattern - 调整了日志记录格式
util.rank_host_speed对写操作加锁避免竞争冒险model.StudentSession.get_selectable_courses使用了多线程进行优化
接口变动
- 去掉了
model.StudentSession.change_password` 多余的 `oldpwd`,`new2pwd参数, 合肥校区修改教务密码无意义, 因此不允许调用此接口 model.StudentSession.login_session改为model.StudentSession.login并且不再有返回值, 同时也修复了上个版本需要主动调用的问题
问题修复
model.StudentSession.__str__格式化错误model.StudentSession.change_course中错误的属性引用- 修复由于存在未完成的课程评价导致接口调用出错的问题
1.2.2 (20160625)¶
小的改进
model.StudentSession初始化成功后会从 cookie 中提取出姓名- 登录失败时将会触发新增的
exception.SystemLoginFailed, IP被封会触发exception.IPBanned
接口变动
model.StudentSession实例化后不会自动登录,需要主动调用model.StudentSession.login_session登录, 这样可以在登陆前对实例进行其他初始化,例如配置代理等
1.2.0 (20160510)¶
小的改进
- 优化了
utils.filter_curriculum, 当课程冲突时会给出警告
接口改变
- 接口会话初始化参数
is_hefei变成了campus(value模块中的校区代码HF,XC) 并且需要显示提供 - 删除了
model.AuthSession,value中的用户类型常量 - 去除了
model.APIResult中的魔法方法, 保证了调用明确的原则
问题修复
- 纠正了错误的通用登陆逻辑
- 修复了合肥校区登陆网址变更导致合肥校区无法登陆的问题
其他杂项
- 调整了例子
web_curriculum.py - 相应调整了测试用例
1.1.2 (20160413)¶
小的改进
model.APIResult.json支持了 json.dumps 的参数- 统一
model.GuestSession.get_entire_curriculum和model.GuestSession.get_my_curriculum的代码 model.GuestSession.get_entire_curriculum和model.GuestSession.get_my_curriculum返回值添加了起止周字段
接口改变
parser.parse_course不再接受 None 值为参数
文档
- 补充例子
其他杂项
- 添加例子
web_curriculum.py, 使用 bottle 编写的一个简单课表查看页面, 可以筛选每周的课程, 可以在手机上安装 qpython 并安装好 hfu_stu_lib 后在手机上运行
1.1.1 (20160330)¶
功能和改进
- 添加了
utils.filter_curriculum, 筛选出指定星期[和指定星期几]的课程 - 所有接口文档添加里
@structure描述标记用来描述返回数据的结构和类型
小的改进
- 添加
parser.zip函数保证 zip 过程的准确性 - 添加
log.log_result_not_found输出当接口未解析出数据时的日志
接口改变
utils.get_host_speed_rank改名为utils.rank_host_speedlog.unfinished装饰器被移除parser.parse_tr_strs不再接受单个的Tag对象作为参数, 同时现在td下有子标签也会解析结果, 不再报ValueError
接口变动
__init__中的变量, 迁移到了values
问题修复
- 修复了一些接口返回数据字段类型与整体定义不一致的问题
- 修复了一些接口出现意外的空值导致 zip 长度不一致导致结果出错的问题
- 统一了返回空值的行为
文档
- 对应地更新了
功能特性这一部分
1.1.0 (20160310)¶
功能和改进
- 现在支持合肥校区的教务系统了
小的改进
- 简单的修改了一下例子
接口改变
- 所有继承自
model.BaseSession的类现在需要一个is_hefei参数来确定是否是合肥校区
问题修复
- 修复
model.StudentSession.get_selected_courses的费用字段使用了错误的整数类型 - 修复
model.GuestSession.get_course_classes键值分离由于特殊情况导致的错误, 同时也对其他方法进行了相应的修改避免类似问题发生 - 修复
model.APIResult.__bool__错误
文档
- 补充部分接口的文档
其他杂项
- 补充和修复了测试用例
- 为了保护贡献者隐私将测试模块从线上仓库删除, 对用户没有任何影响
1.0.0 (20160307)¶
功能和改进
- 精简了架构,现在接口区分更清晰,现在支持单独的会话配置,同时不会再因动态绑定接口而无法进行代码提示
- 添加了
util.cal_term_code和util.term_str2code计算学期代码 - 添加了
model.GuestSession.get_selecting_lesson_time查询选课时间 - 添加
get_host_speed_rank,由于宣城校区校内还有多个镜像站点,现在提供了测试地址速度排行的功能 - 现在能够自动更新会话保持登录状态了
小的改进
change_lesson现在能够判断当前是否能够选课get_lessons_can_be_selected导出的结果现在是格式化后的了model.StudentSession.get_stu_timetable现在返回的上课周数为周数列表便于实际处理get_selected_lessons结果中的费用和学分两个字段从字符串分别改为了整型和浮点型- 调整了
model.GuestSession.get_teaching_plan的参数使使用更加方便 - 统一了
model.StudentSession.get_code的结果键值为中文 - 现在登录时能够判断是否是煞笔的防注入系统导致无法登陆并且如果是宣城校区会自动选取可用地址重新登录
接口改变
去除了
const,session,api,api_request_builder,core将原来的
api中所有的接口根据要求的登录权限不同分别迁移到了model.GuestSession和model.StudentSession将原来的
core中的@unstable,@unfinish迁移到了log模块中const中的配置项迁移到了BaseSession中, 现在的配置是会话级而不是全局的,这样可以方便的根据需要进行修改util.store_api_result迁移到了model.APIResult.store_api_result并稍微调整了一下参数- 重新命名了大量接口使其更易理解, 同时纠正命名的错误, 接口的重命名状态如下
get_selecting_lesson_time->get_system_statesearch_lessons->search_courseget_lesson_classes->get_course_classesget_stu_info->get_my_infoget_stu_grades->get_my_achievementsget_stu_timetable->get_my_curriculumget_stu_feeds->get_my_feesget_optional_lessons->get_optional_coursesget_selected_lessons->get_selected_coursesis_lesson_selected->check_coursesget_lessons_can_be_selected->get_selectable_courses
接口变动
- 现在登录也看作是一个接口,进行了重构
- 现在所有的接口返回的都是
model.APIResult对象
问题修复
- 修复发送登录权限不一致时仍会发送请求的问题
- 修复
AuthSession初始化时参数判断逻辑错误 - 修复
model.APIRequest初始化时继承参数错误 - 修复
api.get_optional_lessons由于疏忽缺少一个参数 - 修复
model.StudentSession.get_stu_timetable上课周数匹配情况的遗漏 - 修复
model.GuestSession.search_lessons由于编码问题无法使用课程名称搜索的问题 - 修复
parser.parse_tr_strs触发异常时字符串格式错误的问题
文档
- 在**高级技巧**一章添加了例子
其他杂项
- 将默认的测试模块从
unitest迁移到了pytest - 添加大量测试,Python 版本覆盖 2.6-3.5
0.5.0 (20160225)¶
- 重构
api_request_builder.GetLessonClasses, 现在可以返回课程已选人数, 课程容量, 时间地点等信息, 同时修复了一些问题
- 重构
- 添加
api.get_lessons_can_be_selected, 获取可以选上的课程教学班级
- 添加
- 合并
api.select_lesson和api.delete_lesson为 api.change_lesson并重构了逻辑
- 合并
- 修改
api.is_lesson_selected参数类型为 list, 避免使用中重复调用导致发送大量冗余的请求
- 修改
重构
parser.parse_tr_strs, 现在支持单个值输入输出添加
parser.dict_list_2_tuple_set提升兼容性
0.4.2 (20160218)¶
- 修复由于配置遗漏导致无法安装的问题
0.4.1 (20160217)¶
- 修复一些潜在问题
- 更新文档
0.4.0 (20160216)¶
删除缓存模块及相关接口
- 分离一般接口与请求接口, 去除了
g对象, 只使用列表all_api 保存注册的一般接口
- 分离一般接口与请求接口, 去除了
- 将
AuthSession.catch_response删除, 改用 AuthSession.api_request
- 将
- 新增了
model模块, 包含model.APIRequestBuilder, model.APIRequest,model.APIResult三个类
- 新增了
- api 模块合并为单个文件, 添加了请求生成与响应处理的
api_request_builder模块
- 新的架构避免了
api注册冗余以及api与session 的交叉调用, 简化模型, 增加了灵活性, 并且不改变之前使用 session 调用接口的方式
- 新的架构避免了
修改了
api.get_stu_info中照片地址的生成方式
0.3.5 (20160208)¶
- 修复
session.AuthSession初始化时的逻辑错误 - 修改缓存 md5 计算方式
- 兼容 Python 3.X
0.3.4 (20151030)¶
- 添加 MANIFEST.in
- 提交到了官方仓库
0.3.3 (20151030)¶
- 修复 setup.py 配置中的一处错误
- 提交到了官方仓库
0.3.2 (20151030)¶
- 修改持续集成通知
- 修复 anydbm 在不同环境下触发的 AttributeError: get
0.3.1 (20151030)¶
- 修复接口注册前后的参数差异导致
cal_cache_md5 计算结果不正确的问题
- 修复接口注册前后的参数差异导致
添加了更多的测试用例
0.3.0 (20151029)¶
修改
regist_api为register_api默认在安装uniout的情况下使用其输出unicode内容方便使用
改用元类来绑定接口, 提升声明对象时的效率
预定义了用户类型,
user_type参数使用预定义变量cal_gpa精度改为5位小数, 与学校一致- 添加缓存功能, 你可以通过一个全局的缓存管理对象管理缓存了,
模块内置了
MemoryCache和FileCache, 当然你也可以继承BaseCache编写新的缓存管理对象, 模块会自动帮你注册
0.2.0 (20151025)¶
调整了模块结构
- 分离了
session与 接口, 通过一个统一的AuthSession 自动绑定接口, 参数原来
StuLib接口参数相同
- 分离了
区分了用户类型, AuthSession 即使没有登录也能访问公共接口了
- 添加了
regist_api, 现在你可以在不修改模块代码的情况下添加自己的接口了
- 添加了
0.1.3 (20150912)¶
- 修复因
StuLib初始化时未对stu_id进行类型转换而导致 StuLib.get_stu_info出错的问题
- 修复因
0.1.2 (20150912)¶
- 修复安装时 README.md 缺失的问题
0.1.1 (20150912)¶
- 添加了一些单元测试
0.1.0 (20150911)¶
解决
requests不能对 GBK 转 UTF8 无损转换的问题- 添加
StuLib.catch_response, 抽象了响应的获取, 提升了代码的可维护性
- 添加
0.0.4 (20150910)¶
- 修复了
StuLib.get_class_student 中由于教务网页代码严重的错误导致页面无法解析而不可用的问题
- 修复了
添加了
StuLib.get_class_student的测试用例- 由于
requests返回的的网页无法做到无损转码, 将传递 BeautifulSoup的文档改为原始编码文档,将转码工作交给BeautifulSoup处理, 但用到正则匹配的方法还存在此问题
- 由于
0.0.3 (20150909)¶
- 统一将返回的课程代码进行大写转换,
避免因学校课程代码大小写的不统一产生不可预料的问题
重构了
StuLib.select_lesson, 现在支持更好地批量选课以及更好地结果处理过程重构了
StuLib.delete_lesson, 现在支持批量删课以及更好地结果处理过程
0.0.2 (20150903)¶
- 重构了
StuLib.select_lesson的参数处理过程, 由于第二次选课结束暂时没有完成对提交结果的处理
- 重构了
添加 Travis IC 持续集成工具
0.0.1 (20150902)¶
- 修复
StuLib.get_class_info出错 - 添加 教师信息查询
StuLib.get_teacher_info功能 - 将
StuLib.get_url的code修改为对应的方法名称 - 修复
StuLib.change_password正则匹配不完整的问题 - 修复
StuLib.set_telephone正则匹配不完整的问题 - 添加部分单元测试
- 调整了包的结构