以 OUCHN 教育平台自动化脚本为案例,完整走一遍:需求分析 → 架构设计 → 核心开发 → 踩坑修复 → 持续迭代。920 行 Python,日均处理 20 门课、120+ 次页面操作。
需求:辅导老师的日常三件事
国家开放大学辅导老师每天要在学习网上做三件事:
| 任务 | 目标 | 痛点 |
|---|---|---|
| 浏览课程资源 | 100 页/天 | 20+ 门课,逐一点击 |
| 批改学生作业 | 不限 | 分布在多门课,每份需评分+评语 |
| 回复论坛帖子 | 10 条/天 | 要找帖子、写回复 |
技术约束:需要短信验证码登录(无法全自动)、前端是 Angular 1.x(DOM 操作无效,必须走 scope)、Cookie 约 7-10 天过期。
架构:一个文件搞定
CONFIG — 可调参数集中管理
Logger — 日志类(文件+控制台双写)
Stats — 统计类(计数+报告)
get_activities() — 获取活动列表(共享给子任务)
grade_course() — 批改作业(Angular scope 操控)
browse_course() — 浏览资源(多策略随机)
reply_forum() — 论坛回复
main() — 连接→登录→执行→报告
单文件 ~900 行。没有过度工程化——当功能规模在 1000 行以内时,文件拆分反而是负担。
核心技巧 1:活动列表共享
课程的活动列表只获取一次,三个子任务共享:
activities = await get_activities(page, course_id)
await browse_course(page, course_id, course_name, stats, activities)
await grade_course(page, course_id, course_name, stats, activities)
await reply_forum(page, course_id, course_name, stats, activities)
优化效果:浏览从 26 页 → 96 页 (+270%),批改从 30 份 → 62 份 (+107%)。每门课少掉了 2-3 次网络请求和 Angular 初始化等待。
核心技巧 2:Angular Scope 操作分步走
这是最复杂的部分。完整批改流程:
进入 full-screen 页面 → 等 10 秒(Angular 初始化慢)
→ 取 PagedSubmissionListController scope
→ 筛未评分学生
→ setViewingData(idx) 触发弹窗
→ 强制显示 modal(display:block)
→ 取 GiveScoreController scope
→ 设 score + comment,调 $apply()
→ 点"保存" → 隐藏 modal → 下一个
核心 JavaScript:
async (params) => {
var psc = document.querySelector(
"[ng-controller='PagedSubmissionListController']"
);
var s = angular.element(psc).scope();
await s.setViewingData(params.idx);
var m = document.getElementById('give-score');
m.style.display = 'block';
var g = angular.element(
document.querySelector("[ng-controller='GiveScoreController']")
).scope();
g.dataBindTo.score = params.score;
g.dataBindTo.reviewer_comment = params.comment;
g.$apply();
var btns = document.querySelectorAll('#give-score button');
btns.forEach(function(btn) {
if (btn.textContent.indexOf('保存') >= 0) btn.click();
});
return 'ok';
}
关键细节:setViewingData() 是异步的必须 await、弹窗可能是 display:none 需要暴力设 block、$apply() 不调 Angular 不会知道数据变了。
四个真实踩坑
坑 1 — Select2 组件选不中角色:jQuery UI MultiSelect 组件直接设 DOM value 无效。必须走 Angular scope:scope.conditions.role = ['assistant_instructor']; scope.search()。修复后课程从 83 门降到 20 门。
坑 2 — Angular 初始化太慢:full-screen 页面等 3 秒后取 scope 返回 undefined。调到 10-15 秒才稳定。
坑 3 — Cookie 失效静默失败一周:6/16-6/22 期间脚本全失败,但没报错——Cookie 失效后被重定向到登录页,拿不到数据就退了。加了登录态检测逻辑后不再漏报。
坑 4 — 页面被关闭导致下一门课报 Target closed:加了 ensure_page() 恢复函数,检测到页面关闭自动新建。
持续迭代
| 版本 | 改进 | 效果 |
|---|---|---|
| V1 | 基本功能 | 能浏览、能批改 |
| V2 | Cookie 持久化 | 不用每次登录 |
| V3 | 云端共享+多终端 | 家里办公室都能用 |
| V4 | 角色筛选+活动共享 | 性能提升 2-3 倍 |
每发现一个 bug,立即修到代码和 SKILL.md 里。 今天不修,下周就忘了上下文。
整套代码已在 WorkBuddy 上稳定运行,日均处理 20 门课、96 页浏览、62 份批改。关键不是代码多复杂,而是把坑都填平了。