20260901 104042 抖音作品采集工具提示词

20260901_104042_抖音作品采集工具提示词.md
请开发一个基于 Flask 的抖音作品采集工具,满足以下全部需求:

## 1. 核心功能
- 用户输入抖音**作者主页链接**或**单个作品链接**,系统自动采集该链接下的所有作品(视频/图集)并下载保存到本地文件夹。
- 对每个作品调用 **DeepSeek API** 进行内容分析,生成 120 字以内的内容总结,并将总结结果展示在网页上。
- 提供简单的 Web 操作界面,支持任务提交、状态实时查看、结果展示。

## 2. 技术栈
- Python 3.8+
- Flask(Web 框架)
- requests(HTTP 请求)
- python-dotenv(环境变量管理)
- 不使用数据库,任务状态存储于内存(简单字典即可)
- 抖音解析:使用**第三方解析 API**(需要在代码中预留接口,用户可自行替换为实际可用的服务,例如聚合数据、快解析等,本提示词中默认使用一个虚构的 API `https://api.example.com/douyin/parse`,开发者需自行替换)
- AI 总结:调用 **DeepSeek Chat API**(`https://api.deepseek.com/v1/chat/completions`),模型使用 `deepseek-chat`,API Key 从环境变量 `DEEPSEEK_API_KEY` 读取。

## 3. 项目结构

douyin_collector/
├── app.py # Flask 主程序(路由、任务管理)
├── config.py # 配置文件(下载目录、API Key 默认设置等)
├── requirements.txt # 依赖列表
├── utils/
│ ├── init.py
│ ├── douyin_parser.py # 抖音解析模块
│ ├── downloader.py # 下载器模块
│ └── ai_summarizer.py # DeepSeek 总结模块
├── templates/
│ ├── index.html # 首页:输入链接的表单
│ └── result.html # 结果页:展示任务状态和结果(含 AJAX 轮询)
├── static/
│ └── style.css # 可选,简单样式(可省略)
└── downloads/ # 下载文件保存目录(运行时自动创建)

## 4. 模块详细要求

### 4.1 抖音解析模块 (`utils/douyin_parser.py`)
- 函数 `parse_douyin_url(url: str) -> List[Dict]`,接收用户输入的链接,返回**作品信息列表**(即使只有一个作品也返回列表)。
- 该函数内部调用第三方解析 API(POST 或 GET 均可,示例使用 GET 请求,参数 `url`)。
- 解析 API 返回 JSON 格式,假设包含字段:
  - `is_author`: 布尔值,表示是否为作者主页(若为作者主页,则 `works` 字段是一个包含多个作品信息的列表)
  - 若 `is_author` 为 `True`,则从 `data["works"]` 中提取作品列表;
  - 若为 `False`,则直接返回一个作品对象(包装成列表)。
- 每个作品对象包含以下字段(根据实际 API 可能有所不同,但需在代码中做兼容处理):
  ```python
  {
      "type": "video" 或 "image",
      "author": "作者昵称",
      "title": "作品标题或描述",
      "video_url": "无水印视频直链(type=video时必填)",
      "image_urls": ["图片链接1", "图片链接2", ...] (type=image时必填),
      "cover": "封面图链接(可选)",
      "duration": 15,  # 视频时长(秒,可选)
      "music": "背景音乐名称(可选)",
      "likes": 100,    # 点赞数(可选)
      "comments": 20,  # 评论数(可选)
      "shares": 5,     # 分享数(可选)
      "create_time": "2023-01-01 12:00:00"  # 发布时间(可选)
  }
  ```
- 注意:第三方 API 可能没有所有这些字段,需要给出默认值(例如 `duration` 默认 0,`music` 默认 "无",等等)。
- 如果解析失败(网络错误、API 返回错误等),抛出异常,由上层捕获。

### 4.2 下载器模块 (`utils/downloader.py`)
- 函数 `download_work(work: Dict, save_dir: str) -> str`,接收单个作品信息和保存目录,返回下载后的本地文件路径(视频文件路径或图集文件夹路径)。
- 根据 `work["type"]` 分两种情况:
  - **视频**:从 `work["video_url"]` 下载视频文件,文件名格式建议为 `{作者}_{标题前20字符}.mp4`(需处理非法字符),使用流式下载(requests.get(stream=True))。
  - **图集**:创建子文件夹,文件夹名同样为 `{作者}_{标题前20字符}`,依次下载所有图片,保存为 `image_1.jpg`, `image_2.jpg`, ...。
- 确保 `save_dir` 存在,若不存在则创建。
- 如果下载失败,抛出异常。

### 4.3 AI 总结模块 (`utils/ai_summarizer.py`)
- 函数 `summarize_work(work: Dict) -> str`,接收作品信息,返回内容总结字符串(不超过 120 字)。
- 使用 `requests.post` 调用 DeepSeek API:
  - URL: `https://api.deepseek.com/v1/chat/completions`
  - 请求头:`Content-Type: application/json`,`Authorization: Bearer {DEEPSEEK_API_KEY}`
  - 请求体 JSON:
    ```json
    {
      "model": "deepseek-chat",
      "messages": [
        {"role": "system", "content": "你是一个严谨的内容总结助手。"},
        {"role": "user", "content": "这里是完整的提示词模板(见下)"}
      ],
      "temperature": 0.7,
      "max_tokens": 300,
      "stream": false
    }
    ```
  - API Key 从环境变量 `DEEPSEEK_API_KEY` 读取,若未设置则返回错误信息。
- **完整提示词模板**(用户消息内容,使用 f-string 填充作品信息):
  ```
  你是一个专业的内容分析师,擅长从抖音作品的元数据中提炼核心信息。请根据以下作品信息,生成一段简洁、准确、有吸引力的内容总结(不超过120字),帮助用户快速了解作品主题和亮点。

  【作品信息】
  作者:{author}
  标题/描述:{title}
  类型:{'视频' if type == 'video' else '图集'}
  时长:{duration}秒
  背景音乐:{music}
  点赞数:{likes}
  评论数:{comments}
  分享数:{shares}
  发布时间:{create_time}

  【总结要求】
  1. 概括作品的主要内容或主题;
  2. 突出作品的特色或可能的爆点(如情感、搞笑、知识、颜值等);
  3. 语言流畅,避免冗余,直接输出总结文本,不要任何前缀或解释。
  ```
- 如果 API 调用失败(如网络问题、密钥错误等),捕获异常并返回错误信息字符串,格式如 `"DeepSeek API 调用失败:{错误详情}"`。

### 4.4 Flask 主程序 (`app.py`)
- 定义以下路由:
  - `GET /`:渲染 `index.html`,显示一个表单,包含一个输入框(name="url")和提交按钮。
  - `POST /submit`:接收表单中的 `url`,创建任务 ID(使用 `os.urandom(8).hex()`),将任务信息存入全局字典 `tasks`(结构见下),启动后台线程执行 `process_task(task_id, url)`,然后重定向到 `/task/<task_id>`。
  - `GET /task/<task_id>`:根据任务 ID 从 `tasks` 字典获取任务,渲染 `result.html`,传入任务对象和任务 ID。
  - `GET /api/task/<task_id>`:返回该任务的 JSON 数据(用于前端 AJAX 轮询),若任务不存在返回 404。
- **任务字典结构**:
  ```python
  tasks[task_id] = {
      'status': 'pending',   # pending / parsing / downloading / completed / error
      'message': '任务已提交',
      'results': []           # 最终结果为列表,每个元素为字典,包含 work, local_path, summary
  }
  ```
- `process_task(task_id, url)` 函数逻辑:
  1. 更新状态为 `parsing`,调用 `parse_douyin_url(url)` 获取作品列表。
  2. 如果列表为空或解析失败,设置状态为 `error`,消息为对应错误,返回。
  3. 更新状态为 `downloading`,遍历作品列表,对每个作品:
     - 调用 `download_work(work, config.DOWNLOAD_DIR)` 下载,得到本地路径。
     - 调用 `summarize_work(work)` 生成 AI 总结。
     - 将 `{'work': work, 'local_path': local_path, 'summary': summary}` 追加到 `tasks[task_id]['results']`。
     - 更新消息为 `下载中 {idx+1}/{total}`。
  4. 全部完成后,设置状态为 `completed`,消息为 `处理完成,共 {total} 个作品`。
  5. 若过程中出现异常,设置状态为 `error`,消息包含错误详情。

### 4.5 配置文件 (`config.py`)
- 定义下载目录 `DOWNLOAD_DIR = os.path.join(os.path.dirname(__file__), 'downloads')`
- 尝试从 `.env` 文件加载环境变量(使用 `python-dotenv` 的 `load_dotenv()`)
- 不直接写死 API Key,全部从环境变量读取。

### 4.6 前端模板
- `index.html`:简单的 HTML 表单,包含一个输入框和提交按钮,表单 action 指向 `/submit`,method 为 POST。
- `result.html`:显示任务状态(status 和 message),并使用 JavaScript 每 2 秒通过 `fetch('/api/task/{{ task_id }}')` 轮询任务状态,当状态变为 `completed` 或 `error` 时停止轮询,并渲染结果列表(如果有 results)。结果列表中每一项显示:作品标题、作者、本地路径、AI 总结。页面底部提供返回首页的链接。

## 5. 依赖文件 `requirements.txt`

flask==2.3.2
requests==2.31.0
python-dotenv==1.0.0

## 6. 运行说明
- 用户需要在项目根目录创建 `.env` 文件,内容为 `DEEPSEEK_API_KEY=sk-xxxx`(实际密钥)。
- 用户需要将 `utils/douyin_parser.py` 中的第三方解析 API URL 替换为实际可用的服务,并确保返回格式符合上述约定(或自行调整解析逻辑)。
- 运行 `python app.py` 启动服务,默认端口 5000。

## 7. 注意事项
- 代码中要包含适当的注释,特别是关键步骤(如解析、下载、API 调用)。
- 请确保所有模块都能正确导入,路径处理正确(使用 `os.path`)。
- 需要处理文件名中的非法字符(如 `/ \ : * ? " < > |`),替换为下划线。
- 异常处理要完善,避免进程崩溃,所有错误都应反馈到任务状态中。
- 生成的代码应该是完整可运行的,不需要用户再手动补充核心逻辑。

请严格按照以上要求生成完整的项目代码,包括所有目录下的文件内容。