Files
douyin-pc/docs/2026-09-06-10-54-windows-technology-stack.md
T

7.9 KiB
Raw Blame History

Windows 多账号监听与任务执行:技术栈评估

范围与结论

需求:Windows 上运行多个 Chrome 登录环境;一个账号持续监听通知,按规则将关注、私信任务分发给其它账号。本文按初期单机、小规模账号部署评估,不实施启动浏览器、登录、关注或发送消息。

推荐:Python 3.12 + asyncio + Playwright PythonCDP 接入)+ SQLite + 系统安装的 Chrome。需要桌面界面时增加 PySide6Windows 分发使用 PyInstaller,在 Windows 构建和验证。初期不用 Redis、Celery、微服务、Docker 或 Electron。

仓库调研

通过 CodeGraph 获取结构与相关函数源码,并查看私信脚本开头:

  • src/subscribe_notifications.py:通过 browser-harness 执行页面表达式、处理推送通知并获取详情。
  • src/follow_user.py:通过浏览器上下文中的 XHR 调用关注接口,包含当前账号检查、目标校验与结果回查。
  • src/douyin_im.py:在已登录页面发现 IM SDK 服务,通过 SDK 获取会话、读取和发送私信。
  • 当前模式依赖 browser-harness 子进程和当前选中页面,现有调用处未显式传入账号级 CDP 连接。这是多账号产品化需要解决的隔离点;并非声称 harness 本身不支持多连接。
  • 已有业务协议逻辑值得复用,但尚未进行 Windows 实机、多账号、长时间运行验证。

组件职责

建议 职责
核心 Python 3.12 复用现有业务代码,独立 CLI 入口
异步调度 asyncio 监听、分发、各账号串行消费、跨账号并发
浏览器接入 Playwright async API + connect_over_cdp 每个账号绑定独立连接;必要时 new_cdp_session 获取底层事件
浏览器管理 subprocess + pathlib 启动系统 Chrome,管理端口、目录与进程
持久化 sqlite3 账号映射、事件去重、任务状态、恢复依据
配置与日志 json + logging 环境无关配置、滚动日志、敏感数据脱敏
桌面界面(可选) PySide6 账号状态、启停、待人工处理队列
打包 PyInstaller Windows 原生构建,先 onedir

Playwright 仅作为 CDP 连接和 JS/网络事件通道,不建议把点击按钮、输入文本或遍历 DOM 作为最终业务方案。保留浏览器内接口/SDK 执行方式与完全脱离浏览器的 HTTP 客户端是不同目标。当前代码依赖前者;若要求后者,需另行验证签名、令牌、长连接协议,不应只替换成 httpx 后承诺可用。浏览器内部 SDK 属于非公开稳定契约,页面更新可能使其失效。

Chrome 隔离

每个账号使用一个独立 user-data-dir、一个独立 Chrome 主实例及一个独立 CDP 端口。例如 listener/9222、worker-a/9223、worker-b/9224。端口只是示例,应可配置并在启动时检查冲突。不要仅依赖同一个 User Data 下的 --profile-directory 来实现独立进程与独立 CDP。

命令形态:

& $ChromeExe --remote-debugging-port=9222 --user-data-dir="$env:LOCALAPPDATA\DouyinController\profiles\listener"

ChromeExe 由配置或常见安装位置发现,不硬编码机器路径。同一目录不允许多个实例并发使用,也不要在 Chrome 运行时复制目录。每个新目录由用户首次手动登录,之后由 Chrome 保存登录状态。Chrome 136 起远程调试参数对默认数据目录有限制,应使用非默认 user-data-dir;本次未成功拉取官方页面,版本细节应在选定 Windows/Chrome 版本上复核。

CDP 不应对公网或局域网开放;检查实际监听地址,仅允许本机访问,不关闭安全防护。账号配置保存预期 UID;每次执行写操作前校验实际 UID,不能用第一个标签页或端口号代替身份验证。

最小执行模型

  1. 监听账号收取事件,先持久化并去重,再按规则生成执行任务。
  2. 一个进程运行调度器和多个异步账号 worker,每个账号串行执行,不需要每账号一个 Python 进程。
  3. SQLite 是任务真源,asyncio.Queue 只是进程内唤醒/排队手段。任务至少记录来源事件、执行账号、动作、目标、参数、状态及错误。
  4. 用唯一约束避免重复派发同一事件/执行账号/动作/目标的任务;同一事件允许多条同类动作时还需规则步骤标识。
  5. 状态可采用 pending/running/succeeded/failed/unknown。进程重启时不能把所有 running 直接重新执行,需先核对结果。
  6. 私信发送超时不代表发送失败;无法确认时标记 unknown,人工核对或基于 SDK 消息标识查询,不能盲目重发。关注也应回查状态。
  7. 若规则要求先关注再私信,按同一账号任务步骤执行,并以明确成功条件决定下一步,而不是只靠队列插入顺序。
  8. 登录失效、验证码或风控立即暂停对应账号并提示用户,不自动登录或绕过验证。监听账号失效时停止新的派发。
  9. 页面刷新/连接断开后需重连并重新安装订阅;断线期间事件是否可补拉,需按现有通知接口验证,不能承诺推送零丢失。

Windows 注意事项

  • 核心可跨平台开发,浏览器启动、中文路径、权限、打包、休眠恢复必须在 Windows 实测。
  • Chrome 与登录界面运行在交互式用户会话,初期不做 Windows ServiceSession 0 与桌面隔离)。可用任务计划程序在用户登录后启动,设置“仅当用户登录时运行”。
  • Windows 休眠/网络断开会打断监听。运行时要有心跳、离线状态与恢复流程;不要宣称普通桌面进程天然 24 小时可靠。
  • 多账号通常主要消耗 Chrome 内存和 CPU,先按实际账号数量测量,不先承诺单机容量。
  • 引入 PySide6 后,Qt 主线程处理 UI,asyncio 核心置于独立线程,用 Qt 信号传递状态,避免阻塞界面;初期 CLI 无需承担这层复杂度。
  • 打包不是加密。保护 profile 目录和任务数据库,不记录 Cookie、令牌或完整带签名 URL,私信内容按最小必要原则保存。

空白 Windows 环境安装(推荐方案,不表示当前脚本已迁移)

安装 Windows 版 Python 3.12 和 Chrome,在 PowerShell 执行:

py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install playwright
# 仅需要桌面界面或打包时安装:
.\.venv\Scripts\python.exe -m pip install PySide6 pyinstaller

只通过 connect_over_cdp 连接系统 Chrome 时,无需 playwright install 下载配套 Chromium。实际交付时锁定实测依赖版本。当前已有脚本仍调用 browser-harness,以上依赖不会自动替换现有桥接代码。首次迁移优先明确账号级连接,再复用原有通知、关注与 IM 业务函数。

其它选型

  • 若团队以 C# 为主、Windows 桌面交付是最高优先级,可选 .NET LTS + WPF + Microsoft.Playwright + SQLite;代价是重写或桥接现有 Python 逻辑。
  • Node.js + Playwright 也可行,但对当前 Python 项目收益不明显;Electron 不会替代那些实际登录的 Chrome 实例,反而增加一套前端运行环境。
  • 多机部署或单进程调度确实成为瓶颈时,再考虑服务端数据库、远程队列和 worker 服务。

调研限制与参考

本次通过 fetch_content 尝试读取以下官方资料,工具因 DNS 映射至 198.18.0.0/15 的 SSRF 防护拒绝请求,未更改网络安全配置。下列链接供复核,不能视为本次已经成功读取的证据:

本次结论依据仓库可见代码与通用平台约束。未进行 Windows 实机测试、接口稳定性保证或平台自动化权限核验。关注与私信仅在账号授权、平台规则允许、避免骚扰的前提下使用;支持配额、暂停与审计,不以多账号切换规避限制。