585a7a28dd
- settings: study.mode fast|normal and study.parallel 1-5 - normal mode: one headless browser per video, visibility keep-alive, auto-degrade when the platform enforces order - report study/log/detail/save before isComplete; drop lastProgressTime on completion - complete periodType 10/13 container nodes and recompute counters via PUT calFinalScore - capture mode: POST /api/capture records all XHR/fetch including new tabs - UI: study mode in settings, capture / stop-capture menu items
80 lines
4.5 KiB
Markdown
80 lines
4.5 KiB
Markdown
# TODO
|
||
|
||
## 待修复:首次进入课程会弹提示挡住,必须手动点一下才能进课程
|
||
|
||
**状态**:暂停(2026-10-27 18:27)。现象确认存在,但还没抓到具体弹窗,修复方案未定。
|
||
|
||
### 现象
|
||
|
||
- 一个课程/课时**第一次**进入时,页面会先出提示(弹层/遮罩/确认框),不点它进不去。
|
||
- 手动点一下之后就能正常进入、正常播放;再进同一门课就不再出现。
|
||
- 因为卡在这一步,自动学习流程跑不下去,只能人工点。
|
||
|
||
### 需要先确认(下一步的起点)
|
||
|
||
1. 那个提示到底是哪一层的东西,三选一:
|
||
- 培训平台(`study.dgjy.net`)自己的「学习须知 / 继续学习 / 我已知晓」弹层;
|
||
- 播放页 `courseVideo` 里的播放前确认(点「开始学习」才 load video);
|
||
- 浏览器层的 autoplay / 全屏 / 权限提示。
|
||
2. 弹层出现的确切条件(首次进课程?首次进课时?换设备/换浏览器算不算首次?)。
|
||
3. 点掉它之后前端发了什么请求(有没有 `period/study/log`、`student/join` 之类)。
|
||
|
||
### 已排查到的线索
|
||
|
||
- 触发点在「进入课程 → 课时」这条路径上,接口层面看不出来:
|
||
`app.py` 的学习主流程是纯 HTTP(`study_complete_period` → `period/study/log`),
|
||
只有 `kind == "direct"` 的直链视频才用 Playwright 开真浏览器(`play_period_to_end`,app.py:1664)。
|
||
- `play_period_to_end` 里已经有一处「盲点确定」的补丁,说明历史上就撞过类似弹层:
|
||
|
||
```python
|
||
ok = pg.query_selector(".el-message-box__btns .el-button--primary")
|
||
if ok:
|
||
ok.click()
|
||
```
|
||
|
||
但它只在视频开始播放**之后**每 2 秒点一次,且只认 Element-UI 的 message-box;
|
||
如果是进入页面时的 `el-dialog` 遮罩,这个选择器打不中。
|
||
- 新版平台课程页地址(`discover()` 拿到的 `page_url`,日志里 token 打码):
|
||
`https://study.dgjy.net/training/trainDetails?id=<trainCourseId>&isFront=1`
|
||
- 课程页点「继续学习」后跳到课时列表页:
|
||
`https://study.dgjy.net/training/curriculum?id=<moocCourseId>&isFront=1&courseId=<trainCourseId>`
|
||
视频课时在 `period/list/tree/studyLog` 里,`periodType=2`,`file.fileType=mooc_video`。
|
||
- 播放页拼法见 app.py:1675:
|
||
`https://study.dgjy.net/training/courseVideo?classhour=<periodId>&isJoin=1&needJoin=1&courseId=<trainCourseId>&isFront=1&trainCourseId=<trainCourseId>`
|
||
|
||
### 为什么这次没抓到
|
||
|
||
演示账号(库里唯一账号)的两门课 12 + 14 个课时**全部已 `completeTime` 有值**,
|
||
「首次进入」的前置状态已经不在了,弹层复现不出来。
|
||
下次要么换一个没学过的账号/课程,要么把某个课时的 `studyLog` 清掉再试。
|
||
|
||
### 下次的复现 + 取证办法
|
||
|
||
用带界面的 Playwright 窗口,把登录后的 cookie 注进去,人工在窗口里点到弹层出现:
|
||
|
||
1. `python -c` 跑一遍 `app.login(user, pw)`,把 `sess.cookies`(只取 `*.dgjy.net`)写成 JSON;
|
||
2. `launch_persistent_context(headless=False)`,`ctx.add_cookies(...)`,`goto` 课程页;
|
||
3. 同时挂:
|
||
- `page.on("request"/"response")` 全量记录(过滤掉 png/css/font);
|
||
- `document.addEventListener('click', ..., true)` 记录 `target` 的 CSS 路径和文字;
|
||
- 每 2 秒 `page.screenshot()` 一张;
|
||
- 每 2 秒扫一次可见的 `.el-message-box / .el-dialog / [role=dialog]`,把 `innerText` 落日志。
|
||
4. 人工点掉弹层 → 看日志里「点击前后出现了哪个 dialog 文本 + 紧随其后的请求」,就知道该自动点哪个。
|
||
|
||
### 修好后要做到
|
||
|
||
- 自动学习时不再需要人工点一下:进课程/进课时后若出现确认弹层,自动识别并点掉,
|
||
再继续走 `period/study/log` 或 `courseVideo` 播放。
|
||
- 只点「继续/确定/我已知晓」这类无副作用的按钮,别乱点「提交/评价」。
|
||
- 日志里留下「已自动关闭弹层:<文字>」,方便出问题时对账。
|
||
|
||
### 相关代码位置
|
||
|
||
| 位置 | 作用 |
|
||
| --- | --- |
|
||
| `app.py:1664` `play_period_to_end` | 直链视频真播;已有盲点 `.el-message-box__btns .el-button--primary` |
|
||
| `app.py:1530` `run_study_course` | 新版平台课程主流程(反馈表 / 测验 / 视频) |
|
||
| `app.py:1013` `discover_study` | 读课程结构,产出 `page_url` / `train_id` / `courseware` |
|
||
| `app.py:1128` `study_period_log` | 课时上报接口,`isComplete` 走这里 |
|
||
| `app.py:633` `_discover_once` | jspx 课程页 → study `trainDetails` 的跳转与 token 落 cookie |
|