2026-08-20 03:24:19 +00:00
|
|
|
|
# DouBao2Api
|
|
|
|
|
|
|
2026-08-20 11:32:32 +08:00
|
|
|
|
将网页版豆包(doubao.com)转换为 OpenAI 兼容 API 的 Docker 化方案。通过 VNC + Playwright 模拟真人浏览器操作,间接发送消息并捕获回复,对外暴露标准 `/v1/chat/completions` 接口。
|
|
|
|
|
|
|
|
|
|
|
|
<div align="center">
|
|
|
|
|
|
<br>
|
|
|
|
|
|
|
|
|
|
|
|
[**中文**](README.md) | [English](README_EN.md)
|
|
|
|
|
|
|
|
|
|
|
|
<br>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
## 工作原理
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
┌──────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ 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. 构建与启动
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
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. 保存登录状态
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl -X POST http://localhost:8000/login/save
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 调用 API
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 非流式
|
|
|
|
|
|
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 模式(服务端强制):
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 切换到交互模式
|
|
|
|
|
|
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 代理
|
|
|
|
|
|
|
|
|
|
|
|
## 免责声明
|
|
|
|
|
|
|
|
|
|
|
|
本项目仅供学习和研究用途。使用前请确保遵守豆包的服务条款。作者不对因使用本项目而产生的任何直接或间接后果承担责任。
|