⌈产品⌋ 多源抓取、去重与索引的工程实践 x PKU7Day(北京大学自习教室规划与课程检索)
做这个项目有两个原因,一是看到了下图中的树洞帖子,回想起本科维护过的民间数学机考刷题网站;二是 AI 崛起,国产 Deepseek 成绩瞩目,想动手尝试一次尽量使用 AI 编写含前后端的项目。

课表查询
申请到的校园 API 信息量太少,难以实现检索,故只能从门户中寻找有用的接口。上课摸鱼了三天,一直在整理数据来源和思考这些数据如何整合,实现 。
flowchart LR
subgraph A[第一阶段:单源处理]
A1[数据采集] --> A2[预处理与结构化]
end
subgraph B[第二阶段:多源整合]
B1[以主体为核心] --> B2[特征匹配与交叉扩展]
end
A --提供--> B
B --形成--> C1
subgraph C[最终目标]
direction LR
C1[完整、一致的数据集]
C1 --> D[数据建模]
D --> E[✅ 支持高效查询与分析]
end
数据采集与预处理流程
flowchart LR
A[选定目标数据源<br>网页/API] --> B{评估稳定性与可靠性}
B -- 不可靠 --> A
B -- 可靠 --> C[爬取数据]
C --> D[原始数据<br>(JSON/HTML/文本等)]
D --> E{数据是否为非结构化文本?}
E -- 是 --> F[使用正则表达式等方法<br>提取与分割关键信息]
E -- 否 --> G[直接解析结构化的数据<br>(如JSON)]
F --> H[初步结构化数据]
G --> H
flowchart LR
A[开始爬取任务] --> B[读取爬取目标参数<br>e.g. URL, 接口, 日期]
B --> C{查询数据库记录<br>该目标是否已爬取过?}
C -- 未爬取过 --> D[执行爬取任务]
C -- 已存在记录 --> E{强制更新?}
E -- 是 --> D
E -- 否 --> G[跳过爬取<br>使用现有数据]
D --> H[保存/覆盖原始数据至<br>'源数据存储']
H --> I[更新或插入爬取记录至<br>'爬取记录表'<br>记录目标参数、时间、状态等]
I --> J[结束本次任务]
G --> J
多源数据交叉扩展流程
flowchart LR
A[初始数据集合<br>(以某一主体为核心)] --> B(提取关键特征<br>如ID、名称、时间等)
subgraph S[多源数据扩展]
direction LR
B --> C[根据特征匹配数据源2]
B --> D[根据特征匹配数据源3]
B --> E[根据特征匹配数据源...]
C -- 补充信息 --> F[扩展后的数据记录]
D -- 补充信息 --> F
E -- 补充信息 --> F
end
F --形成--> Z[更完整的数据记录]
数据存储与查询
flowchart LR
A[完整数据] --> B[数据建模]
B --> C[映射与保存至数据库]
subgraph C [数据库表]
direction LR
T1[Teacher]
T2[Room]
T3[Semester]
T4[...]
end
C --> D[利用外键关联<br>支持高效复杂查询]
C --> E[快速列举特征<br>前端支持选择特征]
在构造复杂查询函数时,AI 表现不佳,很像刚学数据库的小白。
1 | async searchCoursesInner(searchDto: SearchCourseDto): Promise<Course[]> { |


空闲教室规划
使用类似方法获取和更新空闲教室数据。
给定时间段,从教室集合中选择 条路径(可更换教室),使得总使用时间覆盖,且移动距离最小。算法通过启发式搜索(优先队列 + BFS)实现。
flowchart TD
A[开始] --> B[预处理教室空闲时间段排序]
B --> C[初始化优先队列]
C --> D{优先队列是否为空?}
D -- 是 --> E[输出解(反转解队列)]
D -- 否 --> F[弹出当前状态<br>count, distance, endTime, path]
F --> G{检查剪枝条件<br>已有10个解且当前距离>堆顶距离?}
G -- 是 --> D
G -- 否 --> H{endTime >= t?}
H -- 是 --> I[加入解队列并保持最多10个解]
I --> D
H -- 否 --> J[尝试延续当前教室]
J --> K[生成新路径并加入队列]
H -- 否 --> L[尝试切换教室]
L --> M[生成新路径并加入队列]
K --> D
M --> D

数据库表
使用 TypeORM 同步和操作数据库。无论是 ChatGPT 还是 DS,都能很好地完成任务。

起名与域名注册
在 AI 的帮助下,构建它只花了一周,所以起名为 7Day。

部署
部署在校内 CLab。


更新日志
2025-09-16
- 🐞 修复无法按照校区、教学楼、楼层检索课程的问题(错误将区域 ID 当作教室 ID,ANTD 级联未设置只允许勾选叶子节点)。 @安茗炫
- 🆕 支持多关键词搜索课程中英文名称、描述。
- 💄 更新二维码、关于我们以及首页文案。
- 💄 更新项目依赖。