1. 项目背景与需求分析
作为一名在南京理工大学就读的学生,我每天都需要关注学校十几个部门网站的通知公告。教务处、研究生院、学工处、创新创业学院...每个网站的通知发布频率不同,页面结构各异,手动检查不仅耗时耗力,还经常遗漏重要信息。
去年我就因为错过了教务处发布的选课通知,导致只能选到别人挑剩下的课程。这种经历让我意识到:信息获取的效率直接影响学业规划的质量。于是我开始思考如何用技术手段解决这个问题。
传统解决方案是写个爬虫,但存在几个痛点:
- 学校部分网站有反爬机制,普通requests无法获取内容
- 不同部门的网页结构差异大,需要定制化解析
- 需要定期手动运行脚本,缺乏即时性
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术方案设计
2.1 整体架构
项目采用"数据采集+智能展示"的双层架构:
code复制[爬虫引擎] → [数据标准化] → [AI Skill接口] → [用户交互]
2.2 核心组件
2.2.1 双引擎爬虫系统
针对不同网站的反爬策略,我们设计了两种抓取方式:
- 轻量级引擎(requests+BeautifulSoup)
- 适用:研究生院等无反爬的网站
- 特点:速度快,资源占用低
- 示例代码:
python复制def get_with_requests(url):
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get(url, headers=headers)
return BeautifulSoup(response.text, 'html.parser')
- 浏览器引擎(DrissionPage)
- 适用:教务处等有反爬的网站
- 特点:模拟真实浏览器行为
- 配置要点:
python复制from DrissionPage import ChromiumPage
def get_with_browser(url):
page = ChromiumPage()
page.get(url)
page.wait.ele_displayed('#content') # 关键:等待元素加载
return page.html
2.2.2 智能解析系统
针对四种常见页面结构,我们开发了对应的解析器:
| 页面类型 | 特征 | 解析方法 | 示例网站 |
|---|---|---|---|
| 列表型 | ul.news_ul | CSS选择器提取li元素 | 研究生院 |
| 卡片型 | div.news-item | 定位标题和日期块 | 学校主页 |
| 表格型 | table tr | 遍历行提取td内容 | 教务处 |
| 文章型 | li.list_item | 解析article结构 | 学工处 |
实际开发中发现,学校网站的div类名经常变化,但整体结构相对稳定。因此我们选择基于DOM结构而非class名进行解析,提高了容错性。
3. 实现细节
3.1 核心代码结构
项目采用模块化设计,主要文件结构:
code复制njust_monitor/
├── __init__.py
├── engines/ # 爬虫引擎
│ ├── base.py
│ ├── requests.py
│ └── browser.py
├── parsers/ # 页面解析器
│ ├── news_ul.py
│ ├── news_list.py
│ ├── article.py
│ └── table.py
└── utils/
├── date_utils.py # 日期处理
└── log_utils.py # 日志记录
3.2 关键实现逻辑
3.2.1 智能路由系统
根据URL自动选择最优爬取策略:
python复制def get_optimal_engine(url):
if 'gs.njust.edu.cn' in url: # 研究生院
return RequestsEngine()
else: # 其他有反爬的网站
return BrowserEngine()
3.2.2 自适应解析
通过特征检测自动匹配解析器:
python复制def auto_detect_parser(html):
if html.select('ul.news_ul'):
return NewsUlParser()
elif html.select('div.news-item'):
return NewsListParser()
# 其他类型检测...
3.3 性能优化
- 并发处理:
python复制from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor(max_workers=4) as executor:
results = list(executor.map(fetch_site, urls))
- 缓存机制:
- 使用磁盘缓存避免重复抓取
- 设置合理的TTL(默认1小时)
4. 部署与集成
4.1 Claude Code集成
配置步骤:
- 在
~/.claude/commands/创建njust.md - 设置执行权限:
chmod +x njust_monitor.py - 测试命令:
/njust
注意:Windows系统需要将python路径加入环境变量
4.2 OpenClaw集成
更推荐这种方式,因为:
- 支持定时任务
- 有完善的日志系统
- 可以对接飞书等IM工具
配置示例:
markdown复制---
schedule: "0 9 * * *" # 每天9点执行
notify:
- feishu: "xxxxx"
---
5. 使用技巧与经验
5.1 实用技巧
- 快速添加监控站点:
code复制/add_monitor https://new.site.edu.cn
系统会自动分析页面结构并生成解析规则
- 自定义过滤条件:
python复制# 在config.ini中添加
[filter]
keywords = 选课, 考试, 奖学金
5.2 常见问题解决
问题1:返回空结果
- 检查网站是否改版
- 尝试手动访问确认是否有反爬
问题2:日期解析错误
- 更新utils/date_utils.py中的正则表达式
- 常见日期格式已内置支持
问题3:浏览器引擎卡死
- 增加超时设置:
page.set.timeout(30) - 检查Chromium版本是否兼容
6. 扩展与优化
6.1 后续改进方向
- 智能去重:
- 使用SimHash算法识别相似通知
- 建立关键词黑白名单
- 自动摘要:
python复制from transformers import pipeline
summarizer = pipeline("summarization")
summary = summarizer(article_text)
- 多平台通知:
- 支持微信/邮件/短信推送
- 重要通知即时提醒
6.2 架构演进
计划引入:
- Redis缓存加速
- Celery任务队列
- Prometheus监控
这个项目最让我自豪的是它解决了真实存在的痛点。技术不在于多复杂,而在于能否创造实际价值。通过将爬虫与AI Skill结合,我们实现了:
- 自动化:解放人力,避免遗漏
- 智能化:统一入口,自然交互
- 可扩展:轻松添加新监控源
如果你也在为类似的信息获取问题困扰,不妨从这个案例出发,定制属于自己的信息助手。记住,好的工具应该像空气一样存在——你需要时它就在,但感受不到它的负担。
