7.7 KiB
0.1.4:修复新点赞、评论推送无法取得详情
结论及上一版的不足
用户在 0.1.3 中继续实测:不再整组暂停,但新点赞和评论仍无法取得详情。上一版只解决了阻塞;仅凭 HTTP 200、业务码 0、列表为空,就认为某条通知不可用,证据不充分。
本次同一登录浏览器、同一批 ID 的对照结果:
| 请求方式 | 结果 |
|---|---|
| 原有简化 fetch | HTTP 200、status_code=0、详情为 null |
| fetch 增加 channel_pc_web | 仍为 null |
| 原生 XHR,简化参数 | 已带浏览器 SDK 附加的校验字段,仍为 null |
| 原生 XHR,再增加 channel_pc_web | 仍为 null |
| 网页导出的 getNoticeDetail | 返回完整的 2 条:点赞和评论 |
| 修复后的共用请求函数 | 返回同样 2 条,账号、ID 均匹配 |
根因定位在原来的详情请求构造方式:它绕过网页完整请求层,只发送手工拼接的少量参数。不是推送 ID 取错,也不能归结为简单漏一个 channel 或使用了 fetch 而非 XHR。
已确认网页请求层还会补充 update_version_code、客户端/浏览器/设备字段、webid、uifid 等运行时参数,并使用网站现有 HTTP 客户端。未逐个隔离所有字段和请求头,因此不声称某一个字段单独决定结果;直接复用完整请求层,不手工模拟它。
调研过程与安全边界
- 通过 Windows MCP 操作“停止全部”,保留两个账号的浏览器和登录目录。未关闭持久化规则,未启动业务。
- SSH 只读读取实际数据库和 instance.json,确定唯一待排查主账号;CDP 经仅绑定本机的临时 SSH 转发提供给独立命名的 browser-harness 会话。
- 核对自身资料与既有绑定 UID 一致,再进行详情请求。
- 在已加载的 Webpack 模块中定位 getNoticeDetail 及其底层 GET 请求函数;观察请求字段名和原始响应类型,不保存令牌或原始账号数据。
- 原生客户端使用 Axios/XHR;response.request.responseText 可取得尚未经过 JS JSON 解析的响应原文。
- 新增独立只读监听,用户确认新点了一次赞并留了一条评论,再按真实推送 ID 请求详情。
- 完成后移除自己的监听和响应观察器、关闭临时转发,删除临时真实 ID 文件;用户浏览器保留。
所有主动详情请求都设置 is_mark_read=0。未执行关注、私信、标记已读或自动登录。真实账号数据库仅以 mode=ro 打开;调度入库验证使用一次性数据库。
最小代码改动
共用原生请求函数
src/subscribe_notifications.py::detail_request_script():
- 输入必须是非空 list/tuple,元素为 ASCII 十进制字符串。
- 仅在 https://www.douyin.com 执行。
- 根据导出名 getNoticeDetail 动态定位 SDK,不写死本次调研观察到的模块编号。
- 通过 SDK 发送 id_list,保持 type=0、is_mark_read=0,由网站自行补全环境参数和请求处理。
- 临时添加 Axios 响应观察器,只匹配同源详情路径、本次 id_list 和 is_mark_read=0。
- 原样返回响应对象,不修改站点请求、响应或全局 XMLHttpRequest。
- 将匹配 XHR 的 HTTP 状态与 responseText 包装成字符串交给 Python 解析,避免 SDK 的 JSON.parse 舍入 64 位整数。
- 成功、异常和 20 秒等待超时都在 finally 中清理观察器与计时器。超时不会改动网页自身请求生命周期。
- SDK 缺失、请求失败或拿不到响应原文时明确失败,不回退到已证实不可靠的简化 fetch,也不输出敏感 SDK 原始错误。
src/account_session.py::Session.details() 和独立订阅脚本的 details() 共用上述实现。桌面路径的 HTTP、业务码、结构、请求 ID 集合、所属 UID 校验继续保留;不放宽账号隔离。
0.1.3 的逐 ID 持久化退避继续作为真正缺失通知的保护,不再被当成详情请求故障的替代修复。本次没有新增依赖、变更数据库结构或改变关注/私信的执行规则。
验证证据
用户现场新增事件
挂好独立监听后,用户确认新增了点赞和评论:
{
"fresh_push_ids": 2,
"detail_rows": 2,
"all_requested": true,
"all_identity_verified": true,
"kinds": ["comment", "digg"],
"raw_numeric_ids_exact": true,
"real_write_actions": 0
}
这是新事件的“推送 → 提取 ID → 原生详情请求 → 完整响应”验证,不是只使用历史通知,也不是仅观察错误提示消失。
Windows 实际产品代码、临时入库
上传产品源码后,再通过 Patchright 的 Session.details() 和 Engine.collect_details() 处理同两个新 ID;Engine 只绑定临时数据库,规则默认关闭且不启动业务。
{
"fresh_detail_count": 2,
"kinds": ["comment", "digg"],
"all_ids_processed": true,
"raw_ids_exact": true,
"real_database_unchanged": true,
"real_write_actions": 0
}
临时 inbox 两条均 done,无任务;实际 accounts、inbox、tasks 表在验证前后内容一致。实际程序仍停止,所以调研捕获的新事件不会被偷偷导入真实业务队列。
回归与打包
- Linux、Windows 完整 pytest:52 项通过。
- 5 个相关 Python 文件的主 LSP 错误检查:0 诊断。
- 新 Node 离线检查覆盖 SDK 选择、只读参数、原文精度、返回对象不变、正常/失败/SDK 缺失/原文缺失/超时后的观察器清理。
- Windows fingerprint-chromium 矩阵通过新增
native_detail_transport_partial_null_precision_and_cleanup:实际 XHR 访问离线模拟接口,要求 SDK 专有标记,验证部分结果、null、64 位 ID 和原有观察器保留。 - 原有身份隔离、独立目录/端口、固定种子、登录回填、重启持久化和浏览器保留等矩阵项全部通过。
- Windows 构建成功,全部 21 个 Python 源文件摘要与发布清单一致。
- 运行依赖和浏览器版本不变:fingerprint-chromium 148.0.7778.215、Patchright 1.62.3;没有改用系统 Chrome,也没有增加自动化启动标志。
离线复测:
python -m pip install -r requirements-test.txt
python -m pytest -q
python src/test_subscribe_notifications.py
Windows 浏览器矩阵与构建沿用现有离线打包环境:
.venv\Scripts\python.exe src\test_browser_matrix.py --chrome .build-cache\fingerprint-runtime\chrome.exe --report browser-matrix-native-detail.json
.venv\Scripts\python.exe build_windows.py
空白环境构建说明见 Windows 构建指南 和 指纹浏览器迁移说明。最终用户只需要安装包,不需要单独安装 Python、Node 或浏览器。
发布
C:\Users\rogee\Desktop\抖音账号助手-0.1.4\
DouyinAccounts-0.1.4-Windows-x64-Setup.exe
SHA256SUMS.txt
使用说明.txt
- 安装包大小:222,679,336 字节。
- SHA256:
f350b9fc1e7910776cb107c6906ba85cc82043112d63999d06412c4821ea1b56。 - 桌面发布副本已再次校验哈希。
- Windows 构建目录保留
native-live-proof.json、tests-native-detail.log、browser-matrix-native-detail.json、build-native-detail.log和dist/DouyinAccounts/build-manifest.json。
没有代用户安装或重启业务。最终只读检查:两个账号仍已停止,浏览器保留,实际任务表为空;原有 2 条 pending ID 和已启用规则保持不变。用户退出旧程序覆盖安装后手动启动,再由正常流程处理到期旧 ID 和新通知;无需删除账号或登录目录。
本次验证覆盖详情链路和临时入库,不声称实测了真实自动关注/私信,也不承诺平台无法检测浏览器。后续网页 SDK 若变化,将失败关闭并需要适配。安装体验仍由用户验收。