Files
Netease_url/README.md
2025-11-05 14:22:18 +08:00

378 lines
8.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 📖 网易云音乐工具箱 (v9.x - Web 应用重构版)
本项目是基于原版 `Netease_url` 项目的深度重构,旨在将其从一个依赖本地 `cookie.txt` 的工具,升级为一个**支持多用户、无状态后端、客户端认证**的现代化 Web 应用。
## ✨ V9 核心功能升级
相较于原版V9 架构带来了质的飞跃:
- **用户认证系统**
- **扫码登录**:移除本地脚本,实现了完整的 API 驱动的扫码登录流程。
- **客户端凭证**:用户 Cookie **不再**存储于服务器。登录成功后Cookie 凭证安全地存储在**用户自己的浏览器 `localStorage`** 中。
- **无状态 (Stateless) 后端**
- 服务器**不保存任何用户状态**。所有 API 请求均通过 `localStorage` 自动携带 Cookie 凭证进行鉴权。
- **高并发支持**天然支持多用户同时登录和使用Cookie 互相隔离,绝不串号。
- **全局播放器**
- 实现了一个固定在底部的**全局 APlayer 播放器**。
- 音乐播放在页面内导航、搜索、解析时**不会中断**,提供了现代音乐站的体验。
- **高级 UI/UX**
- **智能错误提示**:当解析高音质失败时,系统会智能判断用户是否未登录,并提示“请登录黑胶会员”。
- **用户设置**:增加了“自动播放”开关,并将其偏好存储在 `localStorage`
- **安全加固**:在 F12 控制台增加了醒目的安全警告,防止用户被“社会工程学”攻击。
## 🚀 部署模式 (重要)
V9 架构支持两种部署模式,灵活性极高:
### 1. 🌍 服务器部署模式 (多用户)
这是标准的线上部署模式。
1. **清空 `cookie.txt`**:将 `cookie.txt` 文件内容设置为空。
2. **启动服务**`python main.py`
3. **用户流程**
- 访问者**必须**点击右上角的“登录”按钮。
- 通过 App 扫码登录。
- Cookie 自动保存在他们各自的浏览器中,全程不接触你的服务器。
### 2. 💻 本地开发模式 (单用户)
这是你自己本地调试时使用的便捷模式。
1. **填写 `cookie.txt`**:在 `cookie.txt` 中填入你自己的黑胶会员 Cookie。
2. **启动服务**`python main.py`
3. **开发者流程**
- 你**无需**点击“登录”按钮。
- 当你进行解析、下载等操作时,前端 `index.html` 会发送一个“空”的 Cookie。
- 后端 `main.py``_get_cookies_from_request` 函数会检测到 Cookie 为空,并**自动降级 (Fallback)** 去读取 `cookie.txt` 中的内容来完成请求。
## 🔌 API 接口文档 (V9)
原版的 API 文档 已失效。以下是当前 `main.py` 提供的有效接口。
**请求说明**
- 所有需要鉴权的接口(如下载、解析高音质),都**必须**在 JSON 请求体中包含 `cookie` 字段。
- 前端 `index.html``getApiPayload` 函数会自动完成这一操作。
------
### /login/qr/generate
- **功能**:生成一个用于扫码登录的二维码 Key 和 Base64 图像。
- **方法**`POST`
- **请求 (JSON)**`{}` (无参数)
- **响应 (JSON)**
JSON
```
{
"success": true,
"data": {
"qr_key": "xxx-xxx-xxx",
"qr_img_b64": "data:image/png;base64,..."
}
}
```
------
### /login/qr/check
- **功能**:轮询检查二维码的扫码状态。
- **方法**`POST`
- **请求 (JSON)**
JSON
```
{
"qr_key": "xxx-xxx-xxx"
}
```
- **响应 (JSON)** (code: `801`=等待, `802`=已扫码, `803`=成功, `800`=过期)
JSON
```
{
"success": true,
"data": {
"code": 803,
"cookie": "MUSIC_U=...; __csrf=...;",
"message": "登录成功"
}
}
```
------
### /search
- **功能**:搜索歌曲。
- **方法**`POST`
- **请求 (JSON)**
JSON
```
{
"keyword": "蓝莲花",
"cookie": "...(来自 localStorage)"
}
```
------
### /song
- **功能**:解析单曲详情和播放链接。
- **方法**`POST`
- **请求 (JSON)**
JSON
```
{
"url": "歌曲ID或链接",
"level": "lossless",
"cookie": "...(来自 localStorage)"
}
```
------
### /playlist
- **功能**:解析歌单详情。
- **方法**`POST`
- **请求 (JSON)**
JSON
```
{
"id": "歌单ID或链接",
"cookie": "...(来自 localStorage)"
}
```
------
### /album
- **功能**:解析专辑详情。
- **方法**`POST`
- **请求 (JSON)**
JSON
```
{
"id": "专辑ID或链接",
"cookie": "...(来自 localStorage)"
}
```
------
### /download_song_zip
- **功能**:打包下载单曲(含封面、歌词)。
- **方法**`POST`
- **请求 (JSON)**
JSON
```
{
"id": "歌曲ID",
"quality": "lossless",
"cookie": "...(来自 localStorage)"
}
```
- **响应**`application/zip` 文件流。
------
### /download_playlist_zip
- **功能**:打包下载整个歌单。
- **方法**`POST`
- **请求 (JSON)**
JSON
```
{
"id": "歌单ID",
"quality": "lossless",
"cookie": "...(来自 localStorage)"
}
```
- **响应**`application/zip` 文件流。
------
### /download_album_zip
- **功能**:打包下载整个专辑。
- **方法**`POST`
- **请求 (JSON)**
JSON
```
{
"id": "专辑ID",
"quality": "lossless",
"cookie": "...(来自 localStorage)"
}
```
- **响应**`application/zip` 文件流。
## 📝 架构与开发说明
### V9 核心架构
本项目成功的关键在于**“责任分离”**
1. **`main.py` (服务层)**:作为“总指挥”。它**只负责**编排请求 (接收 HTTP、解析参数) 和响应 (返回 JSON 或 Zip)。它**不**包含任何Cookie管理或API请求的硬编码逻辑。
2. **`qr_login.py` (认证模块)****只负责**生成和检查二维码。
3. **`music_api.py` (API 模块)****只负责**调用网易云的 *JSON* API (如搜索、歌单详情)。它必须是“无状态的”,并接收 `cookies` 作为参数。
4. **`music_downloader.py` (下载模块)****只负责**获取 *文件* API (如歌曲 URL、歌词),并处理打包逻辑。它也必须接收 `cookies` 参数。
5. **`cookie_manager.py` (工具模块)****只负责**解析 Cookie 字符串 (`parse_cookie_string`) 和读取 `cookie.txt` (作为备用)。
6. **`index.html` (客户端)**:作为“用户界面”和“**凭证保险箱**”。它**全权负责**存储 `userCookie`,并在**每一次** API 调用时主动提供它。
### 项目结构 (V9)
```
Netease_url/
├── main.py # [!! 重构 !!] Flask 主程序, 路由层
├── music_api.py # API 核心模块 (基本不变, 仅被调用)
├── music_downloader.py # [!! 重构 !!] 下载模块 (已解耦, 需传入 cookie)
├── cookie_manager.py # Cookie 管理工具 (现主要用于解析)
├── qr_login.py # [!! 重构 !!] 从脚本变为 QR 登录 API 模块
├── templates/
│ └── index.html # [!! 重构 !!] V9 前端应用
├── static/ # [!! 新增 !!] 静态文件目录
│ └── favicon.ico # [!! 新增 !!] 网站图标
├── requirements.txt
├── cookie.txt # (可选) 仅用于本地开发模式
└── README_v9.md # (本文档)
```
### 未来升级的基石 (v10 展望)
基于 V9 的“无状态后端 + 客户端凭证”架构,我们为下一阶段的升级打下了完美的基础:
- **实现“我的音乐”**
- 后端:在 `music_api.py` 中新增 `get_user_playlists(uid, cookies)` 函数。
- 后端:在 `main.py` 中新增 `/my/playlists` 路由,它调用上述函数。
- 前端:在登录成功后,`fetch('/my/playlists')` 并在 `index.html` 中渲染一个新区域。
- **实现“真实进度条”**
- 后端:`main.py` 引入 `Flask-SocketIO`。
- 后端:`_package_tracks_as_zip` 在 `for` 循环中 `socketio.emit` 真实进度。
- 前端:`handleDownloadClick` 不再使用假进度 `setInterval`,而是 `socket.on('progress', ...)` 来更新进度条。
- **实现“歌单即时播放”**
- 前端:在 `renderCollection` 中增加“播放全部”按钮。
- 前端:点击后,循环 `tracks` 列表,为每首歌调用 `/song` 接口。
- 前端:将所有返回的 `data.url` 组装成一个列表,一次性 `globalAPlayer.list.add([...])`。