10 KiB
DouBao2Api
将网页版豆包(doubao.com)转换为 OpenAI 兼容 API 的 Docker 化方案。通过 VNC + Playwright 模拟真人浏览器操作,间接发送消息并捕获回复,对外暴露标准 /v1/chat/completions 接口。
工作原理
┌──────────────────────────────────────────────────────────┐
│ Docker 容器 (RockyLinux 9) │
│ │
│ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │
│ │ Xvfb │──│ openbox │──│ Chromium │──│Playwright│ │
│ │ 虚拟显示 │ │ 窗口管理器 │ │ 浏览器 │ │ 自动化 │ │
│ └─────────┘ └──────────┘ └──────────┘ └────────┘ │
│ │ │ │
│ │ ┌──────────┐ │ │
│ └──────────│ x11vnc │◄───────────────────┘ │
│ │ VNC 服务 │ │
│ └────┬─────┘ │
│ │ │
│ ┌────┴─────┐ ┌──────────┐ │
│ │websockify│──│ noVNC │ │
│ │ 代理 │ │ Web 客户端 │ │
│ └──────────┘ └──────────┘ │
│ │
│ ┌──────────────────────┐ │
│ │ FastAPI (端口 8000) │ │
│ │ OpenAI 兼容 API │ │
│ └──────────────────────┘ │
└──────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
API :8000 VNC :5900 noVNC :6080
核心流程:API 收到请求 → Playwright 在 Chromium 中操作豆包页面(输入消息、Enter 发送) → DOM 轮询捕获流式回复 → 以 SSE 或 JSON 返回。
功能特性
- OpenAI 兼容:标准
/v1/chat/completions接口,支持流式(SSE)和非流式响应 - VNC 可视化:通过 noVNC Web 客户端实时查看浏览器画面,支持只读/交互切换
- 反检测:Playwright stealth 脚本隐藏 webdriver 标志,模拟人类打字延迟
- 会话持久化:登录状态通过
storage_state保存到 Docker volume,重启免登录 - 聊天复用:默认复用当前聊天会话,降低风控风险;支持按需新建对话
- 调试端点:
/inspect返回页面 DOM 结构,方便选择器适配
快速开始
1. 构建与启动
docker compose build
docker compose up -d
2. 登录豆包
容器启动后,浏览器打开 noVNC:
http://localhost:6080/vnc.html
VNC 密码:doubao123(可在 docker-compose.yml 中修改 VNC_PASSWORD)
noVNC 默认为只读模式(防止误触)。在左侧设置面板取消勾选 "View Only" 即可切换到交互模式。
在 VNC 中的 Chromium 浏览器里登录豆包账号,确认能看到聊天输入框。
3. 保存登录状态
curl -X POST http://localhost:8000/login/save
4. 调用 API
# 非流式
curl http://localhost:8000/v1/chat/completions \
-H "Authorization: Bearer sk-your-api-key-here" \
-H "Content-Type: application/json" \
-d '{"model":"doubao-pro","messages":[{"role":"user","content":"你好"}]}'
# 流式
curl http://localhost:8000/v1/chat/completions \
-H "Authorization: Bearer sk-your-api-key-here" \
-H "Content-Type: application/json" \
-d '{"model":"doubao-pro","messages":[{"role":"user","content":"你好"}],"stream":true}'
配置项
所有配置通过环境变量设置,在 docker-compose.yml 或 .env 中修改:
| 环境变量 | 默认值 | 说明 |
|---|---|---|
API_KEY |
sk-your-api-key-here |
API 鉴权密钥,客户端需在 Header 中携带 Authorization: Bearer <key> |
API_PORT |
8000 |
API 服务端口 |
VNC_PASSWORD |
doubao123 |
VNC 连接密码 |
VNC_VIEW_ONLY |
false |
x11vnc 服务端是否强制只读(true 时即使 noVNC 取消勾选也无法操作) |
VNC_PORT |
5900 |
VNC 直连端口 |
NOVNC_PORT |
6080 |
noVNC Web 客户端端口 |
DOUBAO_URL |
https://www.doubao.com/chat/ |
豆包聊天页面 URL |
BROWSER_HEADLESS |
false |
浏览器是否无头模式(VNC 方案需设为 false) |
RESPONSE_TIMEOUT |
120 |
响应超时时间(秒) |
TYPING_DELAY_MIN |
30 |
打字延迟下限(毫秒/字符) |
TYPING_DELAY_MAX |
80 |
打字延迟上限(毫秒/字符) |
INTER_MESSAGE_DELAY |
0.5 |
消息发送前等待时间(秒) |
SCREEN_WIDTH |
1280 |
虚拟屏幕宽度 |
SCREEN_HEIGHT |
720 |
虚拟屏幕高度 |
SCREEN_DEPTH |
24 |
虚拟屏幕色深 |
LOG_LEVEL |
INFO |
日志级别 |
API 接口
POST /v1/chat/completions
OpenAI 兼容的对话接口。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
model |
string | doubao-pro |
模型名称 |
messages |
array | 必填 | 消息数组,同 OpenAI 格式 |
stream |
bool | false |
是否流式返回 |
new_chat |
bool | false |
是否新建聊天会话(自定义扩展字段) |
GET /v1/models
返回支持的模型列表。
GET /login/status
检查当前豆包登录状态。
POST /login/save
保存当前浏览器状态(cookies、storage)到磁盘。
POST /chat/new
显式开启新的豆包聊天会话。
GET /inspect
返回当前页面的 DOM 结构信息,用于调试选择器。
GET /vnc/mode
查看当前 VNC 模式(viewonly 或 interactive)。
POST /vnc/mode
切换 VNC 模式(服务端强制):
# 切换到交互模式
curl -X POST http://localhost:8000/vnc/mode \
-H "Authorization: Bearer sk-your-api-key-here" \
-H "Content-Type: application/json" \
-d '{"mode":"interactive"}'
# 切换到只读模式
curl -X POST http://localhost:8000/vnc/mode \
-H "Authorization: Bearer sk-your-api-key-here" \
-H "Content-Type: application/json" \
-d '{"mode":"viewonly"}'
POST /browser/restart
重启浏览器会话。
GET /health
健康检查端点。
VNC 模式说明
提供两层只读控制:
| 层级 | 控制方式 | 默认 | 说明 |
|---|---|---|---|
| 客户端 | noVNC 侧边栏 "View Only" 勾选框 | 勾选(只读) | 取消勾选即时切换到交互模式,刷新后恢复只读 |
| 服务端 | API POST /vnc/mode |
interactive |
viewonly 模式下 x11vnc 拒绝所有输入,即使客户端取消勾选也无效 |
日常使用:客户端层即可满足需求。如需更强控制(防止任何 VNC 客户端操作),使用 API 切换服务端模式。
项目结构
DouBao2Api/
├── Dockerfile # Docker 镜像构建文件
├── docker-compose.yml # 容器编排配置
├── requirements.txt # Python 依赖
├── .env.example # 环境变量模板
├── app/
│ ├── __init__.py
│ ├── config.py # 配置管理(pydantic-settings)
│ ├── models.py # OpenAI 兼容数据模型
│ ├── browser_manager.py # Playwright 浏览器管理
│ ├── doubao.py # 豆包页面交互逻辑
│ └── main.py # FastAPI 服务入口
└── scripts/
├── entrypoint.sh # 容器入口脚本
├── supervisord.conf # 进程管理配置
├── start_wm.sh # 窗口管理器启动脚本
└── start_x11vnc.sh # x11vnc 启动脚本(支持只读/交互切换)
进程架构
容器内通过 supervisord 管理五个进程,按优先级启动:
| 优先级 | 进程 | 说明 |
|---|---|---|
| 10 | Xvfb | 虚拟帧缓冲 X 服务器 |
| 20 | openbox | 轻量级窗口管理器 |
| 30 | x11vnc | VNC 服务器,映射 Xvfb 显示 |
| 40 | websockify | WebSocket 代理,提供 noVNC Web 访问 |
| 50 | uvicorn | FastAPI 应用服务器 |
常见问题
构建失败:找不到包
本项目基于 RockyLinux 9。RHEL 10 / RockyLinux 10 移除了 X11 server 包,不支持本方案。Docker 容器独立于宿主系统,在 RL10 宿主上运行 RL9 容器完全兼容。
API 返回空响应
豆包前端更新可能导致 CSS 选择器失效。调用 GET /inspect 查看当前 DOM 结构,然后修改 app/doubao.py 中的选择器常量。
提示 "Not logged in"
需先通过 VNC 浏览器登录豆包,再调用 POST /login/save 保存状态。调用 GET /login/status 检查登录状态。
VNC 无法操作
确认 noVNC 侧边栏 "View Only" 已取消勾选。若仍无法操作,检查服务端模式:GET /vnc/mode,如为 viewonly 则调用 API 切换为 interactive。
技术栈
- RockyLinux 9 — 容器基础系统
- Xvfb + x11vnc + noVNC — 虚拟显示与远程查看
- Playwright — 浏览器自动化
- FastAPI + Uvicorn — API 服务
- Supervisor — 进程管理
- websockify — VNC over WebSocket 代理
免责声明
本项目仅供学习和研究用途。使用前请确保遵守豆包的服务条款。作者不对因使用本项目而产生的任何直接或间接后果承担责任。