构建一个基于 Python 的在线 Web 截图服务,提供一个Web 前端管理 Docker 中的 Chrome(使用镜像 selenium/standalone-chrome:latest)并能实时预览容器内 Chrome 页面的能力。目标用户为需要远程批量抓取页面截图、生成缩略图以及人工审核/预览页面渲染效果的产品/测试人员。
POST /api/screenshot:提交截图任务(参数:url, width, height, full_page, wait_selector/wait_ms, device_pixel_ratio, cookies/headers 等)。GET /api/screenshot/{id}:获取任务状态与结果(或重定向到图片)。GET /api/containers:列出管理的容器。POST /api/containers/{id}/start/stop:控制容器。[用户浏览器] <--HTTPS--> [前端 (React/Vue)]
|
v
[后端 API (FastAPI/Flask)]
|
+------------+-------------+
| |
[任务队列:Redis/RQ 或 Celery + Redis/RabbitMQ]
| |
[Worker] [Docker 管理器]
| (docker-py)
v |
启动/连接 selenium 容器 <-----> docker host (运行 selenium/standalone-chrome)
| |
通过 Selenium / CDP 控制 Chrome noVNC (可选) 提供实时 VNC 预览
selenium/standalone-chrome:latest(自带 VNC,可通过 noVNC 访问)。使用 docker-py(Python SDK)启动 selenium 镜像:示例参数包括端口映射、环境变量(如 VNC 密码)、资源限制(cgroups)。每个用户/任务可以绑定一个短寿命容器或复用池中的容器。
两条主路径:
fullPage:使用 Chrome DevTools 的 Page.captureScreenshot + 滚动或 CDP 的 Emulation.setDeviceMetricsOverride。wait_selector)、固定延时、或页面网络空闲(可检测网络请求数)。POST /api/screenshot
Content-Type: application/json
{
"url":"https://example.com",
"width":1280,
"height":800,
"full_page":true,
"wait_for_selector":"#ready",
"timeout_ms":20000
}
200 OK
{
"task_id":"uuid-1234",
"status":"queued"
}
GET /api/screenshot/{task_id}
200 OK
{
"task_id":"...",
"status":"done",
"image_url":"/files/..../uuid.png",
"meta":{...}
}
version: '3'
services:
chrome:
image: selenium/standalone-chrome:latest
shm_size: '2g'
ports:
- "4444:4444" # selenium
- "5900:5900" # vnc(如有)
- "7900:7900" # noVNC(镜像支持时)
environment:
- SE_VNC_PASSWORD=secret
volumes:
- ./screens:/screens
web-screenshot-app/
├─ backend/
│ ├─ Dockerfile
│ ├─ requirements.txt
│ ├─ app/
│ │ ├─ main.py
│ │ ├─ api.py
│ │ ├─ tasks.py
│ │ ├─ docker_manager.py
│ │ └─ utils.py
│ └─ start.sh
├─ frontend/
│ ├─ Dockerfile
│ ├─ package.json
│ ├─ vite.config.js
│ └─ src/
│ ├─ main.jsx
│ ├─ App.jsx
│ ├─ api.js
│ └─ index.css
└─ docker-compose.yml