Files
douyin_cookie_yunsya/README.md
T
travel cd65b4ccc9 docs: 补充不使用 Playwright 的详细技术说明
在 README 中说明 DOM 自动化脆弱性、风控冲突、二次验证、架构复杂度及 HTTP SSO 取舍,便于后续维护与部署决策。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-25 11:07:56 +08:00

6.8 KiB
Raw Blame History

抖音 Cookie 一键提取

扫码登录抖音后,自动导出 JSON 格式 Cookie。

原理

采用 HTTP SSO 接口(无需 Playwright / 浏览器):

  1. 注册 ttwid 设备标识
  2. 调用 passport/web/get_qrcodesso.douyin.com/get_qrcode 获取二维码
  3. 轮询 check_qrconnect 检测扫码状态
  4. 确认后跟随 redirect_url 完成会话,导出 Cookie

若服务器 IP 被抖音风控(错误码 4031),请配置住宅代理 API

为什么不使用 Playwright

本项目早期版本基于 Playwright + Headless Chromium 实现扫码登录,但在实际使用与维护中暴露出大量问题。经过多轮修复后,仍无法稳定支撑「一键提取 Cookie」这一核心目标,因此彻底移除 Playwright,改为直接调用抖音 Passport / SSO 的 HTTP 接口。

1. 登录流程依赖脆弱的 DOM 自动化

Playwright 方案需要模拟用户在网页上的每一步操作:

  • 打开 douyin.com 并点击「登录」
  • 切换到「扫码登录」标签
  • 从页面 <img> / <canvas> 中提取二维码
  • 扫码后识别「身份验证」弹窗,再自动点击「短信验证码」「发送验证码」等按钮
  • 跨 iframe、Shadow DOM 查找输入框并填入验证码

抖音前端 UI 频繁改版,按钮文案、CSS 类名、弹窗结构随时可能变化。任何一次改版都会导致:

  • 找不到登录入口或二维码
  • 误判登录状态(例如把「等待确认」当成「需要验证」)
  • 自动填验证码失败,用户无法完成二次验证

这类问题无法通过局部修补根治,因为本质是在用浏览器自动化对抗一个持续变化的前端

2. Headless 模式与风控冲突

无头浏览器(headless: true)极易触发抖音反爬与风控策略:

  • navigator.webdriver 等特征可被检测
  • 滑块、图形验证码在 headless 下几乎无法完成
  • 扫码后常出现二次验证(短信 / 密码 / 滑块),自动化脚本无法可靠处理

改为「可见浏览器 + 用户手动验证」虽能缓解,但又带来新问题:必须在服务器上弹出 GUI 窗口(Linux 无桌面环境不可用),且仍依赖 DOM 点击逻辑,并没有降低维护成本

3. 二次验证是最大不稳定因素

真实场景中,用户手机确认登录后,网页端仍可能要求:

  • 接收短信验证码
  • 验证登录密码
  • 完成滑块验证

旧方案试图用 Playwright 自动点击、自动填码、自动提交,实际效果很差:

  • 验证码输入框分布在不同 iframe 中,选择器经常失效
  • 轮询逻辑与用户手动操作互相覆盖(例如自动点击「接收短信」与用户选择密码验证冲突)
  • 提交按钮文案不统一(「确定」「提交」「验证」等),跨 frame 点击失败率高

Cookie 提取工具不应承担「代替用户在网页里完成风控验证」的职责;这类步骤更适合由用户在 App 或官方页面自行完成,服务端只负责检测登录结果。

4. 架构复杂、难以维护

Playwright 版本将全部逻辑塞在单文件 app.py(约 1200 行),并引入额外复杂度:

问题 说明
Flask 与 asyncio 桥接 需要自定义 run_async_sync() 和全局 event loop,易出现协程/线程竞态
浏览器生命周期 登录成功即关闭浏览器,调试困难;异常时容易残留僵尸进程
单全局会话 LoginSession + 锁,同一时刻仅支持一个扫码任务
部署依赖重 除 Python 外还需 playwright install chromium(数百 MB
二维码提取不可靠 常退化为「整页截图」,用户扫到的并非标准 QR

模块化拆分后,浏览器相关代码仍是最难测试、最难 Mock 的部分,投入产出比极低

5. 与项目目标不匹配

本项目的核心目标是:

扫码登录成功后,导出网页端可用的 Cookie JSON

完成这一目标,并不需要渲染完整页面,只需要走通抖音官方的 扫码 SSO 协议

get_qrcode → 展示二维码 → check_qrconnect 轮询 → redirect_url 换票 → 拿到 Cookie

这是一条稳定的 HTTP 状态机,与页面 DOM 无关。抖音网页版、创作者平台、早期开源项目均采用同一套 sso.douyin.com 接口,协议层比 UI 层可靠得多

6. HTTP SSO 方案的优势与代价

优势:

  • 无需安装 Chromium,部署仅需 pip install -r requirements.txt
  • 无 GUI / 无头浏览器依赖,适合 Linux 服务器与 Docker
  • 逻辑清晰:backend/sso/qr_login.py 独立维护,易于单测
  • 资源占用低:一个 requests.Session 即可,内存占用从数百 MB 降至数 MB
  • 前端只展示二维码与轮询状态,不再耦合浏览器截图、验证表单等复杂 UI

代价(需知晓):

  • 依赖抖音 SSO 接口,若接口参数变更需跟进适配
  • 部分机房 IP 会被风控(错误码 4031),需配置住宅代理 API
  • 若账号在 SSO 层仍要求额外验证,需用户在手机端完成;HTTP 层无法代替网页内操作

综合权衡:HTTP SSO 更轻、更稳、更易部署,更符合「一键提取 Cookie」的产品定位;Playwright 适合需要完整浏览器行为的场景(如自动化发帖、复杂交互),不适合作为 Cookie 提取的主路径

与其他方案对比

方案 说明 本项目
HTTP SSO 直接调用 passport / SSO 接口,轻量、可部署 当前采用
Playwright 模拟真实浏览器,重、易受 UI 改版影响 已移除(见上文)
开放平台 OAuth 需注册应用,返回 access_token 而非网页 Cookie 不适用
读取本机浏览器 Cookie 需用户事先在 Chrome 登录,非远程一键扫码 未采用

环境要求

  • Python 3.9+
  • Node.js 18+(仅构建前端时需要)

安装

pip install -r requirements.txt

cd frontend
npm install
npm run build

运行

py -3 app.py

访问:http://127.0.0.1:5001

环境变量

变量 默认值 说明
PORT 5001 服务端口
LOGIN_TIMEOUT 600 登录超时(秒)
QR_POLL_INTERVAL 2 建议前端轮询间隔
DOUYIN_AID 6383 抖音 Web 应用 ID
DOUYIN_SERVICE https://www.douyin.com SSO service 参数

API

接口 说明
POST /api/start_qr 获取二维码(HTTP SSO
GET /api/check_login 轮询扫码/登录状态
POST /api/reset 重置会话
GET /api/debug SSO 轮询调试信息
POST /api/test_proxy 测试代理

项目结构

app.py
backend/
  sso/qr_login.py      # HTTP 扫码登录核心
  cookies.py           # Cookie 检测
  routes/              # API + SPA
frontend/              # Vue 3 前端