Compare commits
3 Commits
d1dc08a16d
...
bfa286318d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfa286318d | ||
|
|
4c41df3e39 | ||
|
|
2e0e4ea8c6 |
@@ -1,213 +0,0 @@
|
|||||||
# BUG修复:邮件通知课程列表不正确
|
|
||||||
|
|
||||||
## 问题描述
|
|
||||||
|
|
||||||
**症状:**
|
|
||||||
- 日志显示检测到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. 导致邮件中显示的课程与实际新增的课程不一致
|
|
||||||
|
|
||||||
### 举例说明
|
|
||||||
|
|
||||||
**场景:**
|
|
||||||
- 之前有6门课程:A、B、C、D、E、F
|
|
||||||
- 新增2门课程:G、H
|
|
||||||
- 当前总共8门课程:A、B、C、D、E、F、G、H
|
|
||||||
|
|
||||||
**错误行为:**
|
|
||||||
- 日志显示:新增2门(G、H)✓ 正确
|
|
||||||
- 邮件显示:A、B、C(前3门)❌ 错误
|
|
||||||
|
|
||||||
**期望行为:**
|
|
||||||
- 邮件显示:G、H ✓ 正确
|
|
||||||
|
|
||||||
## 修复方案
|
|
||||||
|
|
||||||
### 1. 修改 `check_grade_changes` 函数签名
|
|
||||||
|
|
||||||
```python
|
|
||||||
# 修改前
|
|
||||||
def check_grade_changes(self, current_content: str, current_html: str = None) -> bool:
|
|
||||||
|
|
||||||
# 修改后
|
|
||||||
def check_grade_changes(self, current_content: str, current_html: str = None) -> tuple:
|
|
||||||
"""检查成绩是否有变化
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
tuple: (是否有变化: bool, 新增课程列表: list)
|
|
||||||
"""
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 返回新增课程列表
|
|
||||||
|
|
||||||
```python
|
|
||||||
# 修改前
|
|
||||||
if new_courses:
|
|
||||||
# ... 记录日志 ...
|
|
||||||
return True
|
|
||||||
|
|
||||||
# 修改后
|
|
||||||
if new_courses:
|
|
||||||
# ... 记录日志 ...
|
|
||||||
return (True, new_courses) # 返回元组
|
|
||||||
|
|
||||||
# 其他情况
|
|
||||||
return (False, []) # 无变化
|
|
||||||
return (True, []) # 有变化但无新增课程(成绩更新)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 更新调用代码
|
|
||||||
|
|
||||||
```python
|
|
||||||
# 修改前
|
|
||||||
if self.check_grade_changes(grade_info, grade_html):
|
|
||||||
self.send_email_notification(current_courses[:3]) # ❌ 错误
|
|
||||||
|
|
||||||
# 修改后
|
|
||||||
has_changes, new_courses = self.check_grade_changes(grade_info, grade_html)
|
|
||||||
|
|
||||||
if has_changes:
|
|
||||||
if new_courses:
|
|
||||||
# 有新增课程,发送真正的新增课程列表
|
|
||||||
self.send_email_notification(new_courses) # ✅ 正确
|
|
||||||
else:
|
|
||||||
# 没有新增课程但内容变化(成绩更新),发送通用通知
|
|
||||||
self.send_email_notification()
|
|
||||||
```
|
|
||||||
|
|
||||||
## 修复效果
|
|
||||||
|
|
||||||
### 修复前
|
|
||||||
```
|
|
||||||
日志:
|
|
||||||
[INFO] ✓ 检测到新增课程成绩!共 2 门
|
|
||||||
[INFO] 1. [2025-2026 秋季] 马克思主义基本原理 (A3505000018)
|
|
||||||
[INFO] 2. [2025-2026 秋季] 软件需求分析与设计 (A0801050220)
|
|
||||||
|
|
||||||
邮件:
|
|
||||||
新增课程(共3门):
|
|
||||||
- 2025-2026 秋季 C++程序设计 ❌ 错误!
|
|
||||||
- 2025-2026 秋季 体育(三) 乒乓球 ❌ 错误!
|
|
||||||
- 2025-2026 秋季 概率论与数理统计 ❌ 错误!
|
|
||||||
```
|
|
||||||
|
|
||||||
### 修复后
|
|
||||||
```
|
|
||||||
日志:
|
|
||||||
[INFO] ✓ 检测到新增课程成绩!共 2 门
|
|
||||||
[INFO] 1. [2025-2026 秋季] 马克思主义基本原理 (A3505000018)
|
|
||||||
[INFO] 2. [2025-2026 秋季] 软件需求分析与设计 (A0801050220)
|
|
||||||
|
|
||||||
邮件:
|
|
||||||
新增课程(共2门):
|
|
||||||
- 2025-2026 秋季 马克思主义基本原理 ✅ 正确!
|
|
||||||
- 2025-2026 秋季 软件需求分析与设计 ✅ 正确!
|
|
||||||
```
|
|
||||||
|
|
||||||
## 测试建议
|
|
||||||
|
|
||||||
### 1. 单元测试场景
|
|
||||||
|
|
||||||
**场景1:新增课程**
|
|
||||||
- 之前:3门课程
|
|
||||||
- 现在:5门课程(新增2门)
|
|
||||||
- 期望:邮件显示新增的2门
|
|
||||||
|
|
||||||
**场景2:成绩更新**
|
|
||||||
- 之前:5门课程
|
|
||||||
- 现在:5门课程(某门成绩变化)
|
|
||||||
- 期望:邮件显示通用通知
|
|
||||||
|
|
||||||
**场景3:无变化**
|
|
||||||
- 之前:5门课程
|
|
||||||
- 现在:5门课程(完全相同)
|
|
||||||
- 期望:不发送邮件
|
|
||||||
|
|
||||||
### 2. 集成测试
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 删除历史记录(模拟首次运行)
|
|
||||||
cd ~/grade_monitor
|
|
||||||
rm .last_*
|
|
||||||
|
|
||||||
# 2. 运行测试
|
|
||||||
python3 monitor.py --test
|
|
||||||
|
|
||||||
# 3. 再次运行(模拟检测到变化)
|
|
||||||
# 手动编辑 .last_courses.txt,删除几行
|
|
||||||
python3 monitor.py --test
|
|
||||||
|
|
||||||
# 4. 检查邮件内容是否正确
|
|
||||||
```
|
|
||||||
|
|
||||||
## 影响评估
|
|
||||||
|
|
||||||
### 向后兼容性
|
|
||||||
- ✅ 完全兼容:函数返回元组,Python 会自动解包
|
|
||||||
- ✅ 不影响测试模式:test_fetch 不调用此函数
|
|
||||||
- ✅ 不影响旧版数据:历史文件格式不变
|
|
||||||
|
|
||||||
### 风险等级
|
|
||||||
- 🟢 **低风险**:仅修改返回值类型
|
|
||||||
- 🟢 所有调用点已更新
|
|
||||||
- 🟢 已通过语法检查
|
|
||||||
|
|
||||||
## 部署步骤
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 本地打包
|
|
||||||
cd /mnt/e/50425/Documents/Github/GPA_Monitoring
|
|
||||||
./打包.sh
|
|
||||||
|
|
||||||
# 2. 上传到服务器
|
|
||||||
scp gpa_monitor.tar.gz user@server:~/
|
|
||||||
|
|
||||||
# 3. 服务器上更新
|
|
||||||
systemctl stop grade-monitor
|
|
||||||
cd ~/grade_monitor
|
|
||||||
cp monitor.py monitor.py.backup.$(date +%Y%m%d_%H%M%S)
|
|
||||||
tar -xzf ~/gpa_monitor.tar.gz
|
|
||||||
systemctl restart grade-monitor
|
|
||||||
|
|
||||||
# 4. 验证
|
|
||||||
tail -f monitor.log
|
|
||||||
```
|
|
||||||
|
|
||||||
## 后续优化建议
|
|
||||||
|
|
||||||
1. **添加单元测试** - 测试 `check_grade_changes` 函数
|
|
||||||
2. **记录邮件内容** - 在日志中记录发送的课程列表
|
|
||||||
3. **邮件确认机制** - 发送成功后记录一份副本
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**BUG编号:** #001
|
|
||||||
**严重程度:** 高(数据不一致)
|
|
||||||
**修复日期:** 2026-01-21
|
|
||||||
**修复人员:** GitHub Copilot
|
|
||||||
**测试状态:** 待用户验证
|
|
||||||
408
Debian服务器部署指南.md
408
Debian服务器部署指南.md
@@ -1,408 +0,0 @@
|
|||||||
# 成绩监控系统 - Debian服务器部署指南
|
|
||||||
|
|
||||||
## 📦 项目文件说明
|
|
||||||
|
|
||||||
### 必需文件(需要上传到服务器)
|
|
||||||
|
|
||||||
| 文件名 | 用途 | 何时使用 |
|
|
||||||
|--------|------|----------|
|
|
||||||
| `monitor.py` | **主程序** | 运行监控的核心文件 |
|
|
||||||
| `config.ini` | **配置文件** | 包含账号密码、邮箱配置(⚠️ 敏感文件) |
|
|
||||||
| `requirements.txt` | **Python依赖列表** | 安装Python包时使用 |
|
|
||||||
| `setup_python.sh` | **环境安装脚本** | 首次部署时执行,安装所有依赖 |
|
|
||||||
| `grade-monitor.service` | **systemd服务配置** | 设置开机自启和后台运行 |
|
|
||||||
|
|
||||||
### 可选文件(参考文档)
|
|
||||||
|
|
||||||
| 文件名 | 用途 |
|
|
||||||
|--------|------|
|
|
||||||
| `config(模板).ini` | 配置文件模板,新用户参考 |
|
|
||||||
| `readme.md` | 项目说明文档 |
|
|
||||||
| `部署.md` | 详细部署步骤 |
|
|
||||||
| `常见问题解决.md` | 常见问题和解决方案 |
|
|
||||||
|
|
||||||
### 不需要的文件(不要上传)
|
|
||||||
|
|
||||||
- `venv/` - 虚拟环境(服务器上重新创建)
|
|
||||||
- `.git/` - Git仓库(可选)
|
|
||||||
- `.last_*` - 运行时生成的缓存文件
|
|
||||||
- `monitor.log` - 运行时生成的日志文件
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Debian服务器部署步骤
|
|
||||||
|
|
||||||
### 第一步:准备文件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 在本地打包必需文件
|
|
||||||
cd /mnt/e/50425/Documents/Github/GPA_Monitoring
|
|
||||||
|
|
||||||
# 创建压缩包(只包含必需文件)
|
|
||||||
tar -czf gpa_monitor.tar.gz \
|
|
||||||
monitor.py \
|
|
||||||
config.ini \
|
|
||||||
requirements.txt \
|
|
||||||
setup_python.sh \
|
|
||||||
grade-monitor.service \
|
|
||||||
readme.md
|
|
||||||
|
|
||||||
# 查看压缩包内容
|
|
||||||
tar -tzf gpa_monitor.tar.gz
|
|
||||||
```
|
|
||||||
|
|
||||||
### 第二步:上传到服务器
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 方法1:使用 scp
|
|
||||||
scp gpa_monitor.tar.gz 用户名@服务器IP:/home/用户名/
|
|
||||||
|
|
||||||
# 方法2:使用 rsync(推荐)
|
|
||||||
rsync -avz gpa_monitor.tar.gz 用户名@服务器IP:/home/用户名/
|
|
||||||
|
|
||||||
# 方法3:使用 sftp
|
|
||||||
sftp 用户名@服务器IP
|
|
||||||
put gpa_monitor.tar.gz
|
|
||||||
```
|
|
||||||
|
|
||||||
### 第三步:在服务器上解压并安装
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 登录到Debian服务器
|
|
||||||
ssh 用户名@服务器IP
|
|
||||||
|
|
||||||
# 解压文件
|
|
||||||
cd ~
|
|
||||||
tar -xzf gpa_monitor.tar.gz
|
|
||||||
cd gpa_monitor # 或者你解压到的目录
|
|
||||||
|
|
||||||
# 给脚本添加执行权限
|
|
||||||
chmod +x setup_python.sh
|
|
||||||
|
|
||||||
# 运行安装脚本(会自动安装Python、创建虚拟环境、安装依赖)
|
|
||||||
./setup_python.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### 第四步:检查配置文件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 编辑配置文件(如果需要修改)
|
|
||||||
nano config.ini
|
|
||||||
|
|
||||||
# 确认配置正确:
|
|
||||||
# - USERNAME 和 PASSWORD(学号和密码)
|
|
||||||
# - 邮箱配置(SENDER_EMAIL、SENDER_PASSWORD、RECEIVER_EMAIL)
|
|
||||||
# - CHECK_INTERVAL(建议120秒以上)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 第五步:测试运行
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 激活虚拟环境
|
|
||||||
source venv/bin/activate
|
|
||||||
|
|
||||||
# 测试运行(获取一次成绩,不进行监控)
|
|
||||||
python3 monitor.py --test
|
|
||||||
|
|
||||||
# 如果测试成功,运行正式监控
|
|
||||||
python3 monitor.py
|
|
||||||
# 按 Ctrl+C 停止
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 设置后台运行(三选一)
|
|
||||||
|
|
||||||
### 方案A:使用 tmux(推荐,简单易用)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 安装 tmux(如果没有)
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install tmux
|
|
||||||
|
|
||||||
# 2. 创建会话并运行
|
|
||||||
tmux new -s grade_monitor
|
|
||||||
source venv/bin/activate
|
|
||||||
python3 monitor.py
|
|
||||||
|
|
||||||
# 3. 离开会话(程序继续运行)
|
|
||||||
# 按 Ctrl+B,然后按 D
|
|
||||||
|
|
||||||
# 4. 重新连接查看
|
|
||||||
tmux attach -t grade_monitor
|
|
||||||
|
|
||||||
# 5. 查看所有会话
|
|
||||||
tmux ls
|
|
||||||
```
|
|
||||||
|
|
||||||
**tmux 使用时机:**
|
|
||||||
- ✅ 测试阶段使用
|
|
||||||
- ✅ 需要随时查看程序输出
|
|
||||||
- ✅ 临时运行,不需要开机自启
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 方案B:使用 systemd 服务(推荐,生产环境)
|
|
||||||
|
|
||||||
**`grade-monitor.service` 文件用途:**
|
|
||||||
这是 systemd 服务配置文件,告诉系统如何启动、管理和自动重启你的程序。
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 编辑服务文件,修改用户名和路径
|
|
||||||
nano grade-monitor.service
|
|
||||||
|
|
||||||
# 确保这些路径正确:
|
|
||||||
# User=你的用户名
|
|
||||||
# WorkingDirectory=/home/你的用户名/gpa_monitor
|
|
||||||
# ExecStart=/home/你的用户名/gpa_monitor/venv/bin/python3 /home/你的用户名/gpa_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
|
|
||||||
|
|
||||||
# 查看日志
|
|
||||||
journalctl -u grade-monitor -f
|
|
||||||
|
|
||||||
# 开机自启
|
|
||||||
sudo systemctl enable grade-monitor
|
|
||||||
|
|
||||||
# 禁用自启
|
|
||||||
sudo systemctl disable grade-monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
**systemd 使用时机:**
|
|
||||||
- ✅ 生产环境长期运行
|
|
||||||
- ✅ 需要开机自启动
|
|
||||||
- ✅ 程序崩溃后自动重启
|
|
||||||
- ✅ 系统化管理
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 方案C:使用 nohup(最简单,但不推荐)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 后台运行
|
|
||||||
source venv/bin/activate
|
|
||||||
nohup python3 monitor.py > output.log 2>&1 &
|
|
||||||
|
|
||||||
# 查看进程
|
|
||||||
ps aux | grep monitor.py
|
|
||||||
|
|
||||||
# 停止程序
|
|
||||||
pkill -f monitor.py
|
|
||||||
```
|
|
||||||
|
|
||||||
**nohup 使用时机:**
|
|
||||||
- ✅ 临时快速运行
|
|
||||||
- ❌ 不适合长期运行
|
|
||||||
- ❌ 程序崩溃不会自动重启
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 监控和维护
|
|
||||||
|
|
||||||
### 查看日志
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 查看监控日志(程序自己的日志)
|
|
||||||
tail -f ~/gpa_monitor/monitor.log
|
|
||||||
|
|
||||||
# 查看最后100行
|
|
||||||
tail -n 100 ~/gpa_monitor/monitor.log
|
|
||||||
|
|
||||||
# 搜索关键词
|
|
||||||
grep "新增课程" ~/gpa_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 ~/gpa_monitor/monitor.log
|
|
||||||
|
|
||||||
# 方法3:systemd状态(如果用systemd)
|
|
||||||
sudo systemctl status grade-monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
### 更新程序
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 停止程序
|
|
||||||
# tmux: Ctrl+C 或 tmux kill-session -t grade_monitor
|
|
||||||
# systemd: sudo systemctl stop grade-monitor
|
|
||||||
|
|
||||||
# 2. 备份配置
|
|
||||||
cp config.ini config.ini.backup
|
|
||||||
|
|
||||||
# 3. 上传新版本文件并解压
|
|
||||||
|
|
||||||
# 4. 恢复配置
|
|
||||||
cp config.ini.backup config.ini
|
|
||||||
|
|
||||||
# 5. 重启程序
|
|
||||||
# tmux: 重新运行
|
|
||||||
# systemd: sudo systemctl restart 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
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ❓ 常见问题
|
|
||||||
|
|
||||||
### 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秒)
|
|
||||||
CHECK_INTERVAL = 300
|
|
||||||
|
|
||||||
# 重启程序
|
|
||||||
```
|
|
||||||
|
|
||||||
### Q3: 如何在多台服务器部署?
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 每台服务器重复部署步骤,注意:
|
|
||||||
# 1. 每台服务器使用不同的监控账号(如果可能)
|
|
||||||
# 2. 适当增加 CHECK_INTERVAL 避免同时访问
|
|
||||||
# 3. 可以设置不同的邮件接收地址
|
|
||||||
```
|
|
||||||
|
|
||||||
### Q4: 忘记 tmux 会话名怎么办?
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 列出所有会话
|
|
||||||
tmux ls
|
|
||||||
|
|
||||||
# 连接到第一个会话
|
|
||||||
tmux attach
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 快速命令参考
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# === 部署 ===
|
|
||||||
tar -xzf gpa_monitor.tar.gz
|
|
||||||
cd gpa_monitor
|
|
||||||
chmod +x setup_python.sh
|
|
||||||
./setup_python.sh
|
|
||||||
|
|
||||||
# === 运行 ===
|
|
||||||
# 测试
|
|
||||||
source venv/bin/activate && python3 monitor.py --test
|
|
||||||
|
|
||||||
# tmux运行
|
|
||||||
tmux new -s grade_monitor
|
|
||||||
source venv/bin/activate && python3 monitor.py
|
|
||||||
|
|
||||||
# systemd运行
|
|
||||||
sudo cp grade-monitor.service /etc/systemd/system/
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
sudo systemctl start grade-monitor
|
|
||||||
sudo systemctl enable grade-monitor
|
|
||||||
|
|
||||||
# === 监控 ===
|
|
||||||
# 查看日志
|
|
||||||
tail -f monitor.log
|
|
||||||
|
|
||||||
# 查看状态
|
|
||||||
sudo systemctl status grade-monitor
|
|
||||||
|
|
||||||
# === 停止 ===
|
|
||||||
# tmux: Ctrl+C
|
|
||||||
# systemd: sudo systemctl stop grade-monitor
|
|
||||||
# nohup: pkill -f monitor.py
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 获取帮助
|
|
||||||
|
|
||||||
- 查看项目 README: `cat readme.md`
|
|
||||||
- 查看常见问题: `cat 常见问题解决.md`
|
|
||||||
- 查看详细部署: `cat 部署.md`
|
|
||||||
- 查看程序帮助: `python3 monitor.py --help`
|
|
||||||
996
docs/完整使用文档.md
Normal file
996
docs/完整使用文档.md
Normal file
@@ -0,0 +1,996 @@
|
|||||||
|
# 成绩监控系统 - 完整使用文档
|
||||||
|
|
||||||
|
> **最后更新:** 2026-01-29
|
||||||
|
> **版本:** v2.0 - 自动会话恢复版
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📑 目录
|
||||||
|
|
||||||
|
1. [服务器部署指南](#服务器部署指南)
|
||||||
|
2. [快速更新指南](#快速更新指南)
|
||||||
|
3. [故障排查指南](#故障排查指南)
|
||||||
|
4. [常见问题解决](#常见问题解决)
|
||||||
|
5. [服务管理](#服务管理)
|
||||||
|
6. [历史BUG修复记录](#历史bug修复记录)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 服务器部署指南
|
||||||
|
|
||||||
|
## 📋 前置要求
|
||||||
|
|
||||||
|
- Linux服务器(Debian/Ubuntu/CentOS等)
|
||||||
|
- Python 3.7+
|
||||||
|
- 服务器能访问外网
|
||||||
|
- SSH访问权限
|
||||||
|
|
||||||
|
## 📦 项目文件说明
|
||||||
|
|
||||||
|
### 必需文件(需要上传到服务器)
|
||||||
|
|
||||||
|
| 文件名 | 用途 | 何时使用 |
|
||||||
|
|--------|------|----------|
|
||||||
|
| `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
|
||||||
|
|
||||||
|
# 创建压缩包(只包含必需文件)
|
||||||
|
tar -czf gpa_monitor.tar.gz \
|
||||||
|
monitor.py \
|
||||||
|
config.ini \
|
||||||
|
requirements.txt \
|
||||||
|
setup_python.sh \
|
||||||
|
diagnose.sh \
|
||||||
|
grade-monitor.service \
|
||||||
|
README.md
|
||||||
|
|
||||||
|
# 查看压缩包内容
|
||||||
|
tar -tzf gpa_monitor.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
### 第二步:上传到服务器
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 方法1:使用 scp
|
||||||
|
scp gpa_monitor.tar.gz 用户名@服务器IP:/home/用户名/
|
||||||
|
|
||||||
|
# 方法2:使用 rsync(推荐)
|
||||||
|
rsync -avz gpa_monitor.tar.gz 用户名@服务器IP:/home/用户名/
|
||||||
|
|
||||||
|
# 方法3:使用 sftp
|
||||||
|
sftp 用户名@服务器IP
|
||||||
|
put gpa_monitor.tar.gz
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
### 第三步:在服务器上解压并安装
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 登录到服务器
|
||||||
|
ssh 用户名@服务器IP
|
||||||
|
|
||||||
|
# 解压文件
|
||||||
|
cd ~
|
||||||
|
tar -xzf gpa_monitor.tar.gz
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 设置后台运行
|
||||||
|
|
||||||
|
### 方案A:使用 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
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方案B:使用 tmux(简单易用)
|
||||||
|
|
||||||
|
**优点:** 简单、可随时查看输出、适合测试阶段
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 安装 tmux(如果没有)
|
||||||
|
sudo apt update && sudo apt install tmux
|
||||||
|
|
||||||
|
# 2. 创建会话并运行
|
||||||
|
tmux new -s grade_monitor
|
||||||
|
source venv/bin/activate
|
||||||
|
python3 monitor.py
|
||||||
|
|
||||||
|
# 3. 离开会话(程序继续运行)
|
||||||
|
# 按 Ctrl+B,然后按 D
|
||||||
|
|
||||||
|
# 4. 重新连接查看
|
||||||
|
tmux attach -t grade_monitor
|
||||||
|
|
||||||
|
# 5. 查看所有会话
|
||||||
|
tmux ls
|
||||||
|
|
||||||
|
# 6. 关闭会话
|
||||||
|
tmux kill-session -t grade_monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方案C:使用 nohup(最简单)
|
||||||
|
|
||||||
|
**优点:** 快速、无需额外工具
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 后台运行
|
||||||
|
source venv/bin/activate
|
||||||
|
nohup python3 monitor.py > output.log 2>&1 &
|
||||||
|
|
||||||
|
# 查看进程
|
||||||
|
ps aux | grep monitor.py
|
||||||
|
|
||||||
|
# 停止程序
|
||||||
|
pkill -f monitor.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 监控和维护
|
||||||
|
|
||||||
|
### 查看日志
|
||||||
|
|
||||||
|
```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
|
||||||
|
```
|
||||||
|
|
||||||
|
当前支持的表格选择器:
|
||||||
|
- `<table class="gridtable">`
|
||||||
|
- `<table id="dataList">`
|
||||||
|
- 任何包含"课程名称"或"成绩"关键词的表格
|
||||||
|
|
||||||
|
## ⚠️ 问题二:"请不要过快点击"错误
|
||||||
|
|
||||||
|
### 问题原因
|
||||||
|
学校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
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
# 问题修复说明
|
|
||||||
|
|
||||||
## 问题描述
|
|
||||||
|
|
||||||
服务器运行时出现以下错误:
|
|
||||||
```
|
|
||||||
[WARNING] 未能提取到成绩信息,返回原始文本
|
|
||||||
[INFO] 成绩无变化(共 0 门课程)
|
|
||||||
```
|
|
||||||
|
|
||||||
## 根本原因
|
|
||||||
|
|
||||||
成绩提取函数 `extract_grade_info` 在某些情况下无法正确解析HTML页面,返回原始HTML文本,导致 `parse_courses` 函数无法从原始HTML中提取课程信息。
|
|
||||||
|
|
||||||
可能的具体原因包括:
|
|
||||||
1. BeautifulSoup 库未安装
|
|
||||||
2. 登录会话失效,返回的是登录页面
|
|
||||||
3. 学校网页结构发生变化
|
|
||||||
4. 网络问题导致获取的HTML不完整
|
|
||||||
|
|
||||||
## 修复内容
|
|
||||||
|
|
||||||
### 1. 改进 `extract_grade_info` 函数 (monitor.py 第286-370行)
|
|
||||||
|
|
||||||
**新增功能:**
|
|
||||||
- ✅ 检测登录页面,返回特殊标记 `LOGIN_REQUIRED`
|
|
||||||
- ✅ 支持多种表格选择器(`gridtable`, `dataList`, 关键词搜索)
|
|
||||||
- ✅ 添加详细的调试日志(表头、行数等)
|
|
||||||
- ✅ 自动保存问题HTML到 `debug_page.html` 便于排查
|
|
||||||
- ✅ 提供成功提取的反馈信息
|
|
||||||
|
|
||||||
**改进代码片段:**
|
|
||||||
```python
|
|
||||||
# 检查是否是登录页面
|
|
||||||
if soup.find('input', {'name': 'username'}) or soup.find('input', {'name': 'password'}):
|
|
||||||
logger.error("检测到登录页面,可能需要重新登录")
|
|
||||||
return "LOGIN_REQUIRED"
|
|
||||||
|
|
||||||
# 尝试多种方式查找成绩表格
|
|
||||||
table = soup.find('table', {'class': 'gridtable'})
|
|
||||||
if not table:
|
|
||||||
table = soup.find('table', {'id': 'dataList'})
|
|
||||||
if not table:
|
|
||||||
# 尝试查找任何包含成绩相关标题的表格
|
|
||||||
for tbl in soup.find_all('table'):
|
|
||||||
headers = tbl.find_all('th')
|
|
||||||
if headers and any('课程名称' in th.get_text() or '成绩' in th.get_text() for th in headers):
|
|
||||||
table = tbl
|
|
||||||
logger.info("通过表头关键词找到成绩表格")
|
|
||||||
break
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 改进 `parse_courses` 函数 (monitor.py 第347-378行)
|
|
||||||
|
|
||||||
**新增功能:**
|
|
||||||
- ✅ 检测 `LOGIN_REQUIRED` 标记
|
|
||||||
- ✅ 检测未解析的原始HTML
|
|
||||||
- ✅ 添加详细的解析日志
|
|
||||||
- ✅ 统计解析的课程数量
|
|
||||||
|
|
||||||
**改进代码片段:**
|
|
||||||
```python
|
|
||||||
# 检查是否需要重新登录
|
|
||||||
if grade_text == "LOGIN_REQUIRED":
|
|
||||||
logger.warning("检测到登录失效,需要重新登录")
|
|
||||||
return []
|
|
||||||
|
|
||||||
# 检查是否是原始HTML(未成功解析的标记)
|
|
||||||
if '<html' in grade_text.lower() or '<body' in grade_text.lower():
|
|
||||||
logger.warning("检测到未解析的HTML内容,成绩提取可能失败")
|
|
||||||
logger.debug(f"文本前100字符: {grade_text[:100]}")
|
|
||||||
return []
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 添加调试模式 (monitor.py 第743-797行)
|
|
||||||
|
|
||||||
**新增命令行参数:**
|
|
||||||
```bash
|
|
||||||
python3 monitor.py --debug # 启用详细日志
|
|
||||||
```
|
|
||||||
|
|
||||||
**功能:**
|
|
||||||
- 显示详细的调试信息
|
|
||||||
- 帮助快速定位问题
|
|
||||||
- 不影响正常运行模式
|
|
||||||
|
|
||||||
### 4. 创建诊断工具
|
|
||||||
|
|
||||||
**新增文件:**
|
|
||||||
1. **diagnose.sh** - 自动诊断脚本
|
|
||||||
- 检查依赖库安装
|
|
||||||
- 运行测试并分析结果
|
|
||||||
- 提供修复建议
|
|
||||||
|
|
||||||
2. **故障排查指南.md** - 详细的排查文档
|
|
||||||
- 常见问题及解决方案
|
|
||||||
- 调试流程说明
|
|
||||||
- 联系支持信息
|
|
||||||
|
|
||||||
3. **更新 常见问题解决.md** - 添加新问题说明
|
|
||||||
4. **更新 readme.md** - 添加快速诊断指引
|
|
||||||
|
|
||||||
## 使用方法
|
|
||||||
|
|
||||||
### 方式1:自动诊断(推荐)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/grade_monitor
|
|
||||||
chmod +x diagnose.sh
|
|
||||||
./diagnose.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方式2:手动调试
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 检查依赖
|
|
||||||
pip3 install -r requirements.txt
|
|
||||||
|
|
||||||
# 2. 运行调试模式
|
|
||||||
python3 monitor.py --test --debug
|
|
||||||
|
|
||||||
# 3. 查看输出
|
|
||||||
cat .last_grade_content.txt
|
|
||||||
cat debug_page.html | head -50
|
|
||||||
|
|
||||||
# 4. 如果正常,重启服务
|
|
||||||
systemctl restart grade-monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方式3:启用服务调试模式
|
|
||||||
|
|
||||||
编辑服务配置:
|
|
||||||
```bash
|
|
||||||
sudo nano /etc/systemd/system/grade-monitor.service
|
|
||||||
```
|
|
||||||
|
|
||||||
修改启动命令:
|
|
||||||
```ini
|
|
||||||
ExecStart=/usr/bin/python3 /home/yourusername/grade_monitor/monitor.py --debug
|
|
||||||
```
|
|
||||||
|
|
||||||
重新加载:
|
|
||||||
```bash
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
sudo systemctl restart grade-monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
## 预期效果
|
|
||||||
|
|
||||||
### 正常运行时的日志
|
|
||||||
```
|
|
||||||
[DEBUG] 找到总平均绩点: 总平均绩点:3.85
|
|
||||||
[DEBUG] 找到成绩表格
|
|
||||||
[DEBUG] 表头: ['学年学期', '课程代码', '课程序号', '课程名称', ...]
|
|
||||||
[DEBUG] 找到 15 行成绩数据
|
|
||||||
[INFO] 成功提取成绩信息,共 17 行
|
|
||||||
[DEBUG] 开始解析成绩,共 17 行
|
|
||||||
[DEBUG] 解析到课程: 高等数学A(1)
|
|
||||||
[DEBUG] 解析到课程: 线性代数
|
|
||||||
...
|
|
||||||
[INFO] 共解析到 15 门课程
|
|
||||||
[INFO] 成绩无变化(共 15 门课程)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 出错时的日志
|
|
||||||
```
|
|
||||||
[WARNING] 未找到成绩表格
|
|
||||||
[WARNING] 未能提取到成绩信息,页面可能结构异常
|
|
||||||
[INFO] 已保存HTML到 /home/user/grade_monitor/debug_page.html 供调试
|
|
||||||
[WARNING] 检测到未解析的HTML内容,成绩提取可能失败
|
|
||||||
[DEBUG] 文本前100字符: <!DOCTYPE html><html><head>...
|
|
||||||
[INFO] 共解析到 0 门课程
|
|
||||||
```
|
|
||||||
|
|
||||||
## 优势
|
|
||||||
|
|
||||||
1. **更好的错误提示** - 明确告知问题原因
|
|
||||||
2. **自动保存调试信息** - debug_page.html 便于排查
|
|
||||||
3. **灵活的表格查找** - 支持多种网页结构
|
|
||||||
4. **详细的日志** - 方便追踪每一步
|
|
||||||
5. **完善的文档** - 提供多种解决方案
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
1. **不要过度使用调试模式** - 生产环境可能不需要
|
|
||||||
2. **定期检查 debug_page.html** - 了解实际获取的内容
|
|
||||||
3. **及时更新表格选择器** - 如果学校网页结构变化
|
|
||||||
4. **保护敏感信息** - debug_page.html 可能包含个人信息
|
|
||||||
|
|
||||||
## 下一步
|
|
||||||
|
|
||||||
如果问题仍未解决:
|
|
||||||
1. 查看 `debug_page.html` 的实际内容
|
|
||||||
2. 检查HTML中的表格结构
|
|
||||||
3. 可能需要调整 `extract_grade_info` 中的选择器
|
|
||||||
4. 咨询开发者或提交 Issue
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**版本:** 2026-01-21
|
|
||||||
**修复人员:** GitHub Copilot
|
|
||||||
**测试状态:** 待用户测试确认
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
# 修复说明 - 2026年1月22日
|
|
||||||
|
|
||||||
## 修复的问题
|
|
||||||
|
|
||||||
### 1. 日志重复输出问题
|
|
||||||
**现象**:每条日志都会输出两次
|
|
||||||
|
|
||||||
**原因**:`logging.basicConfig()` 配置会在模块每次被导入时重复添加处理器,导致日志重复输出。
|
|
||||||
|
|
||||||
**解决方案**:
|
|
||||||
- 使用 `if not logger.handlers:` 检查,确保处理器只被添加一次
|
|
||||||
- 设置 `logger.propagate = False` 防止日志传播到根记录器
|
|
||||||
- 使用显式的logger配置替代 `basicConfig`
|
|
||||||
|
|
||||||
### 2. 连续异常时自动重新登录
|
|
||||||
**现象**:当连续多次出现解析失败、获取页面失败或网络错误时,程序不会尝试重新登录,导致持续失败。
|
|
||||||
|
|
||||||
**解决方案**:
|
|
||||||
在以下场景达到3次连续失败时,自动触发重新登录:
|
|
||||||
|
|
||||||
1. **获取成绩页面失败**
|
|
||||||
- 连续3次失败 → 尝试重新登录
|
|
||||||
- 登录成功 → 重置错误计数,继续监控
|
|
||||||
- 登录失败 → 继续累积错误计数
|
|
||||||
|
|
||||||
2. **网络错误(页面过短)**
|
|
||||||
- 连续3次网络错误 → 尝试重新登录
|
|
||||||
- 登录成功 → 重置错误计数
|
|
||||||
- 登录失败 → 继续累积错误计数
|
|
||||||
|
|
||||||
3. **解析课程失败(0门课程)**
|
|
||||||
- 连续3次解析失败 → 尝试重新登录
|
|
||||||
- 登录成功 → 重置错误计数
|
|
||||||
- 登录失败 → 发送通知,可能需要人工介入
|
|
||||||
|
|
||||||
## 技术细节
|
|
||||||
|
|
||||||
### 日志配置改进
|
|
||||||
```python
|
|
||||||
# 旧代码
|
|
||||||
logging.basicConfig(...)
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# 新代码
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
if not logger.handlers:
|
|
||||||
# 配置处理器
|
|
||||||
logger.propagate = False
|
|
||||||
```
|
|
||||||
|
|
||||||
### 重新登录逻辑
|
|
||||||
```python
|
|
||||||
if consecutive_errors >= 3:
|
|
||||||
logger.warning("⚠️ 尝试重新登录以解决问题...")
|
|
||||||
if self.login():
|
|
||||||
logger.info("✓ 重新登录成功,重置错误计数")
|
|
||||||
consecutive_errors = 0
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
logger.error("✗ 重新登录失败")
|
|
||||||
```
|
|
||||||
|
|
||||||
## 使用建议
|
|
||||||
|
|
||||||
1. **重启服务**:修改后需要重启服务使改动生效
|
|
||||||
```bash
|
|
||||||
sudo systemctl restart grade-monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **查看日志**:确认日志不再重复
|
|
||||||
```bash
|
|
||||||
sudo journalctl -u grade-monitor -f
|
|
||||||
# 或
|
|
||||||
tail -f monitor.log
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **监控效果**:
|
|
||||||
- 日志应该只输出一次
|
|
||||||
- 连续3次异常会自动尝试重新登录
|
|
||||||
- 重新登录成功后会显示 "✓ 重新登录成功"
|
|
||||||
|
|
||||||
## 预期效果
|
|
||||||
|
|
||||||
- ✅ 日志不再重复输出
|
|
||||||
- ✅ 连续3次异常自动重新登录
|
|
||||||
- ✅ 重新登录成功后重置错误计数
|
|
||||||
- ✅ 减少因登录会话过期导致的持续失败
|
|
||||||
- ✅ 更好的容错性和自愈能力
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
- 重新登录会记录在日志中,便于追踪
|
|
||||||
- 如果重新登录失败,仍会继续累积错误计数
|
|
||||||
- 达到5次最大连续错误后会发送邮件通知
|
|
||||||
239
常见问题解决.md
239
常见问题解决.md
@@ -1,239 +0,0 @@
|
|||||||
# 常见问题解决方案
|
|
||||||
|
|
||||||
## 🚨 "未能提取到成绩信息,共 0 门课程" 错误
|
|
||||||
|
|
||||||
### 问题症状
|
|
||||||
日志中反复出现:
|
|
||||||
```
|
|
||||||
[WARNING] 未能提取到成绩信息,返回原始文本
|
|
||||||
[INFO] 成绩无变化(共 0 门课程)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 快速诊断
|
|
||||||
|
|
||||||
#### 1. 检查 BeautifulSoup 是否安装
|
|
||||||
```bash
|
|
||||||
python3 -c "import bs4; print('BeautifulSoup4 已安装')"
|
|
||||||
```
|
|
||||||
|
|
||||||
如果报错,安装依赖:
|
|
||||||
```bash
|
|
||||||
pip3 install beautifulsoup4
|
|
||||||
# 或完整安装所有依赖
|
|
||||||
pip3 install -r requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. 使用调试模式查看详细信息
|
|
||||||
```bash
|
|
||||||
cd ~/grade_monitor
|
|
||||||
python3 monitor.py --test --debug
|
|
||||||
```
|
|
||||||
|
|
||||||
查看输出中是否有:
|
|
||||||
- ✅ "找到成绩表格"
|
|
||||||
- ✅ "找到 X 行成绩数据"
|
|
||||||
- ✅ "共解析到 X 门课程"
|
|
||||||
|
|
||||||
如果都没有,继续下一步。
|
|
||||||
|
|
||||||
#### 3. 检查是否登录失效
|
|
||||||
查看日志是否有 "检测到登录页面" 错误:
|
|
||||||
```bash
|
|
||||||
grep "登录页面\|LOGIN_REQUIRED" ~/grade_monitor/monitor.log
|
|
||||||
```
|
|
||||||
|
|
||||||
如果有,重启服务重新登录:
|
|
||||||
```bash
|
|
||||||
systemctl restart grade-monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4. 查看调试HTML文件
|
|
||||||
程序会自动保存问题页面到 `debug_page.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 行:
|
|
||||||
```ini
|
|
||||||
ExecStart=/usr/bin/python3 /home/yourusername/grade_monitor/monitor.py --debug
|
|
||||||
```
|
|
||||||
|
|
||||||
重新加载并重启:
|
|
||||||
```bash
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
sudo systemctl restart grade-monitor
|
|
||||||
tail -f ~/grade_monitor/monitor.log
|
|
||||||
```
|
|
||||||
|
|
||||||
**方案3:如果是网页结构变化**
|
|
||||||
查看详细排查指南:
|
|
||||||
```bash
|
|
||||||
cat ~/grade_monitor/故障排查指南.md
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚠️ "请不要过快点击" 错误
|
|
||||||
|
|
||||||
### 问题原因
|
|
||||||
学校WebVPN系统有严格的访问频率限制,短时间内多次访问会被拦截。
|
|
||||||
|
|
||||||
### 解决方案
|
|
||||||
|
|
||||||
#### 1. 停止手动测试至少5分钟
|
|
||||||
```bash
|
|
||||||
# 如果在服务器上运行,请先停止程序
|
|
||||||
ps aux | grep monitor.py
|
|
||||||
kill <进程ID>
|
|
||||||
|
|
||||||
# 等待至少5分钟后再重新测试
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. 修改配置文件增加间隔
|
|
||||||
编辑 `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-17 10:00:00 - INFO - 开始检查成绩变化...
|
|
||||||
2026-01-17 10:00:05 - INFO - 登录成功!
|
|
||||||
2026-01-17 10:00:10 - INFO - 成功获取成绩页面
|
|
||||||
2026-01-17 10:00:12 - INFO - 未发现新课程
|
|
||||||
2026-01-17 10:02:00 - INFO - 等待下次检查...
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方法2:查看保存的成绩文件
|
|
||||||
```bash
|
|
||||||
cat ~/.last_grade_content.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
如果文件包含完整的课程列表和GPA,说明系统工作正常。
|
|
||||||
|
|
||||||
### 方法3:查看进程状态
|
|
||||||
```bash
|
|
||||||
ps aux | grep monitor.py
|
|
||||||
```
|
|
||||||
|
|
||||||
如果有进程在运行,说明程序正在监控中。
|
|
||||||
|
|
||||||
## 📝 最佳实践
|
|
||||||
|
|
||||||
### 测试阶段
|
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
## 💡 温馨提示
|
|
||||||
|
|
||||||
1. **成绩更新频率不高**:学校不会每分钟更新成绩,建议CHECK_INTERVAL设为120-300秒
|
|
||||||
2. **避免过度监控**:频繁访问可能被学校系统封禁IP
|
|
||||||
3. **合理设置间隔**:既能及时发现新成绩,又不会触发限流
|
|
||||||
4. **信任自动化**:部署后让程序自己运行,不需要频繁检查
|
|
||||||
|
|
||||||
## 📞 仍然无法解决?
|
|
||||||
|
|
||||||
1. 检查配置文件中的账号密码是否正确
|
|
||||||
2. 确认能在浏览器中正常登录学校系统
|
|
||||||
3. 查看 `.debug_response.html` 了解实际响应
|
|
||||||
4. 将CHECK_INTERVAL增加到600秒(10分钟)
|
|
||||||
5. 考虑只在特定时间段运行(如每天上午10点和下午3点)
|
|
||||||
179
快速更新指南.md
179
快速更新指南.md
@@ -1,179 +0,0 @@
|
|||||||
# 快速更新指南 - 修复会话过期问题
|
|
||||||
|
|
||||||
## 🎯 本次更新解决的问题
|
|
||||||
|
|
||||||
**症状:** 程序运行几小时后出现:
|
|
||||||
```
|
|
||||||
[WARNING] 未能提取到成绩信息,返回原始文本
|
|
||||||
[INFO] 成绩无变化(共 0 门课程)
|
|
||||||
```
|
|
||||||
|
|
||||||
**原因:** 登录会话过期,需要重新登录
|
|
||||||
|
|
||||||
**解决:** ✅ 自动检测并重新登录
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 方式1:快速更新(推荐)
|
|
||||||
|
|
||||||
### 在本地打包
|
|
||||||
```bash
|
|
||||||
cd /mnt/e/50425/Documents/Github/GPA_Monitoring
|
|
||||||
chmod +x 打包.sh
|
|
||||||
./打包.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### 上传到服务器
|
|
||||||
```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/
|
|
||||||
```
|
|
||||||
|
|
||||||
### 在服务器上
|
|
||||||
```bash
|
|
||||||
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] 重新登录成功,继续监控
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔍 故障诊断
|
|
||||||
|
|
||||||
如果更新后仍有问题:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/grade_monitor
|
|
||||||
|
|
||||||
# 运行诊断工具
|
|
||||||
./diagnose.sh
|
|
||||||
|
|
||||||
# 或手动测试
|
|
||||||
python3 monitor.py --test --debug
|
|
||||||
|
|
||||||
# 查看生成的调试文件
|
|
||||||
ls -lh debug_page.html
|
|
||||||
cat .last_grade_content.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 更新内容详细列表
|
|
||||||
|
|
||||||
1. **会话过期自动重新登录** (monitor.py 第697-718行)
|
|
||||||
- 检测 `LOGIN_REQUIRED` 状态
|
|
||||||
- 自动调用 `login()` 重新登录
|
|
||||||
- 记录详细日志
|
|
||||||
|
|
||||||
2. **改进成绩提取** (monitor.py 第286-370行)
|
|
||||||
- 检测登录页面
|
|
||||||
- 支持多种表格选择器
|
|
||||||
- 自动保存 debug_page.html
|
|
||||||
- 添加详细调试日志
|
|
||||||
|
|
||||||
3. **改进课程解析** (monitor.py 第375-405行)
|
|
||||||
- 检测登录失效
|
|
||||||
- 识别未解析的HTML
|
|
||||||
- 统计课程数量
|
|
||||||
|
|
||||||
4. **新增调试模式**
|
|
||||||
- `python3 monitor.py --debug`
|
|
||||||
- 显示详细运行信息
|
|
||||||
|
|
||||||
5. **新增诊断工具**
|
|
||||||
- `diagnose.sh` - 自动检测并给出建议
|
|
||||||
- `故障排查指南.md` - 详细排查步骤
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💡 最佳实践
|
|
||||||
|
|
||||||
1. **定期检查日志**(每天1-2次即可)
|
|
||||||
```bash
|
|
||||||
tail -n 50 ~/grade_monitor/monitor.log
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **不要频繁重启服务**
|
|
||||||
- 新版本会自动处理会话过期
|
|
||||||
- 只在真正出问题时才重启
|
|
||||||
|
|
||||||
3. **保留备份**
|
|
||||||
```bash
|
|
||||||
# 每次更新前都会自动备份
|
|
||||||
ls -lh ~/grade_monitor/monitor.py.backup.*
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **合理设置检查间隔**
|
|
||||||
- 建议 120-300 秒
|
|
||||||
- 避免触发学校系统限流
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🆘 需要帮助?
|
|
||||||
|
|
||||||
1. 先运行诊断工具:`./diagnose.sh`
|
|
||||||
2. 查看故障排查指南:`cat 故障排查指南.md`
|
|
||||||
3. 查看详细修复说明:`cat 修复说明_2026-01-21.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**更新日期:** 2026-01-21
|
|
||||||
**版本:** v2.0 - 自动会话恢复版
|
|
||||||
97
打包.sh
97
打包.sh
@@ -1,97 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 成绩监控系统 - 打包脚本
|
|
||||||
# 用途:打包项目文件准备上传到服务器
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
ARCHIVE_NAME="gpa_monitor.tar.gz"
|
|
||||||
|
|
||||||
echo "========================================="
|
|
||||||
echo " 成绩监控系统 - 打包工具"
|
|
||||||
echo "========================================="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
cd "$SCRIPT_DIR"
|
|
||||||
|
|
||||||
# 检查config.ini是否存在
|
|
||||||
if [ ! -f "config.ini" ]; then
|
|
||||||
echo "⚠️ 警告: 未找到 config.ini"
|
|
||||||
echo " 请先配置 config.ini 文件"
|
|
||||||
echo ""
|
|
||||||
read -p "是否继续打包?(y/n): " continue_pack
|
|
||||||
if [ "$continue_pack" != "y" ]; then
|
|
||||||
echo "已取消"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "📦 正在打包必需文件..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 打包必需文件
|
|
||||||
tar -czf "$ARCHIVE_NAME" \
|
|
||||||
monitor.py \
|
|
||||||
config.ini \
|
|
||||||
requirements.txt \
|
|
||||||
setup_python.sh \
|
|
||||||
diagnose.sh \
|
|
||||||
grade-monitor.service \
|
|
||||||
readme.md \
|
|
||||||
"常见问题解决.md" \
|
|
||||||
"故障排查指南.md" \
|
|
||||||
"重启服务.md" \
|
|
||||||
"Debian服务器部署指南.md" \
|
|
||||||
"修复说明_2026-01-21.md" \
|
|
||||||
2>/dev/null
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "✓ 打包成功!"
|
|
||||||
echo ""
|
|
||||||
echo "压缩包信息:"
|
|
||||||
ls -lh "$ARCHIVE_NAME"
|
|
||||||
echo ""
|
|
||||||
echo "📄 包含文件:"
|
|
||||||
tar -tzf "$ARCHIVE_NAME"
|
|
||||||
echo ""
|
|
||||||
echo "========================================="
|
|
||||||
echo "✨ 本次更新内容(2026-01-21):"
|
|
||||||
echo " 1. ✅ 修复会话过期问题 - 自动重新登录"
|
|
||||||
echo " 2. ✅ 改进成绩提取 - 多种表格选择器"
|
|
||||||
echo " 3. ✅ 新增调试模式 - --debug 参数"
|
|
||||||
echo " 4. ✅ 新增诊断工具 - diagnose.sh"
|
|
||||||
echo " 5. ✅ 自动保存 debug_page.html 供排查"
|
|
||||||
echo ""
|
|
||||||
echo "========================================="
|
|
||||||
echo "📤 上传到服务器:"
|
|
||||||
echo " scp $ARCHIVE_NAME 用户名@服务器IP:~/"
|
|
||||||
echo ""
|
|
||||||
echo "🔧 服务器上部署更新:"
|
|
||||||
echo " # 停止服务"
|
|
||||||
echo " systemctl stop grade-monitor"
|
|
||||||
echo ""
|
|
||||||
echo " # 备份旧文件"
|
|
||||||
echo " cd ~/grade_monitor"
|
|
||||||
echo " cp monitor.py monitor.py.backup"
|
|
||||||
echo ""
|
|
||||||
echo " # 解压新文件"
|
|
||||||
echo " tar -xzf ~/gpa_monitor.tar.gz -C ~/grade_monitor"
|
|
||||||
echo ""
|
|
||||||
echo " # 赋予执行权限"
|
|
||||||
echo " chmod +x diagnose.sh"
|
|
||||||
echo ""
|
|
||||||
echo " # 重启服务"
|
|
||||||
echo " systemctl restart grade-monitor"
|
|
||||||
echo ""
|
|
||||||
echo " # 查看日志"
|
|
||||||
echo " tail -f monitor.log"
|
|
||||||
echo ""
|
|
||||||
echo "🔍 如果遇到问题:"
|
|
||||||
echo " cd ~/grade_monitor"
|
|
||||||
echo " ./diagnose.sh"
|
|
||||||
echo ""
|
|
||||||
echo "详细说明: 修复说明_2026-01-21.md"
|
|
||||||
echo "========================================="
|
|
||||||
else
|
|
||||||
echo "✗ 打包失败"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
143
故障排查指南.md
143
故障排查指南.md
@@ -1,143 +0,0 @@
|
|||||||
# 故障排查指南
|
|
||||||
|
|
||||||
## 问题:未能提取到成绩信息,共 0 门课程
|
|
||||||
|
|
||||||
### 症状
|
|
||||||
日志中出现以下警告信息:
|
|
||||||
```
|
|
||||||
[WARNING] 未能提取到成绩信息,返回原始文本
|
|
||||||
[INFO] 成绩无变化(共 0 门课程)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 可能的原因和解决方案
|
|
||||||
|
|
||||||
#### 1. BeautifulSoup 未安装
|
|
||||||
**检查方法:**
|
|
||||||
```bash
|
|
||||||
python3 -c "import bs4; print('BeautifulSoup4 已安装')"
|
|
||||||
```
|
|
||||||
|
|
||||||
**解决方案:**
|
|
||||||
```bash
|
|
||||||
pip3 install beautifulsoup4
|
|
||||||
# 或
|
|
||||||
pip3 install -r requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. 登录会话失效
|
|
||||||
**症状:** 日志中可能出现 "检测到登录页面" 的错误
|
|
||||||
|
|
||||||
**解决方案:**
|
|
||||||
```bash
|
|
||||||
# 停止服务
|
|
||||||
systemctl stop grade-monitor
|
|
||||||
|
|
||||||
# 重新启动服务(会重新登录)
|
|
||||||
systemctl start grade-monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3. 网页结构变化
|
|
||||||
**检查方法:**
|
|
||||||
程序会自动保存 HTML 到 `debug_page.html`,查看这个文件:
|
|
||||||
```bash
|
|
||||||
# 查看 debug_page.html 是否存在
|
|
||||||
ls -la ~/grade_monitor/debug_page.html
|
|
||||||
|
|
||||||
# 查看 HTML 内容,确认是否有成绩表格
|
|
||||||
grep -i "gridtable\|课程名称\|成绩" ~/grade_monitor/debug_page.html
|
|
||||||
```
|
|
||||||
|
|
||||||
**解决方案:**
|
|
||||||
如果网页结构变化,可能需要修改 `monitor.py` 中的 `extract_grade_info` 函数。
|
|
||||||
当前支持的表格选择器:
|
|
||||||
- `<table class="gridtable">`
|
|
||||||
- `<table id="dataList">`
|
|
||||||
- 任何包含"课程名称"或"成绩"关键词的表格
|
|
||||||
|
|
||||||
#### 4. 启用调试模式排查
|
|
||||||
|
|
||||||
**临时测试(手动运行):**
|
|
||||||
```bash
|
|
||||||
cd ~/grade_monitor
|
|
||||||
python3 monitor.py --test --debug
|
|
||||||
```
|
|
||||||
|
|
||||||
**查看详细日志:**
|
|
||||||
```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
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 5. 检查保存的文件
|
|
||||||
```bash
|
|
||||||
cd ~/grade_monitor
|
|
||||||
|
|
||||||
# 查看上次提取的成绩内容
|
|
||||||
cat .last_grade_content.txt
|
|
||||||
|
|
||||||
# 查看上次保存的 HTML(如果存在)
|
|
||||||
cat .last_grade_page.html | head -50
|
|
||||||
|
|
||||||
# 查看调试 HTML(出错时自动保存)
|
|
||||||
cat debug_page.html | head -50
|
|
||||||
```
|
|
||||||
|
|
||||||
### 调试流程
|
|
||||||
|
|
||||||
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 中的表格结构
|
|
||||||
- 修改 `extract_grade_info` 函数中的选择器
|
|
||||||
|
|
||||||
### 常见问题
|
|
||||||
|
|
||||||
**Q: 日志显示"未找到成绩表格"**
|
|
||||||
A: 网页结构可能变化,需要查看 debug_page.html 确认实际的表格结构
|
|
||||||
|
|
||||||
**Q: 日志显示"找到 0 行成绩数据"**
|
|
||||||
A: 表格找到了但是为空,可能是:
|
|
||||||
- 登录失效,返回的是空表格
|
|
||||||
- 实际就是没有成绩数据
|
|
||||||
|
|
||||||
**Q: 日志显示"检测到未解析的HTML内容"**
|
|
||||||
A: BeautifulSoup 解析失败,返回了原始 HTML。检查:
|
|
||||||
1. BeautifulSoup 是否正确安装
|
|
||||||
2. HTML 格式是否正确(查看 debug_page.html)
|
|
||||||
|
|
||||||
### 联系支持
|
|
||||||
|
|
||||||
如果以上方法都无法解决问题,请提供:
|
|
||||||
1. `monitor.log` 的最后 50 行
|
|
||||||
2. `debug_page.html` 文件(如果存在)
|
|
||||||
3. `.last_grade_content.txt` 文件内容
|
|
||||||
4. 是否能手动登录并看到成绩页面
|
|
||||||
516
部署.md
516
部署.md
@@ -1,516 +0,0 @@
|
|||||||
# 服务器部署指南
|
|
||||||
|
|
||||||
本文档详细说明如何将成绩监控系统部署到Linux服务器上。
|
|
||||||
|
|
||||||
## 📋 前置要求
|
|
||||||
|
|
||||||
- Linux服务器(Debian/Ubuntu/CentOS等)
|
|
||||||
- Python 3.7+
|
|
||||||
- 服务器能访问外网
|
|
||||||
- SSH访问权限
|
|
||||||
|
|
||||||
## 📦 准备文件
|
|
||||||
|
|
||||||
### 需要上传的文件
|
|
||||||
|
|
||||||
```
|
|
||||||
grade_monitor/
|
|
||||||
├── monitor.py # 主程序(必需)
|
|
||||||
├── config.ini # 配置文件(必需)
|
|
||||||
├── requirements.txt # Python依赖(必需)
|
|
||||||
├── setup_python.sh # 安装脚本(必需)
|
|
||||||
└── readme.md # 说明文档(可选)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 打包文件
|
|
||||||
|
|
||||||
在Windows本地执行:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
# 方法1:使用tar(需要WSL或Git Bash)
|
|
||||||
tar -czf grade_monitor.tar.gz monitor.py config.ini requirements.txt setup_python.sh readme.md
|
|
||||||
|
|
||||||
# 方法2:使用7-Zip或WinRAR手动打包
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚀 部署步骤
|
|
||||||
|
|
||||||
### 步骤1:修改配置文件
|
|
||||||
|
|
||||||
**在上传前**,确保 `config.ini` 中填入了正确的信息:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[login]
|
|
||||||
USERNAME = 你的学号
|
|
||||||
PASSWORD = 你的密码
|
|
||||||
LOGIN_URL = ...
|
|
||||||
GRADE_URL = ...
|
|
||||||
|
|
||||||
[email]
|
|
||||||
SENDER_EMAIL = your_email@163.com
|
|
||||||
SENDER_PASSWORD = SMTP授权码
|
|
||||||
RECEIVER_EMAIL = 接收通知的邮箱
|
|
||||||
|
|
||||||
[monitor]
|
|
||||||
CHECK_INTERVAL = 60
|
|
||||||
REQUEST_DELAY = 5
|
|
||||||
MAX_RETRIES = 3
|
|
||||||
RETRY_DELAY = 10
|
|
||||||
```
|
|
||||||
|
|
||||||
### 步骤2:上传到服务器
|
|
||||||
|
|
||||||
#### 方法A:使用SCP上传
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 上传打包文件
|
|
||||||
scp grade_monitor.tar.gz username@server-ip:/home/username/
|
|
||||||
|
|
||||||
# 或直接上传文件
|
|
||||||
scp monitor.py config.ini requirements.txt setup_python.sh username@server-ip:/home/username/grade_monitor/
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 方法B:使用SFTP上传
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sftp username@server-ip
|
|
||||||
put grade_monitor.tar.gz
|
|
||||||
exit
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 方法C:使用FTP客户端
|
|
||||||
|
|
||||||
使用FileZilla、WinSCP等工具上传文件。
|
|
||||||
|
|
||||||
### 步骤3:连接到服务器
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ssh username@server-ip
|
|
||||||
```
|
|
||||||
|
|
||||||
### 步骤4:解压和安装
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 创建工作目录
|
|
||||||
mkdir -p ~/grade_monitor
|
|
||||||
cd ~/grade_monitor
|
|
||||||
|
|
||||||
# 添加执行权限
|
|
||||||
chmod +x setup_python.sh
|
|
||||||
|
|
||||||
# 运行安装脚本
|
|
||||||
./setup_python.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
安装脚本会自动:
|
|
||||||
- 更新apt包列表
|
|
||||||
- 安装Python3和pip
|
|
||||||
- 创建虚拟环境
|
|
||||||
- 安装所需的Python包(requests、beautifulsoup4)
|
|
||||||
|
|
||||||
### 步骤5:测试运行
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 激活虚拟环境
|
|
||||||
source venv/bin/activate
|
|
||||||
|
|
||||||
# 测试模式运行
|
|
||||||
python3 monitor.py --test
|
|
||||||
```
|
|
||||||
|
|
||||||
**检查输出:**
|
|
||||||
- 是否成功登录
|
|
||||||
- 是否获取到成绩页面
|
|
||||||
- 查看提取的成绩内容
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 查看提取的成绩
|
|
||||||
cat .last_grade_content.txt
|
|
||||||
|
|
||||||
# 应该看到类似这样的内容:
|
|
||||||
# ============================================================
|
|
||||||
# 总平均绩点:4.3471
|
|
||||||
# ============================================================
|
|
||||||
#
|
|
||||||
# 学年学期 | 课程代码 | 课程序号 | 课程名称 | ...
|
|
||||||
# --------------------------------------------------------
|
|
||||||
# 2025-2026 秋季 | A0801051020 | A095478 | C++程序设计 | ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔄 后台运行方案
|
|
||||||
|
|
||||||
### 方案A:使用systemd(推荐,适合长期运行)
|
|
||||||
|
|
||||||
#### 1. 创建服务文件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo nano /etc/systemd/system/grade-monitor.service
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. 填入以下内容
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[Unit]
|
|
||||||
Description=Grade Monitoring Service
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
User=你的用户名
|
|
||||||
WorkingDirectory=/home/你的用户名/grade_monitor
|
|
||||||
ExecStart=/home/你的用户名/grade_monitor/venv/bin/python3 /home/你的用户名/grade_monitor/monitor.py
|
|
||||||
Restart=always
|
|
||||||
RestartSec=30
|
|
||||||
StandardOutput=append:/home/你的用户名/grade_monitor/monitor.log
|
|
||||||
StandardError=append:/home/你的用户名/grade_monitor/monitor.log
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
```
|
|
||||||
|
|
||||||
**注意:** 将上面的"你的用户名"替换为实际的Linux用户名
|
|
||||||
|
|
||||||
#### 3. 启动服务
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 重载systemd配置
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
|
|
||||||
# 启用开机自启
|
|
||||||
sudo systemctl enable grade-monitor
|
|
||||||
|
|
||||||
# 启动服务
|
|
||||||
sudo systemctl start grade-monitor
|
|
||||||
|
|
||||||
# 查看服务状态
|
|
||||||
sudo systemctl status grade-monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4. 管理服务
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 查看日志
|
|
||||||
sudo journalctl -u grade-monitor -f
|
|
||||||
|
|
||||||
# 停止服务
|
|
||||||
sudo systemctl stop grade-monitor
|
|
||||||
|
|
||||||
# 重启服务
|
|
||||||
sudo systemctl restart grade-monitor
|
|
||||||
|
|
||||||
# 禁用开机自启
|
|
||||||
sudo systemctl disable grade-monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方案B:使用tmux(简单,适合临时运行)
|
|
||||||
|
|
||||||
#### 1. 安装tmux
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Debian/Ubuntu
|
|
||||||
sudo apt install tmux
|
|
||||||
|
|
||||||
# CentOS/RHEL
|
|
||||||
sudo yum install tmux
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. 创建会话并运行
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 创建新的tmux会话
|
|
||||||
tmux new -s grade_monitor
|
|
||||||
|
|
||||||
# 激活虚拟环境
|
|
||||||
source venv/bin/activate
|
|
||||||
|
|
||||||
# 运行程序
|
|
||||||
python3 monitor.py
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3. 离开和重连会话
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 离开会话(程序继续运行)
|
|
||||||
# 按键:Ctrl+B,然后按 D
|
|
||||||
|
|
||||||
# 重新连接到会话
|
|
||||||
tmux attach -t grade_monitor
|
|
||||||
|
|
||||||
# 查看所有会话
|
|
||||||
tmux ls
|
|
||||||
|
|
||||||
# 关闭会话
|
|
||||||
tmux kill-session -t grade_monitor
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方案C:使用screen
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 安装screen
|
|
||||||
sudo apt install screen
|
|
||||||
|
|
||||||
# 创建新会话
|
|
||||||
screen -S grade_monitor
|
|
||||||
|
|
||||||
# 激活环境并运行
|
|
||||||
source venv/bin/activate
|
|
||||||
python3 monitor.py
|
|
||||||
|
|
||||||
# 离开会话:Ctrl+A,然后按 D
|
|
||||||
|
|
||||||
# 重新连接
|
|
||||||
screen -r grade_monitor
|
|
||||||
|
|
||||||
# 查看所有会话
|
|
||||||
screen -ls
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方案D:使用nohup(最简单)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 激活虚拟环境
|
|
||||||
source venv/bin/activate
|
|
||||||
|
|
||||||
# 后台运行
|
|
||||||
nohup python3 monitor.py > monitor.log 2>&1 &
|
|
||||||
|
|
||||||
# 查看进程
|
|
||||||
ps aux | grep monitor.py
|
|
||||||
|
|
||||||
# 停止进程
|
|
||||||
kill <进程ID>
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📊 监控和维护
|
|
||||||
|
|
||||||
### 查看运行状态
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 方法1:查看日志文件
|
|
||||||
tail -f ~/grade_monitor/monitor.log
|
|
||||||
|
|
||||||
# 方法2:查看systemd日志(如果使用systemd)
|
|
||||||
sudo journalctl -u grade-monitor -n 50 -f
|
|
||||||
|
|
||||||
# 方法3:查看进程
|
|
||||||
ps aux | grep monitor.py
|
|
||||||
```
|
|
||||||
|
|
||||||
### 查看当前成绩
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/grade_monitor
|
|
||||||
cat .last_grade_content.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
### 手动触发测试
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/grade_monitor
|
|
||||||
source venv/bin/activate
|
|
||||||
python3 monitor.py --test
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔧 常见问题
|
|
||||||
|
|
||||||
### 问题1:连接服务器失败
|
|
||||||
|
|
||||||
**可能原因:**
|
|
||||||
- SSH端口被防火墙拦截
|
|
||||||
- 服务器IP或用户名错误
|
|
||||||
- SSH密钥配置问题
|
|
||||||
|
|
||||||
**解决方法:**
|
|
||||||
```bash
|
|
||||||
# 指定端口
|
|
||||||
ssh -p 端口号 username@server-ip
|
|
||||||
|
|
||||||
# 使用密钥
|
|
||||||
ssh -i /path/to/key.pem username@server-ip
|
|
||||||
```
|
|
||||||
|
|
||||||
### 问题2:无法访问学校网站
|
|
||||||
|
|
||||||
**可能原因:**
|
|
||||||
- 服务器在校外,需要VPN
|
|
||||||
- 防火墙拦截
|
|
||||||
|
|
||||||
**解决方法:**
|
|
||||||
- 使用校内服务器
|
|
||||||
- 配置代理
|
|
||||||
- 联系网络管理员
|
|
||||||
|
|
||||||
### 问题3:pip安装失败
|
|
||||||
|
|
||||||
**解决方法:**
|
|
||||||
```bash
|
|
||||||
# 更新pip
|
|
||||||
pip install --upgrade pip
|
|
||||||
|
|
||||||
# 使用国内镜像
|
|
||||||
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
|
|
||||||
|
|
||||||
# 或使用清华源
|
|
||||||
pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
|
|
||||||
```
|
|
||||||
|
|
||||||
### 问题4:权限不足
|
|
||||||
|
|
||||||
**解决方法:**
|
|
||||||
```bash
|
|
||||||
# 修改文件所有者
|
|
||||||
sudo chown -R username:username ~/grade_monitor
|
|
||||||
|
|
||||||
# 修改执行权限
|
|
||||||
chmod +x ~/grade_monitor/*.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### 问题5:邮件发送失败
|
|
||||||
|
|
||||||
**解决方法:**
|
|
||||||
- 确认SMTP授权码正确(不是邮箱密码)
|
|
||||||
- 检查服务器能否访问smtp.163.com(端口465)
|
|
||||||
- 查看详细错误信息:`tail -f monitor.log`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 测试网络连接
|
|
||||||
telnet smtp.163.com 465
|
|
||||||
# 或
|
|
||||||
nc -zv smtp.163.com 465
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔐 安全建议
|
|
||||||
|
|
||||||
### 1. 保护配置文件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 限制config.ini权限
|
|
||||||
chmod 600 ~/grade_monitor/config.ini
|
|
||||||
|
|
||||||
# 确保只有自己能访问
|
|
||||||
ls -la ~/grade_monitor/config.ini
|
|
||||||
# 应显示:-rw------- 1 username username
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 使用环境变量(可选)
|
|
||||||
|
|
||||||
不在配置文件中存储明文密码,而是使用环境变量:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 设置环境变量
|
|
||||||
export GRADE_USERNAME="你的学号"
|
|
||||||
export GRADE_PASSWORD="你的密码"
|
|
||||||
export EMAIL_PASSWORD="SMTP授权码"
|
|
||||||
|
|
||||||
# 添加到.bashrc使其永久生效
|
|
||||||
echo 'export GRADE_USERNAME="你的学号"' >> ~/.bashrc
|
|
||||||
echo 'export GRADE_PASSWORD="你的密码"' >> ~/.bashrc
|
|
||||||
echo 'export EMAIL_PASSWORD="SMTP授权码"' >> ~/.bashrc
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 定期更新
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 更新系统
|
|
||||||
sudo apt update && sudo apt upgrade
|
|
||||||
|
|
||||||
# 更新Python包
|
|
||||||
cd ~/grade_monitor
|
|
||||||
source venv/bin/activate
|
|
||||||
pip install --upgrade requests beautifulsoup4
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📱 监控建议
|
|
||||||
|
|
||||||
### 设置监控脚本
|
|
||||||
|
|
||||||
创建一个检查脚本 `check_status.sh`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 检查进程是否运行
|
|
||||||
if pgrep -f "monitor.py" > /dev/null; then
|
|
||||||
echo "✓ 监控程序正在运行"
|
|
||||||
else
|
|
||||||
echo "✗ 监控程序未运行!"
|
|
||||||
# 可以在这里添加重启逻辑
|
|
||||||
# systemctl start grade-monitor
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 检查最近的日志
|
|
||||||
echo ""
|
|
||||||
echo "最近的日志:"
|
|
||||||
tail -n 5 ~/grade_monitor/monitor.log
|
|
||||||
```
|
|
||||||
|
|
||||||
### 定期检查(使用cron)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 编辑crontab
|
|
||||||
crontab -e
|
|
||||||
|
|
||||||
# 添加以下行(每天检查一次)
|
|
||||||
0 12 * * * /home/username/grade_monitor/check_status.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎯 完整部署示例
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# === 本地操作(Windows/WSL) ===
|
|
||||||
cd E:\50425\Documents\Github\GPA_Monitoring
|
|
||||||
tar -czf grade_monitor.tar.gz monitor.py config.ini requirements.txt setup_python.sh readme.md
|
|
||||||
scp grade_monitor.tar.gz user@server.com:~/
|
|
||||||
|
|
||||||
# === 服务器操作 ===
|
|
||||||
ssh user@server.com
|
|
||||||
|
|
||||||
# 解压和安装
|
|
||||||
mkdir -p ~/grade_monitor
|
|
||||||
cd ~/grade_monitor
|
|
||||||
tar -xzf ../grade_monitor.tar.gz
|
|
||||||
chmod +x setup_python.sh
|
|
||||||
./setup_python.sh
|
|
||||||
|
|
||||||
# 测试
|
|
||||||
source venv/bin/activate
|
|
||||||
python3 monitor.py --test
|
|
||||||
cat .last_grade_content.txt
|
|
||||||
|
|
||||||
# 配置systemd服务
|
|
||||||
sudo nano /etc/systemd/system/grade-monitor.service
|
|
||||||
# (填入服务配置)
|
|
||||||
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
sudo systemctl enable grade-monitor
|
|
||||||
sudo systemctl start grade-monitor
|
|
||||||
sudo systemctl status grade-monitor
|
|
||||||
|
|
||||||
# 查看日志
|
|
||||||
sudo journalctl -u grade-monitor -f
|
|
||||||
```
|
|
||||||
|
|
||||||
## ✅ 部署检查清单
|
|
||||||
|
|
||||||
- [ ] 文件已上传到服务器
|
|
||||||
- [ ] config.ini配置正确(账号、密码、邮箱)
|
|
||||||
- [ ] 运行setup_python.sh安装依赖
|
|
||||||
- [ ] 测试模式运行成功
|
|
||||||
- [ ] 成绩提取格式正确
|
|
||||||
- [ ] 配置后台运行(systemd/tmux/screen)
|
|
||||||
- [ ] 服务正常启动
|
|
||||||
- [ ] 日志输出正常
|
|
||||||
- [ ] 收到测试邮件
|
|
||||||
- [ ] 设置文件权限(chmod 600 config.ini)
|
|
||||||
|
|
||||||
## 📞 获取帮助
|
|
||||||
|
|
||||||
如果遇到问题:
|
|
||||||
1. 查看 `monitor.log` 了解详细错误
|
|
||||||
2. 运行 `python3 monitor.py --test` 测试
|
|
||||||
3. 检查 `.debug_response.html` 了解实际响应
|
|
||||||
4. 查看 `readme.md` 了解更多功能说明
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
部署完成后,系统将自动监控成绩变化,有新课程成绩时会立即发送邮件通知!
|
|
||||||
56
重启服务.md
56
重启服务.md
@@ -1,56 +0,0 @@
|
|||||||
# 停止服务
|
|
||||||
systemctl stop grade-monitor
|
|
||||||
|
|
||||||
# 备份旧文件
|
|
||||||
cp monitor.py monitor.py.backup
|
|
||||||
|
|
||||||
# 解压新文件(会覆盖)
|
|
||||||
tar -xzf ~/gpa_monitor.tar.gz -C ~/grade_monitor --strip-components=0
|
|
||||||
|
|
||||||
# 或者只替换 monitor.py
|
|
||||||
# 你可以直接编辑:
|
|
||||||
nano monitor.py
|
|
||||||
|
|
||||||
# 重启服务
|
|
||||||
systemctl restart grade-monitor
|
|
||||||
|
|
||||||
# 查看实时日志
|
|
||||||
tail -f monitor.log
|
|
||||||
|
|
||||||
# 或查看最近的日志(包含完整上下文)
|
|
||||||
tail -n 100 monitor.log
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 常见问题:会话过期
|
|
||||||
|
|
||||||
如果日志显示:
|
|
||||||
```
|
|
||||||
[WARNING] 未能提取到成绩信息,返回原始文本
|
|
||||||
[INFO] 成绩无变化(共 0 门课程)
|
|
||||||
```
|
|
||||||
|
|
||||||
**原因:** 登录会话几小时后自动过期
|
|
||||||
|
|
||||||
**解决:** 最新版本已自动处理!代码会:
|
|
||||||
1. 检测到 "LOGIN_REQUIRED" 时自动重新登录
|
|
||||||
2. 记录日志:`[WARNING] 检测到会话过期,尝试重新登录...`
|
|
||||||
3. 重新登录后继续监控
|
|
||||||
|
|
||||||
**手动重启(如果需要):**
|
|
||||||
```bash
|
|
||||||
systemctl restart grade-monitor
|
|
||||||
tail -f monitor.log
|
|
||||||
```
|
|
||||||
|
|
||||||
**调试模式(查看详细信息):**
|
|
||||||
```bash
|
|
||||||
# 手动测试
|
|
||||||
python3 monitor.py --test --debug
|
|
||||||
|
|
||||||
# 或修改服务启用调试
|
|
||||||
sudo nano /etc/systemd/system/grade-monitor.service
|
|
||||||
# 在 ExecStart 添加 --debug 参数
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
sudo systemctl restart grade-monitor
|
|
||||||
```
|
|
||||||
194
间歇性解析失败说明.md
194
间歇性解析失败说明.md
@@ -1,194 +0,0 @@
|
|||||||
# 间歇性解析失败说明
|
|
||||||
|
|
||||||
## 现象
|
|
||||||
|
|
||||||
日志显示偶尔出现解析失败,但下一次检查又恢复正常:
|
|
||||||
|
|
||||||
```
|
|
||||||
17:34:05 - ✅ 成功提取成绩信息,共 14 行,解析到 8 门课程
|
|
||||||
17:36:12 - ✅ 成功提取成绩信息,共 14 行,解析到 8 门课程
|
|
||||||
17:38:12 - ❌ 未找到成绩表格,解析到 0 门课程
|
|
||||||
17:40:12 - ✅ 成功提取成绩信息,共 14 行,解析到 8 门课程
|
|
||||||
```
|
|
||||||
|
|
||||||
## 原因分析
|
|
||||||
|
|
||||||
这种**偶发性失败**通常是由以下原因造成的:
|
|
||||||
|
|
||||||
### 1. 网络波动(最常见)
|
|
||||||
- 数据包传输不完整
|
|
||||||
- HTML内容被截断
|
|
||||||
- 连接临时中断
|
|
||||||
|
|
||||||
### 2. 服务器临时问题
|
|
||||||
- 学校服务器负载高
|
|
||||||
- 短暂的维护或重启
|
|
||||||
- 数据库查询超时
|
|
||||||
|
|
||||||
### 3. WebVPN不稳定
|
|
||||||
- WebVPN代理服务波动
|
|
||||||
- SSL握手失败
|
|
||||||
- 重定向异常
|
|
||||||
|
|
||||||
### 4. 时机问题
|
|
||||||
- 正好在服务器更新数据时访问
|
|
||||||
- 缓存失效瞬间
|
|
||||||
- 负载均衡切换
|
|
||||||
|
|
||||||
## 改进措施
|
|
||||||
|
|
||||||
最新版本已添加**智能容错机制**:
|
|
||||||
|
|
||||||
### 1. 识别网络错误
|
|
||||||
```python
|
|
||||||
# 检查HTML内容长度
|
|
||||||
if len(html) < 100:
|
|
||||||
logger.warning(f"HTML内容过短({len(html)}字节),可能是网络问题")
|
|
||||||
return "NETWORK_ERROR"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 自动重试
|
|
||||||
当检测到临时性问题时:
|
|
||||||
- ⚠️ 记录警告但不立即报错
|
|
||||||
- ⏱️ 等待30秒后自动重试
|
|
||||||
- 📊 只有连续3次失败才报警
|
|
||||||
|
|
||||||
### 3. 智能判断
|
|
||||||
```python
|
|
||||||
# 如果解析到0门课程,但之前有课程记录
|
|
||||||
if len(current_courses) == 0 and len(previous_courses) > 0:
|
|
||||||
logger.warning("可能是临时问题,30秒后重试")
|
|
||||||
time.sleep(30)
|
|
||||||
continue # 重新检查
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. 保存诊断信息
|
|
||||||
- 自动保存 `debug_page.html`
|
|
||||||
- 记录HTML长度和摘要
|
|
||||||
- 便于事后分析
|
|
||||||
|
|
||||||
## 预期行为
|
|
||||||
|
|
||||||
### 场景1:偶发性失败(正常)
|
|
||||||
```
|
|
||||||
[INFO] 成功提取成绩信息,共 14 行
|
|
||||||
[INFO] 共解析到 8 门课程
|
|
||||||
[INFO] 等待 120 秒...
|
|
||||||
|
|
||||||
[WARNING] 未找到成绩表格
|
|
||||||
[WARNING] ⚠️ 解析到0门课程,但之前有8门课程,可能是临时问题
|
|
||||||
[INFO] 等待 30 秒后重试...
|
|
||||||
|
|
||||||
[INFO] 成功提取成绩信息,共 14 行 ← 重试成功
|
|
||||||
[INFO] 共解析到 8 门课程
|
|
||||||
```
|
|
||||||
|
|
||||||
### 场景2:持续失败(异常)
|
|
||||||
```
|
|
||||||
[WARNING] ⚠️ 解析到0门课程,可能是临时问题
|
|
||||||
[WARNING] 连续异常: 1/5
|
|
||||||
|
|
||||||
[WARNING] ⚠️ 解析到0门课程,可能是临时问题
|
|
||||||
[WARNING] 连续异常: 2/5
|
|
||||||
|
|
||||||
[WARNING] ⚠️ 解析到0门课程,可能是临时问题
|
|
||||||
[WARNING] 连续异常: 3/5 ← 开始报警
|
|
||||||
|
|
||||||
[ERROR] 连续 3 次无法解析课程(之前有8门课程)
|
|
||||||
```
|
|
||||||
|
|
||||||
## 判断标准
|
|
||||||
|
|
||||||
### ✅ 无需担心的情况
|
|
||||||
- 失败率 < 20%(每10次失败少于2次)
|
|
||||||
- 失败后1-2次就恢复
|
|
||||||
- 日志显示"等待30秒后重试"
|
|
||||||
- 下次检查自动恢复正常
|
|
||||||
|
|
||||||
### ⚠️ 需要关注的情况
|
|
||||||
- 失败率 > 20%
|
|
||||||
- 连续3次以上失败
|
|
||||||
- 日志显示"连续异常"
|
|
||||||
- 出现错误通知邮件
|
|
||||||
|
|
||||||
### 🚨 需要处理的情况
|
|
||||||
- 连续5次以上失败
|
|
||||||
- 失败率 > 50%
|
|
||||||
- 伴随"会话过期"错误
|
|
||||||
- debug_page.html 显示登录页面
|
|
||||||
|
|
||||||
## 统计失败率
|
|
||||||
|
|
||||||
使用诊断工具检查:
|
|
||||||
```bash
|
|
||||||
cd ~/grade_monitor
|
|
||||||
./diagnose.sh
|
|
||||||
|
|
||||||
# 或手动统计
|
|
||||||
echo "成功次数: $(grep -c '共解析到 [1-9]' monitor.log)"
|
|
||||||
echo "失败次数: $(grep -c '共解析到 0 门课程' monitor.log)"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 最佳实践
|
|
||||||
|
|
||||||
### 1. 不要过度担心
|
|
||||||
- 偶尔失败是**正常现象**
|
|
||||||
- 程序已自动处理
|
|
||||||
- 只要失败率低,无需干预
|
|
||||||
|
|
||||||
### 2. 定期检查日志
|
|
||||||
```bash
|
|
||||||
# 查看最近的失败记录
|
|
||||||
grep "未找到成绩表格\|共解析到 0 门课程" ~/grade_monitor/monitor.log | tail -10
|
|
||||||
|
|
||||||
# 查看是否自动恢复
|
|
||||||
tail -n 20 ~/grade_monitor/monitor.log
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 调整检查间隔
|
|
||||||
如果失败频繁,可以增加间隔:
|
|
||||||
```ini
|
|
||||||
[monitor]
|
|
||||||
CHECK_INTERVAL = 180 # 从120改为180秒
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. 信任自动化
|
|
||||||
- 程序会自动重试
|
|
||||||
- 只有持续失败才报警
|
|
||||||
- 收到邮件通知时再处理
|
|
||||||
|
|
||||||
## 何时需要手动干预
|
|
||||||
|
|
||||||
只在以下情况需要重启服务:
|
|
||||||
|
|
||||||
1. **连续多次收到错误邮件**
|
|
||||||
2. **日志显示持续登录失败**
|
|
||||||
3. **debug_page.html 显示异常内容**
|
|
||||||
4. **失败率持续超过50%**
|
|
||||||
|
|
||||||
其他情况下,让程序自动处理即可。
|
|
||||||
|
|
||||||
## 对比:改进前 vs 改进后
|
|
||||||
|
|
||||||
### 改进前
|
|
||||||
```
|
|
||||||
17:38:12 - ❌ 未找到成绩表格,解析到 0 门课程
|
|
||||||
17:38:12 - 成绩无变化(共 0 门课程) ← 直接当作正常
|
|
||||||
17:38:12 - 等待 120 秒... ← 不重试
|
|
||||||
17:40:12 - 开始新一轮检查 ← 2分钟后才重试
|
|
||||||
```
|
|
||||||
|
|
||||||
### 改进后
|
|
||||||
```
|
|
||||||
17:38:12 - ❌ 未找到成绩表格
|
|
||||||
17:38:12 - ⚠️ 解析到0门课程,但之前有8门课程
|
|
||||||
17:38:12 - 等待 30 秒后重试... ← 智能判断
|
|
||||||
17:38:42 - ✅ 成功提取成绩信息 ← 快速恢复
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**总结:** 偶发性失败是网络应用的正常现象。新版本通过智能重试机制,将影响降到最低。只要失败率在合理范围(<20%),无需任何手动干预。
|
|
||||||
|
|
||||||
**更新日期:** 2026-01-21
|
|
||||||
**版本:** v2.1 - 智能容错版
|
|
||||||
Reference in New Issue
Block a user