1030 lines
24 KiB
Markdown
1030 lines
24 KiB
Markdown
|
|
# Social Auto Upload - 社交媒体自动化上传工具
|
|||
|
|
|
|||
|
|
## 📌 项目简介
|
|||
|
|
|
|||
|
|
`social-auto-upload` 是一个功能强大的社交媒体自动化上传工具,帮助内容创作者和运营者高效地将视频内容一键分发到多个主流社交媒体平台。项目采用 Playwright 自动化框架,支持定时发布、批量上传、多账号管理等功能。
|
|||
|
|
|
|||
|
|
### 核心特性
|
|||
|
|
|
|||
|
|
- ✅ **多平台支持**:支持抖音、快手、B站、小红书、视频号、百家号、TikTok等主流平台
|
|||
|
|
- ✅ **智能反检测**:集成 stealth.js 和人类化输入模拟,有效规避平台反爬虫机制
|
|||
|
|
- ✅ **Web管理界面**:提供 Vue3 + Element Plus 的现代化前端管理界面
|
|||
|
|
- ✅ **定时发布**:支持灵活的定时发布策略,可设置每天发布数量和时间点
|
|||
|
|
- ✅ **多账号管理**:支持多账号切换和批量发布
|
|||
|
|
- ✅ **Cookie管理**:自动化Cookie获取和状态检测
|
|||
|
|
- ✅ **CLI/API双模式**:既可命令行操作,也可通过API接口调用
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🏗️ 项目架构
|
|||
|
|
|
|||
|
|
### 技术栈
|
|||
|
|
|
|||
|
|
**后端 (Python)**
|
|||
|
|
- **框架**: Flask 3.1+
|
|||
|
|
- **自动化**: Playwright 1.52+
|
|||
|
|
- **数据库**: SQLite3
|
|||
|
|
- **异步**: asyncio + eventlet
|
|||
|
|
- **依赖**: xhs 0.2.13 (小红书SDK), biliup 0.4.98 (B站上传)
|
|||
|
|
|
|||
|
|
**前端 (Vue.js)**
|
|||
|
|
- **框架**: Vue 3 + Vite
|
|||
|
|
- **UI组件**: Element Plus
|
|||
|
|
- **状态管理**: Pinia
|
|||
|
|
- **HTTP客户端**: Axios
|
|||
|
|
|
|||
|
|
### 目录结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
social-auto-upload/
|
|||
|
|
├── uploader/ # 各平台上传器实现
|
|||
|
|
│ ├── douyin_uploader/ # 抖音上传器
|
|||
|
|
│ ├── ks_uploader/ # 快手上传器
|
|||
|
|
│ ├── bilibili_uploader/ # B站上传器
|
|||
|
|
│ ├── tencent_uploader/ # 视频号上传器
|
|||
|
|
│ ├── tk_uploader/ # TikTok上传器
|
|||
|
|
│ ├── baijiahao_uploader/ # 百家号上传器
|
|||
|
|
│ ├── xiaohongshu_uploader/ # 小红书视频上传器 (Playwright)
|
|||
|
|
│ └── xhs_uploader/ # 小红书笔记上传器 (API)
|
|||
|
|
├── utils/ # 工具模块
|
|||
|
|
│ ├── anti_detection.py # 反检测工具
|
|||
|
|
│ ├── human_typing_wrapper.py # 人类化输入模拟
|
|||
|
|
│ ├── human_like.py # 人类行为模拟
|
|||
|
|
│ ├── base_social_media.py # 基础社交媒体工具
|
|||
|
|
│ ├── stealth.min.js # Stealth脚本
|
|||
|
|
│ └── files_times.py # 文件和时间处理
|
|||
|
|
├── myUtils/ # 业务工具
|
|||
|
|
│ ├── auth.py # Cookie认证
|
|||
|
|
│ ├── login.py # 登录处理
|
|||
|
|
│ └── postVideo.py # 视频发布
|
|||
|
|
├── sau_frontend/ # Vue前端项目
|
|||
|
|
│ ├── src/
|
|||
|
|
│ │ ├── views/ # 页面组件
|
|||
|
|
│ │ ├── api/ # API接口
|
|||
|
|
│ │ ├── stores/ # Pinia状态管理
|
|||
|
|
│ │ └── router/ # 路由配置
|
|||
|
|
│ └── vite.config.js
|
|||
|
|
├── sau_backend.py # Flask后端服务
|
|||
|
|
├── cli_main.py # 命令行入口
|
|||
|
|
├── db/ # 数据库
|
|||
|
|
│ ├── createTable.py # 数据库初始化
|
|||
|
|
│ └── database.db # SQLite数据库文件
|
|||
|
|
├── examples/ # 使用示例
|
|||
|
|
├── docs/ # 文档
|
|||
|
|
└── requirements.txt # Python依赖
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚀 快速开始
|
|||
|
|
|
|||
|
|
### 1. 环境准备
|
|||
|
|
|
|||
|
|
#### 系统要求
|
|||
|
|
- Python 3.10+
|
|||
|
|
- Node.js 16+
|
|||
|
|
- Chrome/Chromium浏览器
|
|||
|
|
|
|||
|
|
#### 安装步骤
|
|||
|
|
|
|||
|
|
**1) 克隆项目**
|
|||
|
|
```bash
|
|||
|
|
git clone https://github.com/dreammis/social-auto-upload.git
|
|||
|
|
cd social-auto-upload
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**2) 创建虚拟环境并安装Python依赖**
|
|||
|
|
```bash
|
|||
|
|
# 推荐使用conda
|
|||
|
|
conda create -n social-auto-upload python=3.10
|
|||
|
|
conda activate social-auto-upload
|
|||
|
|
|
|||
|
|
# 安装依赖
|
|||
|
|
pip install -r requirements.txt
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**3) 安装Playwright浏览器驱动**
|
|||
|
|
```bash
|
|||
|
|
playwright install chromium
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**4) 配置项目**
|
|||
|
|
```bash
|
|||
|
|
# 复制配置文件模板
|
|||
|
|
cp conf.example.py conf.py
|
|||
|
|
|
|||
|
|
# 编辑conf.py,配置以下内容:
|
|||
|
|
# - LOCAL_CHROME_PATH: 本地Chrome浏览器路径
|
|||
|
|
# - BASE_DIR: 项目根目录
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**5) 创建必要的目录**
|
|||
|
|
```bash
|
|||
|
|
mkdir -p cookiesFile videoFile
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**6) 初始化数据库**
|
|||
|
|
```bash
|
|||
|
|
cd db
|
|||
|
|
python createTable.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 启动服务
|
|||
|
|
|
|||
|
|
#### 启动后端服务
|
|||
|
|
```bash
|
|||
|
|
python sau_backend.py
|
|||
|
|
# 后端服务运行在 http://localhost:5409
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 启动前端服务
|
|||
|
|
```bash
|
|||
|
|
cd sau_frontend
|
|||
|
|
npm install
|
|||
|
|
npm run dev
|
|||
|
|
# 前端服务运行在 http://localhost:5173
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
浏览器访问 `http://localhost:5173` 即可使用Web界面。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 💡 使用指南
|
|||
|
|
|
|||
|
|
### 方式一:Web界面操作
|
|||
|
|
|
|||
|
|
1. **账号管理**
|
|||
|
|
- 进入"账号管理"页面
|
|||
|
|
- 点击"添加账号",选择平台类型
|
|||
|
|
- 使用二维码扫码登录
|
|||
|
|
- 系统自动保存Cookie
|
|||
|
|
|
|||
|
|
2. **素材管理**
|
|||
|
|
- 进入"素材管理"页面
|
|||
|
|
- 上传视频文件
|
|||
|
|
- 支持批量上传和预览
|
|||
|
|
|
|||
|
|
3. **发布视频**
|
|||
|
|
- 进入"发布中心"页面
|
|||
|
|
- 选择视频文件(本地上传或素材库选择)
|
|||
|
|
- 选择目标账号和平台
|
|||
|
|
- 填写标题、话题
|
|||
|
|
- 配置定时发布(可选)
|
|||
|
|
- 点击发布
|
|||
|
|
|
|||
|
|
4. **批量发布**
|
|||
|
|
- 在发布中心可添加多个Tab
|
|||
|
|
- 每个Tab配置不同的发布任务
|
|||
|
|
- 点击"批量发布"一键发布所有任务
|
|||
|
|
|
|||
|
|
### 方式二:命令行操作
|
|||
|
|
|
|||
|
|
#### 获取Cookie
|
|||
|
|
```bash
|
|||
|
|
# 抖音
|
|||
|
|
python examples/get_douyin_cookie.py
|
|||
|
|
|
|||
|
|
# 小红书
|
|||
|
|
python examples/get_xiaohongshu_cookie.py
|
|||
|
|
|
|||
|
|
# 视频号
|
|||
|
|
python examples/get_tencent_cookie.py
|
|||
|
|
|
|||
|
|
# 快手
|
|||
|
|
python examples/get_kuaishou_cookie.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 上传视频
|
|||
|
|
```bash
|
|||
|
|
# 使用CLI工具
|
|||
|
|
python cli_main.py douyin xiaoA upload /path/to/video.mp4 -pt 0
|
|||
|
|
|
|||
|
|
# 使用示例脚本
|
|||
|
|
python examples/upload_video_to_douyin.py
|
|||
|
|
python examples/upload_video_to_xiaohongshu.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 方式三:API接口调用
|
|||
|
|
|
|||
|
|
#### 主要API端点
|
|||
|
|
|
|||
|
|
**上传文件**
|
|||
|
|
```http
|
|||
|
|
POST /upload
|
|||
|
|
Content-Type: multipart/form-data
|
|||
|
|
|
|||
|
|
# 返回文件路径
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**发布视频**
|
|||
|
|
```http
|
|||
|
|
POST /postVideo
|
|||
|
|
Content-Type: application/json
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"type": 1, # 平台类型: 1-小红书, 2-视频号, 3-抖音, 4-快手
|
|||
|
|
"title": "视频标题",
|
|||
|
|
"tags": ["话题1", "话题2"], # 不带#号
|
|||
|
|
"fileList": ["文件路径1"],
|
|||
|
|
"accountList": ["账号cookie文件"],
|
|||
|
|
"category": 0, # 0-非原创
|
|||
|
|
"enableTimer": 1, # 0-立即发布, 1-定时发布
|
|||
|
|
"videosPerDay": 1, # 每天发布数量
|
|||
|
|
"dailyTimes": ["10:00"], # 发布时间点
|
|||
|
|
"startDays": 0 # 0-明天, 1-后天
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**获取素材列表**
|
|||
|
|
```http
|
|||
|
|
GET /getFiles
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**获取有效账号**
|
|||
|
|
```http
|
|||
|
|
GET /getValidAccounts
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔧 核心功能详解
|
|||
|
|
|
|||
|
|
### 1. 智能反检测系统
|
|||
|
|
|
|||
|
|
项目集成了多层反检测机制:
|
|||
|
|
|
|||
|
|
#### 浏览器指纹隐藏
|
|||
|
|
```python
|
|||
|
|
# utils/anti_detection.py
|
|||
|
|
- 禁用自动化控制标识 (--disable-blink-features=AutomationControlled)
|
|||
|
|
- 随机User-Agent
|
|||
|
|
- 模拟真实视口尺寸
|
|||
|
|
- 设置语言和时区
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 人类化行为模拟
|
|||
|
|
```python
|
|||
|
|
# utils/human_typing_wrapper.py
|
|||
|
|
- 可变输入速度 (2-10字符/秒)
|
|||
|
|
- 随机停顿思考
|
|||
|
|
- 模拟打字疲劳效果
|
|||
|
|
- 分段输入长文本
|
|||
|
|
- 错误修正行为(可选)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Stealth脚本注入
|
|||
|
|
```python
|
|||
|
|
# utils/stealth.min.js
|
|||
|
|
- 隐藏webdriver属性
|
|||
|
|
- 伪造Chrome运行时
|
|||
|
|
- 修改navigator对象
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 小红书双模式上传
|
|||
|
|
|
|||
|
|
项目提供两种小红书上传方式:
|
|||
|
|
|
|||
|
|
#### 视频上传模式 (xiaohongshu_uploader)
|
|||
|
|
- **技术**: Playwright自动化
|
|||
|
|
- **特点**: 支持视频发布、话题添加、地点设置
|
|||
|
|
- **文件**: `uploader/xiaohongshu_uploader/main.py`
|
|||
|
|
- **优势**: 功能完整,支持视频封面、定时发布
|
|||
|
|
- **劣势**: 易被反爬虫检测
|
|||
|
|
|
|||
|
|
#### 笔记上传模式 (xhs_uploader)
|
|||
|
|
- **技术**: 小红书官方API封装 (xhs SDK)
|
|||
|
|
- **特点**: 支持图文笔记、视频笔记
|
|||
|
|
- **文件**: `uploader/xhs_uploader/main.py`
|
|||
|
|
- **优势**: 稳定性高,速度快
|
|||
|
|
- **劣势**: 需要签名服务器
|
|||
|
|
|
|||
|
|
### 3. 定时发布策略
|
|||
|
|
|
|||
|
|
支持灵活的发布时间配置:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 示例:3天内每天发布2个视频,时间点为10:00和16:00
|
|||
|
|
publish_datetimes = generate_schedule_time_next_day(
|
|||
|
|
file_num=6, # 文件总数
|
|||
|
|
videos_per_day=2, # 每天发布数
|
|||
|
|
daily_times=[10, 16], # 发布时间点
|
|||
|
|
start_days=0 # 从明天开始
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 多账号管理
|
|||
|
|
|
|||
|
|
数据库结构:
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 用户账号表
|
|||
|
|
CREATE TABLE user_info (
|
|||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|||
|
|
type INTEGER NOT NULL, -- 平台类型: 1-小红书, 2-视频号, 3-抖音, 4-快手
|
|||
|
|
filePath TEXT NOT NULL, -- Cookie文件路径
|
|||
|
|
userName TEXT NOT NULL, -- 账号名称
|
|||
|
|
status INTEGER DEFAULT 0 -- 状态: 0-失效, 1-有效
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
-- 文件记录表
|
|||
|
|
CREATE TABLE file_records (
|
|||
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|||
|
|
filename TEXT NOT NULL,
|
|||
|
|
filesize REAL, -- 文件大小(MB)
|
|||
|
|
upload_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|||
|
|
file_path TEXT
|
|||
|
|
);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 平台支持详情
|
|||
|
|
|
|||
|
|
### 已支持平台
|
|||
|
|
|
|||
|
|
| 平台 | 视频上传 | 图文上传 | 定时发布 | 多账号 | 反检测 |
|
|||
|
|
|-----|---------|---------|---------|--------|--------|
|
|||
|
|
| 抖音 | ✅ | ❌ | ✅ | ✅ | ✅ |
|
|||
|
|
| 快手 | ✅ | ❌ | ✅ | ✅ | ✅ |
|
|||
|
|
| 小红书 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|||
|
|
| 视频号 | ✅ | ❌ | ✅ | ✅ | ✅ |
|
|||
|
|
| B站 | ✅ | ❌ | ✅ | ✅ | ✅ |
|
|||
|
|
| 百家号 | ✅ | ❌ | ✅ | ✅ | ✅ |
|
|||
|
|
| TikTok | ✅ | ❌ | ✅ | ✅ | ✅ |
|
|||
|
|
|
|||
|
|
### 计划支持
|
|||
|
|
|
|||
|
|
- [ ] YouTube
|
|||
|
|
- [ ] Instagram Reels
|
|||
|
|
- [ ] Twitter/X视频
|
|||
|
|
- [ ] Facebook
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔍 小红书两种上传方式对比分析
|
|||
|
|
|
|||
|
|
### 技术实现差异
|
|||
|
|
|
|||
|
|
#### xiaohongshu_uploader (视频模式 - Playwright)
|
|||
|
|
|
|||
|
|
**实现方式**:
|
|||
|
|
```python
|
|||
|
|
# 使用Playwright模拟浏览器操作
|
|||
|
|
1. 访问创作者中心: https://creator.xiaohongshu.com/publish/publish?from=homepage&target=video
|
|||
|
|
2. 使用input[type=file]上传视频文件
|
|||
|
|
3. 填写标题、话题、地点等信息
|
|||
|
|
4. 点击发布按钮
|
|||
|
|
5. 等待发布成功
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**核心代码流程**:
|
|||
|
|
```python
|
|||
|
|
# uploader/xiaohongshu_uploader/main.py
|
|||
|
|
async def upload(self, playwright: Playwright):
|
|||
|
|
# 1. 创建反检测浏览器
|
|||
|
|
browser = await playwright.chromium.launch(headless=self.headless)
|
|||
|
|
context = await browser.new_context(storage_state=account_file)
|
|||
|
|
context = await set_init_script(context) # 注入stealth脚本
|
|||
|
|
|
|||
|
|
# 2. 上传视频
|
|||
|
|
await page.locator("input.upload-input").set_input_files(self.file_path)
|
|||
|
|
|
|||
|
|
# 3. 人类化输入标题和话题
|
|||
|
|
human_typer = create_human_typer(page)
|
|||
|
|
await human_typer.type_text_human('input.d-text', self.title)
|
|||
|
|
|
|||
|
|
# 4. 逐个输入话题(慢速)
|
|||
|
|
for tag in self.tags:
|
|||
|
|
await slow_typer.type_text_human(css_selector, f"#{tag}")
|
|||
|
|
await page.keyboard.press("Enter")
|
|||
|
|
await page.wait_for_timeout(800) # 停顿800ms
|
|||
|
|
|
|||
|
|
# 5. 设置地点
|
|||
|
|
await self.set_location(page, "青岛市")
|
|||
|
|
|
|||
|
|
# 6. 发布
|
|||
|
|
await page.locator('button:has-text("发布")').click()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**关键特性**:
|
|||
|
|
- ✅ 支持视频上传
|
|||
|
|
- ✅ 支持封面设置
|
|||
|
|
- ✅ 支持地点选择
|
|||
|
|
- ✅ 支持定时发布
|
|||
|
|
- ✅ 人类化输入(防检测)
|
|||
|
|
- ⚠️ 标签输入速度:500-800ms/字符(极慢)
|
|||
|
|
- ⚠️ 每个标签后停顿800ms
|
|||
|
|
|
|||
|
|
#### xhs_uploader (笔记模式 - API)
|
|||
|
|
|
|||
|
|
**实现方式**:
|
|||
|
|
```python
|
|||
|
|
# 使用xhs SDK调用API
|
|||
|
|
1. 创建XhsClient客户端
|
|||
|
|
2. 调用create_video_note方法
|
|||
|
|
3. 直接通过API上传视频和元数据
|
|||
|
|
4. 返回发布结果
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**核心代码流程**:
|
|||
|
|
```python
|
|||
|
|
# uploader/xhs_uploader/main.py
|
|||
|
|
# 1. 初始化客户端
|
|||
|
|
xhs_client = XhsClient(cookies, sign=sign_local, timeout=60)
|
|||
|
|
|
|||
|
|
# 2. 获取话题建议
|
|||
|
|
topics = []
|
|||
|
|
for tag in tags[:3]:
|
|||
|
|
topic_official = xhs_client.get_suggest_topic(tag)
|
|||
|
|
topics.append(topic_official[0])
|
|||
|
|
|
|||
|
|
# 3. 创建视频笔记
|
|||
|
|
note = xhs_client.create_video_note(
|
|||
|
|
title=title[:20],
|
|||
|
|
video_path=str(file),
|
|||
|
|
desc=title + tags_str + hash_tags_str,
|
|||
|
|
topics=topics,
|
|||
|
|
is_private=False,
|
|||
|
|
post_time=publish_datetime
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 4. 强制休眠30s避免风控
|
|||
|
|
sleep(30)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**关键特性**:
|
|||
|
|
- ✅ 支持视频/图文笔记
|
|||
|
|
- ✅ 通过API直接上传
|
|||
|
|
- ✅ 支持话题推荐
|
|||
|
|
- ✅ 速度快(API直传)
|
|||
|
|
- ⚠️ 需要签名服务器
|
|||
|
|
- ⚠️ 必须间隔30秒(风控)
|
|||
|
|
|
|||
|
|
### 反爬虫对比分析
|
|||
|
|
|
|||
|
|
#### xiaohongshu_uploader 反爬虫问题
|
|||
|
|
|
|||
|
|
**问题表现**:
|
|||
|
|
1. **无头模式失败**:headless=True时无法找到上传元素
|
|||
|
|
2. **有头模式跳转登录**:触发反自动化检测,跳转到登录页
|
|||
|
|
3. **标签输入被拦截**:快速输入话题会被识别为机器人
|
|||
|
|
|
|||
|
|
**已实现的对策**:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 1. 多层反检测
|
|||
|
|
- 浏览器参数隐藏自动化标识
|
|||
|
|
- 注入stealth.min.js脚本
|
|||
|
|
- 随机User-Agent
|
|||
|
|
- 真实视口尺寸 (1600x900)
|
|||
|
|
|
|||
|
|
# 2. 人类化输入
|
|||
|
|
- 可变输入速度 (500-800ms/字符)
|
|||
|
|
- 随机停顿 (30%概率,500-1200ms)
|
|||
|
|
- 禁用错误修正(确保文字准确)
|
|||
|
|
- 分段输入长文本
|
|||
|
|
|
|||
|
|
# 3. 慢速标签输入
|
|||
|
|
slow_config = {
|
|||
|
|
'min_delay': 500, # 最小延迟500ms
|
|||
|
|
'max_delay': 800, # 最大延迟800ms
|
|||
|
|
'pause_probability': 0.3, # 30%概率暂停
|
|||
|
|
'pause_min': 500,
|
|||
|
|
'pause_max': 1200,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 4. 标签间停顿
|
|||
|
|
for tag in tags:
|
|||
|
|
await slow_typer.type_text_human(selector, f"#{tag}")
|
|||
|
|
await page.keyboard.press("Enter")
|
|||
|
|
await page.wait_for_timeout(800) # 每个标签后停顿800ms
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**仍存在的风险**:
|
|||
|
|
- ⚠️ 长时间使用同一Cookie可能被封
|
|||
|
|
- ⚠️ 批量操作容易触发风控
|
|||
|
|
- ⚠️ IP频繁请求可能被限制
|
|||
|
|
- ⚠️ 无头模式仍然不稳定
|
|||
|
|
|
|||
|
|
#### xhs_uploader 反爬虫问题
|
|||
|
|
|
|||
|
|
**问题表现**:
|
|||
|
|
1. **签名验证**:API请求需要X-s和X-t签名参数
|
|||
|
|
2. **频率限制**:短时间内多次请求会被拦截
|
|||
|
|
3. **Cookie失效**:长时间不用会失效
|
|||
|
|
|
|||
|
|
**已实现的对策**:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 1. 本地签名服务
|
|||
|
|
def sign_local(uri, data=None, a1="", web_session=""):
|
|||
|
|
with sync_playwright() as playwright:
|
|||
|
|
# 使用真实浏览器环境生成签名
|
|||
|
|
browser = playwright.chromium.launch(headless=True)
|
|||
|
|
context.add_cookies([{'name': 'a1', 'value': a1, ...}])
|
|||
|
|
encrypt_params = page.evaluate(
|
|||
|
|
"([url, data]) => window._webmsxyw(url, data)",
|
|||
|
|
[uri, data]
|
|||
|
|
)
|
|||
|
|
return {
|
|||
|
|
"x-s": encrypt_params["X-s"],
|
|||
|
|
"x-t": str(encrypt_params["X-t"])
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 2. 强制间隔
|
|||
|
|
sleep(30) # 每次上传后休眠30秒
|
|||
|
|
|
|||
|
|
# 3. Cookie验证
|
|||
|
|
try:
|
|||
|
|
xhs_client.get_video_first_frame_image_id("3214")
|
|||
|
|
except:
|
|||
|
|
print("cookie 失效")
|
|||
|
|
exit()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**优势**:
|
|||
|
|
- ✅ API直传,速度快
|
|||
|
|
- ✅ 不需要模拟复杂的页面操作
|
|||
|
|
- ✅ 签名机制稳定
|
|||
|
|
|
|||
|
|
**劣势**:
|
|||
|
|
- ⚠️ 需要维护签名服务
|
|||
|
|
- ⚠️ 必须严格控制请求频率
|
|||
|
|
- ⚠️ Cookie管理更复杂
|
|||
|
|
|
|||
|
|
### 推荐使用策略
|
|||
|
|
|
|||
|
|
#### 使用xiaohongshu_uploader的场景
|
|||
|
|
1. **小批量上传**(每天<5个视频)
|
|||
|
|
2. **需要精细控制**(封面、地点等)
|
|||
|
|
3. **有稳定的代理IP**
|
|||
|
|
4. **可以接受较慢的上传速度**
|
|||
|
|
|
|||
|
|
**最佳实践**:
|
|||
|
|
```python
|
|||
|
|
# 1. 使用有头模式
|
|||
|
|
app = XiaoHongShuVideo(..., headless=False)
|
|||
|
|
|
|||
|
|
# 2. 控制上传频率
|
|||
|
|
for video in videos:
|
|||
|
|
await app.main()
|
|||
|
|
await asyncio.sleep(random.randint(600, 1200)) # 10-20分钟间隔
|
|||
|
|
|
|||
|
|
# 3. 定期更换Cookie
|
|||
|
|
if upload_count > 50:
|
|||
|
|
await xiaohongshu_setup(account_file, handle=True) # 重新登录
|
|||
|
|
|
|||
|
|
# 4. 避免高峰时段
|
|||
|
|
# 建议在凌晨2-6点上传
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 使用xhs_uploader的场景
|
|||
|
|
1. **批量上传**(每天>10个视频)
|
|||
|
|
2. **稳定性要求高**
|
|||
|
|
3. **有独立签名服务器**
|
|||
|
|
4. **可以接受30秒间隔**
|
|||
|
|
|
|||
|
|
**最佳实践**:
|
|||
|
|
```python
|
|||
|
|
# 1. 搭建签名服务
|
|||
|
|
XHS_SERVER = "http://your-sign-server.com"
|
|||
|
|
|
|||
|
|
# 2. 批量上传时控制并发
|
|||
|
|
for video in videos:
|
|||
|
|
xhs_client.create_video_note(...)
|
|||
|
|
sleep(30) # 必须间隔30秒
|
|||
|
|
|
|||
|
|
# 3. 使用多账号轮换
|
|||
|
|
accounts = [account1, account2, account3]
|
|||
|
|
for i, video in enumerate(videos):
|
|||
|
|
client = XhsClient(accounts[i % len(accounts)])
|
|||
|
|
client.create_video_note(...)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 详细差异对比表
|
|||
|
|
|
|||
|
|
| 特性 | xiaohongshu_uploader | xhs_uploader |
|
|||
|
|
|------|---------------------|-------------|
|
|||
|
|
| **技术方案** | Playwright浏览器自动化 | xhs SDK + API |
|
|||
|
|
| **上传方式** | 模拟页面操作 | API直传 |
|
|||
|
|
| **速度** | 慢 (5-10分钟/视频) | 快 (30秒/视频) |
|
|||
|
|
| **稳定性** | 中等 (易被检测) | 高 (官方接口) |
|
|||
|
|
| **反检测压力** | 高 | 低 |
|
|||
|
|
| **Cookie管理** | 自动保存更新 | 手动管理 |
|
|||
|
|
| **视频上传** | ✅ | ✅ |
|
|||
|
|
| **图文上传** | ❌ | ✅ |
|
|||
|
|
| **视频封面** | ✅ 支持 | ❌ 不支持 |
|
|||
|
|
| **地点设置** | ✅ 支持 | ❌ 不支持 |
|
|||
|
|
| **定时发布** | ✅ 支持 | ✅ 支持 |
|
|||
|
|
| **话题推荐** | ❌ 手动输入 | ✅ API获取 |
|
|||
|
|
| **批量上传** | 不推荐 | ✅ 推荐 |
|
|||
|
|
| **无头模式** | ⚠️ 不稳定 | ✅ 稳定 |
|
|||
|
|
| **间隔要求** | 建议10-20分钟 | 必须30秒 |
|
|||
|
|
| **签名需求** | 不需要 | ✅ 需要 |
|
|||
|
|
| **部署复杂度** | 低 | 中 (需签名服务) |
|
|||
|
|
| **维护成本** | 高 | 低 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🛡️ 反检测最佳实践
|
|||
|
|
|
|||
|
|
### 1. 通用策略
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 1. 使用代理IP
|
|||
|
|
# 建议使用住宅IP或动态IP池
|
|||
|
|
|
|||
|
|
# 2. 控制请求频率
|
|||
|
|
import random
|
|||
|
|
await asyncio.sleep(random.randint(600, 1200)) # 10-20分钟
|
|||
|
|
|
|||
|
|
# 3. 多账号轮换
|
|||
|
|
# 避免单账号频繁操作
|
|||
|
|
|
|||
|
|
# 4. 避开高峰时段
|
|||
|
|
# 凌晨2-6点成功率最高
|
|||
|
|
|
|||
|
|
# 5. 定期更新Cookie
|
|||
|
|
# 建议每周重新登录一次
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 小红书专项策略
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 针对xiaohongshu_uploader
|
|||
|
|
|
|||
|
|
# 1. 标签输入优化
|
|||
|
|
slow_config = {
|
|||
|
|
'min_delay': 500, # 最小延迟500ms (不能更快)
|
|||
|
|
'max_delay': 800, # 最大延迟800ms
|
|||
|
|
'pause_probability': 0.3, # 30%概率暂停
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 2. 标签间停顿
|
|||
|
|
await page.wait_for_timeout(800) # 每个标签后必须停顿
|
|||
|
|
|
|||
|
|
# 3. 地点选择停顿
|
|||
|
|
await page.wait_for_timeout(3000) # 地点下拉列表加载
|
|||
|
|
|
|||
|
|
# 4. 避免使用无头模式
|
|||
|
|
headless = False # 建议使用有头模式
|
|||
|
|
|
|||
|
|
# 5. 首次使用建议
|
|||
|
|
# - 先手动在浏览器登录一次
|
|||
|
|
# - 完成一次手动发布
|
|||
|
|
# - 再使用自动化脚本
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ⚙️ 配置说明
|
|||
|
|
|
|||
|
|
### conf.py 配置文件
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
# 项目根目录
|
|||
|
|
BASE_DIR = Path(__file__).resolve().parent
|
|||
|
|
|
|||
|
|
# 本地Chrome浏览器路径
|
|||
|
|
LOCAL_CHROME_PATH = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" # Windows
|
|||
|
|
# LOCAL_CHROME_PATH = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" # macOS
|
|||
|
|
|
|||
|
|
# 小红书签名服务器 (仅xhs_uploader需要)
|
|||
|
|
XHS_SERVER = "http://localhost:5005"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 环境变量
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# .env文件
|
|||
|
|
VITE_API_BASE_URL=http://localhost:5409
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📋 常见问题
|
|||
|
|
|
|||
|
|
### 1. Cookie失效怎么办?
|
|||
|
|
|
|||
|
|
**解决方法**:
|
|||
|
|
```bash
|
|||
|
|
# 重新获取Cookie
|
|||
|
|
python examples/get_xiaohongshu_cookie.py
|
|||
|
|
|
|||
|
|
# 或通过Web界面重新登录
|
|||
|
|
# 进入"账号管理" -> 选择失效账号 -> 重新登录
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 小红书上传失败?
|
|||
|
|
|
|||
|
|
**可能原因及解决方案**:
|
|||
|
|
|
|||
|
|
**A. 无头模式找不到元素**
|
|||
|
|
```python
|
|||
|
|
# 改为有头模式
|
|||
|
|
app = XiaoHongShuVideo(..., headless=False)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**B. 跳转到登录页**
|
|||
|
|
```python
|
|||
|
|
# 说明Cookie失效或触发反检测
|
|||
|
|
# 1. 检查Cookie是否过期
|
|||
|
|
# 2. 增加人类化输入延迟
|
|||
|
|
# 3. 使用代理IP
|
|||
|
|
# 4. 减少上传频率
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**C. 标签输入被拦截**
|
|||
|
|
```python
|
|||
|
|
# 当前已使用极慢速度 (500-800ms/字符)
|
|||
|
|
# 如果还被拦截,可能需要:
|
|||
|
|
# 1. 更换IP
|
|||
|
|
# 2. 更换账号
|
|||
|
|
# 3. 等待24小时后重试
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 如何提高上传成功率?
|
|||
|
|
|
|||
|
|
**针对xiaohongshu_uploader**:
|
|||
|
|
1. 使用有头模式 (`headless=False`)
|
|||
|
|
2. 减少标签数量 (建议≤3个)
|
|||
|
|
3. 增加操作间隔 (至少10分钟)
|
|||
|
|
4. 避免使用新注册账号
|
|||
|
|
5. 定期手动登录维持账号活跃度
|
|||
|
|
|
|||
|
|
**针对xhs_uploader**:
|
|||
|
|
1. 确保签名服务正常运行
|
|||
|
|
2. 严格遵守30秒间隔
|
|||
|
|
3. 使用多账号轮换
|
|||
|
|
4. 定期验证Cookie有效性
|
|||
|
|
|
|||
|
|
### 4. 数据库初始化失败?
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd db
|
|||
|
|
python createTable.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5. Playwright安装失败?
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 使用国内镜像
|
|||
|
|
export PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright/
|
|||
|
|
playwright install chromium
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔌 API文档
|
|||
|
|
|
|||
|
|
### 后端API端点
|
|||
|
|
|
|||
|
|
#### 1. 文件上传
|
|||
|
|
```http
|
|||
|
|
POST /upload
|
|||
|
|
Content-Type: multipart/form-data
|
|||
|
|
|
|||
|
|
参数:
|
|||
|
|
file: 视频文件
|
|||
|
|
|
|||
|
|
响应:
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": "File uploaded successfully",
|
|||
|
|
"data": "uuid_filename.mp4"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. 素材上传(带记录)
|
|||
|
|
```http
|
|||
|
|
POST /uploadSave
|
|||
|
|
Content-Type: multipart/form-data
|
|||
|
|
|
|||
|
|
参数:
|
|||
|
|
file: 视频文件
|
|||
|
|
filename: 自定义文件名(可选)
|
|||
|
|
|
|||
|
|
响应:
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": "File uploaded and saved successfully",
|
|||
|
|
"data": {
|
|||
|
|
"filename": "video.mp4",
|
|||
|
|
"filepath": "uuid_video.mp4"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3. 获取所有素材
|
|||
|
|
```http
|
|||
|
|
GET /getFiles
|
|||
|
|
|
|||
|
|
响应:
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": "success",
|
|||
|
|
"data": [
|
|||
|
|
{
|
|||
|
|
"id": 1,
|
|||
|
|
"filename": "video.mp4",
|
|||
|
|
"filesize": 10.5,
|
|||
|
|
"upload_time": "2025-01-01 10:00:00",
|
|||
|
|
"file_path": "uuid_video.mp4"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4. 删除素材
|
|||
|
|
```http
|
|||
|
|
GET /deleteFile?id=1
|
|||
|
|
|
|||
|
|
响应:
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": "File deleted successfully",
|
|||
|
|
"data": {
|
|||
|
|
"id": 1,
|
|||
|
|
"filename": "video.mp4"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 5. 发布视频
|
|||
|
|
```http
|
|||
|
|
POST /postVideo
|
|||
|
|
Content-Type: application/json
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"type": 1, # 1-小红书, 2-视频号, 3-抖音, 4-快手
|
|||
|
|
"title": "标题",
|
|||
|
|
"tags": ["话题1", "话题2"],
|
|||
|
|
"fileList": ["uuid_video.mp4"],
|
|||
|
|
"accountList": ["uuid_cookie.json"],
|
|||
|
|
"category": 0, # 0-非原创
|
|||
|
|
"enableTimer": 1, # 0-立即, 1-定时
|
|||
|
|
"videosPerDay": 2,
|
|||
|
|
"dailyTimes": ["10:00", "16:00"],
|
|||
|
|
"startDays": 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
响应:
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": null,
|
|||
|
|
"data": null
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 6. 批量发布
|
|||
|
|
```http
|
|||
|
|
POST /postVideoBatch
|
|||
|
|
Content-Type: application/json
|
|||
|
|
|
|||
|
|
[
|
|||
|
|
{
|
|||
|
|
"type": 1,
|
|||
|
|
"title": "标题1",
|
|||
|
|
...
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"type": 2,
|
|||
|
|
"title": "标题2",
|
|||
|
|
...
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 7. 获取有效账号
|
|||
|
|
```http
|
|||
|
|
GET /getValidAccounts
|
|||
|
|
|
|||
|
|
响应:
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": null,
|
|||
|
|
"data": [
|
|||
|
|
[1, 1, "uuid.json", "账号名", 1]
|
|||
|
|
# [id, type, filePath, userName, status]
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 8. 删除账号
|
|||
|
|
```http
|
|||
|
|
GET /deleteAccount?id=1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 9. 更新账号信息
|
|||
|
|
```http
|
|||
|
|
POST /updateUserinfo
|
|||
|
|
Content-Type: application/json
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"id": 1,
|
|||
|
|
"type": 1,
|
|||
|
|
"userName": "新名称"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 10. 账号登录 (SSE)
|
|||
|
|
```http
|
|||
|
|
GET /login?type=1&id=账号名
|
|||
|
|
|
|||
|
|
# SSE流,返回二维码URL和登录状态
|
|||
|
|
data: https://qrcode-url.jpg
|
|||
|
|
...
|
|||
|
|
data: 200 # 登录成功
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🤝 贡献指南
|
|||
|
|
|
|||
|
|
欢迎提交Issue和Pull Request!
|
|||
|
|
|
|||
|
|
### 提交规范
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 创建功能分支
|
|||
|
|
git checkout -b feature/your-feature
|
|||
|
|
|
|||
|
|
# 提交代码
|
|||
|
|
git commit -m "feat: add new feature"
|
|||
|
|
|
|||
|
|
# 推送到远程
|
|||
|
|
git push origin feature/your-feature
|
|||
|
|
|
|||
|
|
# 创建Pull Request
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Commit类型
|
|||
|
|
- `feat`: 新功能
|
|||
|
|
- `fix`: 修复bug
|
|||
|
|
- `docs`: 文档更新
|
|||
|
|
- `style`: 代码格式调整
|
|||
|
|
- `refactor`: 代码重构
|
|||
|
|
- `test`: 测试相关
|
|||
|
|
- `chore`: 构建/工具配置
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📄 许可证
|
|||
|
|
|
|||
|
|
本项目采用 [MIT License](LICENSE) 开源许可证。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🙏 致谢
|
|||
|
|
|
|||
|
|
- [Playwright](https://playwright.dev/) - 强大的自动化测试框架
|
|||
|
|
- [xhs](https://github.com/ReaJason/xhs) - 小红书API封装
|
|||
|
|
- [biliup](https://github.com/biliup/biliup) - B站上传工具
|
|||
|
|
- [Element Plus](https://element-plus.org/) - Vue3 UI组件库
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📞 联系方式
|
|||
|
|
|
|||
|
|
- 官方文档: https://sap-doc.nasdaddy.com/
|
|||
|
|
- GitHub: https://github.com/dreammis/social-auto-upload
|
|||
|
|
- 微信公众号: NasDaddy (后台回复"上传"获取加群方式)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ⭐ Star History
|
|||
|
|
|
|||
|
|
如果这个项目对您有帮助,请给一个 ⭐ Star 以表示支持!
|
|||
|
|
|
|||
|
|
[](https://star-history.com/#dreammis/social-auto-upload&Date)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 更新日志
|
|||
|
|
|
|||
|
|
### v1.0.0 (2025-01-28)
|
|||
|
|
- ✅ 完善小红书反检测机制
|
|||
|
|
- ✅ 增加人类化输入模拟
|
|||
|
|
- ✅ 优化标签输入速度控制
|
|||
|
|
- ✅ 添加批量发布功能
|
|||
|
|
- ✅ 改进Web管理界面
|
|||
|
|
- ✅ 增强Cookie管理
|
|||
|
|
|
|||
|
|
### 计划中
|
|||
|
|
- [ ] Docker一键部署
|
|||
|
|
- [ ] YouTube平台支持
|
|||
|
|
- [ ] 消息推送通知
|
|||
|
|
- [ ] 更智能的AI标题生成
|
|||
|
|
- [ ] 视频自动裁剪适配各平台
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**⚠️ 免责声明**
|
|||
|
|
|
|||
|
|
本项目仅供学习交流使用,请勿用于商业目的或违反平台服务条款的行为。使用本工具所产生的一切后果由使用者自行承担。
|
|||
|
|
|
|||
|
|
|
|||
|
|
|