# 成绩监控系统 - 完整使用文档 > **最后更新:** 2026-01-29 > **版本:** v2.0 - 自动会话恢复版 --- ## 📑 目录 1. [服务器部署指南](#服务器部署指南) 2. [快速更新指南](#快速更新指南) 3. [故障排查指南](#故障排查指南) 4. [常见问题解决](#常见问题解决) 5. [服务管理](#服务管理) 6. [历史BUG修复记录](#历史bug修复记录) --- # 服务器部署指南 ## 📋 前置要求 - Linux服务器(Debian/Ubuntu/CentOS等) - Python 3.7+ - 服务器能访问外网 - SSH访问权限 - (可选)Docker 20+ / Docker Compose v2 ## 📦 项目文件说明 ### 必需文件(需要上传到服务器) | 文件名 | 用途 | 何时使用 | |--------|------|----------| | `monitor.py` | **主程序** | 运行监控的核心文件 | | `config.ini` | **配置文件** | 包含账号密码、邮箱配置(⚠️ 敏感文件) | | `requirements.txt` | **Python依赖列表** | 安装Python包时使用 | | `setup_python.sh` | **环境安装脚本** | 首次部署时执行,安装所有依赖 | | `grade-monitor.service` | **systemd服务配置** | 设置开机自启和后台运行 | ### 可选文件(参考文档) | 文件名 | 用途 | |--------|------| | `config(模板).ini` | 配置文件模板,新用户参考 | | `README.md` | 项目说明文档 | | `diagnose.sh` | 故障诊断脚本 | ### 不需要的文件(不要上传) - `venv/` - 虚拟环境(服务器上重新创建) - `.git/` - Git仓库(可选) - `.last_*` - 运行时生成的缓存文件 - `monitor.log` - 运行时生成的日志文件 ## 🚀 部署步骤 ### 第一步:准备文件 ```bash # 在本地打包必需文件(WSL或Git Bash) cd /mnt/e/50425/Documents/Github/GPA_Monitoring ``` ### 第二步:上传到服务器 ```bash scp gpa_monitor.tar.gz 用户名@服务器IP:/home/用户名/ ``` ### 第三步:在服务器上解压并安装 ```bash # 登录到服务器 ssh 用户名@服务器IP cd grade_monitor # 你解压到的目录 # 给脚本添加执行权限 chmod +x setup_python.sh diagnose.sh # 运行安装脚本(会自动安装Python、创建虚拟环境、安装依赖) ./setup_python.sh ``` ### 第四步:检查配置文件 ```bash # 编辑配置文件(如果需要修改) nano config.ini # 确认配置正确: # - USERNAME 和 PASSWORD(学号和密码) # - 邮箱配置(SENDER_EMAIL、SENDER_PASSWORD、RECEIVER_EMAIL) # - CHECK_INTERVAL(建议120秒以上) ``` 配置文件示例: ```ini [login] USERNAME = 你的学号 PASSWORD = 你的密码 LOGIN_URL = ... GRADE_URL = ... [email] SENDER_EMAIL = your_email@163.com SENDER_PASSWORD = SMTP授权码(不是邮箱密码!) RECEIVER_EMAIL = 接收通知的邮箱 [monitor] CHECK_INTERVAL = 120 # 建议120-300秒 REQUEST_DELAY = 5 MAX_RETRIES = 3 RETRY_DELAY = 10 ``` ### 第五步:测试运行 ```bash # 激活虚拟环境 source venv/bin/activate # 测试运行(获取一次成绩,不进行监控) python3 monitor.py --test # 查看提取的成绩 cat .last_grade_content.txt ``` --- ## 🐳 Docker 部署(推荐) > 适合已有 Docker 环境的服务器(例如 docker.aizhangz.top)。 ### 1) 准备文件(本地或服务器) 必需文件: - `monitor.py` - `requirements.txt` - `Dockerfile` - `docker-compose.yml` - `config.ini`(⚠️ 敏感文件) ### 2) 在服务器上运行 ```bash # 进入项目目录 cd ~/grade_monitor # 首次构建并启动 docker compose up -d --build # 查看日志 docker logs -f gpa-monitor ``` ### 3) 测试模式(可选) ```bash docker compose run --rm gpa-monitor python /app/monitor.py --config /data/config.ini --test ``` ### 4) 说明 - 运行日志和缓存文件会写入 `./data/` - 配置文件通过 `./config.ini:/data/config.ini:ro` 挂载 ## 🔧 设置后台运行 ### 使用 systemd(推荐,生产环境) **优点:** 开机自启、崩溃自动重启、系统化管理 ```bash # 1. 编辑服务文件,修改用户名和路径 nano grade-monitor.service # 确保这些路径正确: # User=你的用户名 # WorkingDirectory=/home/你的用户名/grade_monitor # ExecStart=/home/你的用户名/grade_monitor/venv/bin/python3 /home/你的用户名/grade_monitor/monitor.py # 2. 复制服务文件到系统目录 sudo cp grade-monitor.service /etc/systemd/system/ # 3. 重新加载 systemd sudo systemctl daemon-reload # 4. 启动服务 sudo systemctl start grade-monitor # 5. 查看状态 sudo systemctl status grade-monitor # 6. 设置开机自启 sudo systemctl enable grade-monitor ``` **systemd 常用命令:** ```bash # 启动 sudo systemctl start grade-monitor # 停止 sudo systemctl stop grade-monitor # 重启 sudo systemctl restart grade-monitor # 查看状态 sudo systemctl status grade-monitor # 查看日志 sudo journalctl -u grade-monitor -f # 开机自启 sudo systemctl enable grade-monitor # 禁用自启 sudo systemctl disable grade-monitor ``` ## 📊 监控和维护 ### 查看日志 ```bash # 查看监控日志(程序自己的日志) tail -f ~/grade_monitor/monitor.log # 查看最后100行 tail -n 100 ~/grade_monitor/monitor.log # 搜索关键词 grep "新增课程" ~/grade_monitor/monitor.log # 查看系统日志(如果用systemd) sudo journalctl -u grade-monitor -f sudo journalctl -u grade-monitor --since "1 hour ago" ``` ### 检查运行状态 ```bash # 方法1:查看进程 ps aux | grep monitor.py # 方法2:查看日志时间戳 ls -lh ~/grade_monitor/monitor.log # 方法3:systemd状态(如果用systemd) sudo systemctl status grade-monitor ``` ## 🔒 安全建议 ### 1. 保护配置文件 ```bash # 设置文件权限(只有所有者可读写) chmod 600 config.ini # 查看权限 ls -l config.ini # 应该显示:-rw------- 1 用户名 用户名 ``` ### 2. 不要上传敏感文件到 GitHub 在 `.gitignore` 中添加: ``` config.ini *.log .last_* venv/ ``` ### 3. 定期检查日志 ```bash # 检查是否有异常 grep -i "error\|fail\|warning" monitor.log # 检查登录情况 grep "登录" monitor.log | tail -20 ``` --- # 快速更新指南 ## 🎯 本功能解决的问题 **症状:** 程序运行几小时后出现: ``` [WARNING] 未能提取到成绩信息,返回原始文本 [INFO] 成绩无变化(共 0 门课程) ``` **原因:** 登录会话过期,需要重新登录 **解决:** ✅ 最新版本已自动检测并重新登录 ## 📦 更新方式 ### 方式1:完整更新(推荐) #### 在本地准备 ```bash # WSL或Git Bash中 cd /mnt/e/50425/Documents/Github/GPA_Monitoring # 创建更新包 tar -czf gpa_monitor.tar.gz \ monitor.py \ config.ini \ requirements.txt \ setup_python.sh \ diagnose.sh \ grade-monitor.service ``` #### 上传到服务器 ```bash scp gpa_monitor.tar.gz 用户名@服务器IP:~/ ``` #### 在服务器上更新 ```bash # 停止服务 systemctl stop grade-monitor # 备份旧文件 cd ~/grade_monitor cp monitor.py monitor.py.backup.$(date +%Y%m%d) # 解压更新(会覆盖旧文件) tar -xzf ~/gpa_monitor.tar.gz -C ~/grade_monitor # 赋予执行权限 chmod +x diagnose.sh # 重启服务 systemctl restart grade-monitor # 查看日志(确认自动重新登录功能) tail -f monitor.log ``` ### 方式2:仅更新主程序 如果只想更新 monitor.py: ```bash # 在本地(WSL) cd /mnt/e/50425/Documents/Github/GPA_Monitoring scp monitor.py 用户名@服务器IP:~/grade_monitor/ # 在服务器上 systemctl stop grade-monitor systemctl start grade-monitor tail -f ~/grade_monitor/monitor.log ``` ## ✅ 验证更新成功 查看日志,应该能看到: ### 正常运行 ``` [INFO] 开始新一轮检查 [INFO] 获取成绩页面... [DEBUG] 找到成绩表格 [INFO] 成功提取成绩信息,共 17 行 [INFO] 共解析到 15 门课程 [INFO] 成绩无变化(共 15 门课程) ``` ### 会话过期时自动处理 ``` [WARNING] 检测到会话过期,尝试重新登录... [INFO] 开始登录统一身份认证... [INFO] 登录成功!成功访问成绩页面 [INFO] 重新登录成功,继续监控 ``` ## 💡 最佳实践 1. **定期检查日志**(每天1-2次即可) ```bash tail -n 50 ~/grade_monitor/monitor.log ``` 2. **不要频繁重启服务** - 新版本会自动处理会话过期 - 只在真正出问题时才重启 3. **保留备份** ```bash # 每次更新前都会自动备份 ls -lh ~/grade_monitor/monitor.py.backup.* ``` 4. **合理设置检查间隔** - 建议 120-300 秒 - 避免触发学校系统限流 --- # 故障排查指南 ## 🚨 问题一:"未能提取到成绩信息,共 0 门课程" ### 症状 日志中反复出现: ``` [WARNING] 未能提取到成绩信息,返回原始文本 [INFO] 成绩无变化(共 0 门课程) ``` ### 快速诊断 #### 步骤1:运行诊断工具 ```bash cd ~/grade_monitor ./diagnose.sh ``` 诊断工具会自动: - 检查 BeautifulSoup 是否安装 - 运行测试模式 - 分析测试结果 - 提供修复建议 #### 步骤2:检查 BeautifulSoup 安装 ```bash python3 -c "import bs4; print('BeautifulSoup4 已安装')" ``` 如果报错,安装依赖: ```bash pip3 install beautifulsoup4 # 或完整安装所有依赖 pip3 install -r requirements.txt ``` #### 步骤3:使用调试模式 ```bash cd ~/grade_monitor python3 monitor.py --test --debug ``` 查看输出中是否有: - ✅ "找到成绩表格" - ✅ "找到 X 行成绩数据" - ✅ "共解析到 X 门课程" #### 步骤4:检查是否登录失效 ```bash grep "登录页面\|LOGIN_REQUIRED" ~/grade_monitor/monitor.log ``` 如果有,重启服务重新登录: ```bash systemctl restart grade-monitor ``` #### 步骤5:查看调试HTML文件 ```bash cd ~/grade_monitor # 检查文件是否存在 ls -lh debug_page.html # 查看是否包含成绩表格 grep -i "gridtable\|课程名称\|成绩" debug_page.html | head -5 ``` ### 解决方案 **方案1:重新安装依赖并重启** ```bash cd ~/grade_monitor pip3 install -r requirements.txt systemctl restart grade-monitor tail -f monitor.log ``` **方案2:启用调试模式监控** ```bash # 编辑服务配置 sudo nano /etc/systemd/system/grade-monitor.service # 修改 ExecStart 行添加 --debug 参数 ExecStart=/usr/bin/python3 /home/yourusername/grade_monitor/monitor.py --debug # 重新加载并重启 sudo systemctl daemon-reload sudo systemctl restart grade-monitor tail -f ~/grade_monitor/monitor.log ``` **方案3:如果是会话过期** 最新版本会自动处理!代码会: 1. 检测到 "LOGIN_REQUIRED" 时自动重新登录 2. 记录日志:`[WARNING] 检测到会话过期,尝试重新登录...` 3. 重新登录后继续监控 **方案4:如果是网页结构变化** 程序会自动保存 HTML 到 `debug_page.html`,查看这个文件: ```bash # 查看 HTML 内容,确认是否有成绩表格 cat debug_page.html | grep -i "gridtable\|dataList" -A 10 ``` 当前支持的表格选择器: - `` - `
` - 任何包含"课程名称"或"成绩"关键词的表格 ## ⚠️ 问题二:"请不要过快点击"错误 ### 问题原因 学校WebVPN系统有严格的访问频率限制,短时间内多次访问会被拦截。 ### 解决方案 #### 1. 停止手动测试至少5分钟 ```bash # 如果在服务器上运行,请先停止程序 ps aux | grep monitor.py kill <进程ID> # 等待至少5分钟后再重新测试 ``` #### 2. 修改配置文件增加间隔 ```bash nano config.ini ``` 修改为: ```ini [monitor] # 将检查间隔改为5分钟(300秒)或更长 CHECK_INTERVAL = 300 # 增加请求延迟 REQUEST_DELAY = 15 # 增加重试间隔 RETRY_DELAY = 60 ``` #### 3. 使用正确的测试方式 ```bash # 测试前确保距离上次测试至少5分钟 python3 monitor.py --test # 如果还是被拦截,等10分钟后再试 ``` #### 4. 部署后不要频繁测试 ```bash # 部署systemd服务后,让它自动运行 sudo systemctl start grade-monitor # 只通过日志查看运行情况 tail -f monitor.log # 不要反复启停服务或手动测试 ``` ## 🔍 如何判断系统正常工作 ### 方法1:查看日志 ```bash tail -f ~/grade_monitor/monitor.log ``` 正常日志应该类似: ``` 2026-01-29 10:00:00 - INFO - 开始检查成绩变化... 2026-01-29 10:00:05 - INFO - 登录成功! 2026-01-29 10:00:10 - INFO - 成功获取成绩页面 2026-01-29 10:00:12 - INFO - 未发现新课程 2026-01-29 10:02:00 - INFO - 等待下次检查... ``` ### 方法2:查看保存的成绩文件 ```bash cat ~/.last_grade_content.txt ``` 如果文件包含完整的课程列表和GPA,说明系统工作正常。 ### 方法3:查看进程状态 ```bash ps aux | grep monitor.py ``` 如果有进程在运行,说明程序正在监控中。 ## 📝 调试流程 1. **启用调试模式运行一次测试:** ```bash cd ~/grade_monitor python3 monitor.py --test --debug ``` 2. **查看输出信息:** - 是否显示 "找到成绩表格"? - 是否显示 "找到 X 行成绩数据"? - 是否显示 "共解析到 X 门课程"? 3. **检查保存的文件:** ```bash # 如果生成了 debug_page.html ls -lh debug_page.html # 查看是否包含成绩表格 grep -A 5 "gridtable\|dataList" debug_page.html ``` 4. **如果是网页结构问题:** - 将 `debug_page.html` 发给开发者 - 或者自己检查 HTML 中的表格结构 --- # 常见问题解决 ## 💡 最佳实践 ### 测试阶段 1. **首次测试**:运行 `python3 monitor.py --test` 2. **等待5分钟** 3. **再次测试**:确认能正常获取成绩 4. **等待10分钟** 5. **部署服务**:配置systemd或使用tmux ### 运行阶段 1. **设置CHECK_INTERVAL为120秒或更长** 2. **让程序自动运行,不要手动干预** 3. **每天查看一次日志即可** 4. **不要频繁重启服务** ### 如果被持续拦截 1. **停止所有监控程序** 2. **等待至少30分钟** 3. **将CHECK_INTERVAL改为600秒(10分钟)** 4. **重新启动,让它慢慢运行** 5. **确认稳定后,再逐步减少间隔** ## 🛠️ 调试技巧 ### 查看实际响应内容 ```bash cat ~/grade_monitor/.debug_response.html ``` 如果文件包含"请不要过快点击",说明请求被拦截。 ### 检查登录状态 ```bash # 运行测试模式 python3 monitor.py --test # 查看是否成功登录 grep "登录成功" monitor.log ``` ### 测试网络连接 ```bash # 测试是否能访问学校网站 curl -I https://webvpn.neu.edu.cn # 测试SMTP邮件服务器 nc -zv smtp.163.com 465 ``` ## 🔧 常见问题FAQ ### Q1: 如何确认程序在运行? ```bash # 方法1:查看进程 ps aux | grep monitor.py # 方法2:查看日志最后几行 tail monitor.log # 方法3:查看文件修改时间 ls -lh monitor.log ``` ### Q2: 程序报错"请不要过快点击"怎么办? 编辑配置文件,增加检查间隔: ```bash nano config.ini # 修改 CHECK_INTERVAL 为更大的值(如300秒) ``` ### Q3: 如何在多台服务器部署? 每台服务器重复部署步骤,注意: 1. 每台服务器使用不同的监控账号(如果可能) 2. 适当增加 CHECK_INTERVAL 避免同时访问 3. 可以设置不同的邮件接收地址 ### Q4: 忘记 tmux 会话名怎么办? ```bash # 列出所有会话 tmux ls # 连接到第一个会话 tmux attach ``` ### Q5: 邮件发送失败怎么办? - 确认SMTP授权码正确(不是邮箱密码) - 检查服务器能否访问smtp.163.com(端口465) - 查看详细错误信息:`tail -f monitor.log` ```bash # 测试网络连接 telnet smtp.163.com 465 # 或 nc -zv smtp.163.com 465 ``` ### Q6: 权限不足怎么办? ```bash # 修改文件所有者 sudo chown -R username:username ~/grade_monitor # 修改执行权限 chmod +x ~/grade_monitor/*.sh ``` ## 💬 温馨提示 1. **成绩更新频率不高**:学校不会每分钟更新成绩,建议CHECK_INTERVAL设为120-300秒 2. **避免过度监控**:频繁访问可能被学校系统封禁IP 3. **合理设置间隔**:既能及时发现新成绩,又不会触发限流 4. **信任自动化**:部署后让程序自己运行,不需要频繁检查 --- # 服务管理 ## 🔄 重启服务 ### 使用 systemd ```bash # 停止服务 systemctl stop grade-monitor # 备份旧文件 cd ~/grade_monitor cp monitor.py monitor.py.backup # 如果需要更新文件 # tar -xzf ~/gpa_monitor.tar.gz -C ~/grade_monitor # 重启服务 systemctl restart grade-monitor # 查看实时日志 tail -f monitor.log # 或查看最近的日志(包含完整上下文) tail -n 100 monitor.log ``` ### 使用 tmux ```bash # 连接到会话 tmux attach -t grade_monitor # 停止程序(Ctrl+C) # 重新运行 source venv/bin/activate python3 monitor.py # 离开会话(Ctrl+B 然后 D) ``` ### 使用 nohup ```bash # 查找进程 ps aux | grep monitor.py # 停止进程 kill <进程ID> # 重新启动 cd ~/grade_monitor source venv/bin/activate nohup python3 monitor.py > output.log 2>&1 & ``` ## 📊 日志查看 ### 查看监控日志 ```bash # 实时查看 tail -f ~/grade_monitor/monitor.log # 查看最后N行 tail -n 50 ~/grade_monitor/monitor.log # 搜索关键词 grep "新增课程\|错误\|warning" ~/grade_monitor/monitor.log ``` ### 查看系统日志(systemd) ```bash # 实时查看 sudo journalctl -u grade-monitor -f # 查看最近1小时 sudo journalctl -u grade-monitor --since "1 hour ago" # 查看今天的日志 sudo journalctl -u grade-monitor --since today ``` ## 🔍 状态检查 ```bash # 检查服务状态(systemd) sudo systemctl status grade-monitor # 检查进程 ps aux | grep monitor.py # 检查最后一次检查时间 ls -lh ~/grade_monitor/monitor.log # 查看保存的成绩 cat ~/grade_monitor/.last_grade_content.txt ``` ## 📦 完整更新流程 ```bash # 1. 在本地打包 cd /mnt/e/50425/Documents/Github/GPA_Monitoring tar -czf gpa_monitor.tar.gz monitor.py config.ini requirements.txt setup_python.sh # 2. 上传到服务器 scp gpa_monitor.tar.gz user@server:~/ # 3. 在服务器上更新 ssh user@server systemctl stop grade-monitor cd ~/grade_monitor cp monitor.py monitor.py.backup.$(date +%Y%m%d) tar -xzf ~/gpa_monitor.tar.gz systemctl restart grade-monitor # 4. 验证 tail -f monitor.log ``` --- # 历史BUG修复记录 ## BUG #001: 邮件通知课程列表不正确 **修复日期:** 2026-01-21 **严重程度:** 高(数据不一致) **修复状态:** ✅ 已修复 ### 问题描述 **症状:** - 日志显示检测到2门新增课程: - 马克思主义基本原理 (A3505000018) - 软件需求分析与设计 (A0801050220) - 但邮件通知显示的是3门**完全不同**的课程: - C++程序设计 - 体育(三) 乒乓球 - 概率论与数理统计 ### 根本原因 代码逻辑错误: ```python # 错误的实现 if self.check_grade_changes(grade_info, grade_html): courses_file = self.script_dir / '.last_courses.txt' if courses_file.exists(): # ❌ 发送的是当前所有课程的前3门,而不是新增课程 self.send_email_notification(current_courses[:3]) ``` **问题分析:** 1. `check_grade_changes` 函数内部计算了新增课程列表 `new_courses` 2. 但函数只返回 `True/False`,**没有返回新增课程列表** 3. 主循环中使用了 `current_courses[:3]`(当前所有课程的前3门) 4. 导致邮件中显示的课程与实际新增的课程不一致 ### 修复方案 1. **修改函数签名**:返回元组 `(是否有变化: bool, 新增课程列表: list)` 2. **返回新增课程列表**:`return (True, new_courses)` 3. **更新调用代码**:使用真正的新增课程列表发送邮件 ### 修复效果 **修复前:** ``` 日志:检测到2门新增课程 邮件:显示3门完全不同的课程 ❌ ``` **修复后:** ``` 日志:检测到2门新增课程 邮件:准确显示这2门新增课程 ✅ ``` --- ## 📞 获取帮助 如果遇到问题: 1. 先运行诊断工具:`./diagnose.sh` 2. 查看本文档的故障排查部分 3. 查看 `monitor.log` 了解详细错误 4. 运行 `python3 monitor.py --test --debug` 测试 5. 检查 `debug_page.html` 了解实际响应 --- ## ✅ 部署检查清单 - [ ] 文件已上传到服务器 - [ ] config.ini配置正确(账号、密码、邮箱) - [ ] 运行setup_python.sh安装依赖 - [ ] 测试模式运行成功 - [ ] 成绩提取格式正确 - [ ] 配置后台运行(systemd/tmux) - [ ] 服务正常启动 - [ ] 日志输出正常 - [ ] 收到测试邮件 - [ ] 设置文件权限(chmod 600 config.ini) --- **文档版本:** v2.0 **最后更新:** 2026-01-29 **维护者:** GitHub Copilot