DouBao2Api/README.md

261 lines
10 KiB
Markdown
Raw Permalink Normal View History

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 代理
## 免责声明
本项目仅供学习和研究用途。使用前请确保遵守豆包的服务条款。作者不对因使用本项目而产生的任何直接或间接后果承担责任。