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