- 完整 skill 本体:SKILL.md / README.md / manifest.json / config.json - scripts/123yunpan.py:零依赖 CLI(含空间双配额、QPS 限流、零依赖 XLSX) - references/ 参考资料 - 排除 .workbuddy/ 开发目录与 __pycache__
4.9 KiB
4.9 KiB
123云盘上传模式 & 竞品分析
来源:分析 Skillhub 上
123pan-uploadskill 的实现,提取可借鉴的模式。
短直链生成(Short Direct Link)
直链 URL 包含 user_id 和文件路径,较长且暴露用户信息。短直链只用 file_id,更隐私友好:
import base64, json
def get_user_id_from_token(token: str) -> int:
"""从 JWT token 解析 user_id,无需额外 API 调用"""
parts = token.split(".")
if len(parts) >= 2:
payload = parts[1]
padding = 4 - len(payload) % 4
if padding != 4:
payload += "=" * padding
data = json.loads(base64.b64decode(payload))
return data.get("id", 0)
return 0
def get_short_direct_link(user_id: int, file_id: int) -> str:
return f"https://{user_id}.v.123pan.cn/{user_id}/{file_id}"
对比:
| 类型 | URL 格式 | 隐私性 | 可直链下载 |
|---|---|---|---|
| 分享链接 | https://www.123pan.com/s/{shareKey} |
✅ 好 | ❌ 需跳转 |
| 完整直链 | https://{user_id}.v.123pan.cn/{user_id}/{file_id}/{filename} |
⚠️ 暴露路径 | ✅ |
| 短直链 | https://{user_id}.v.123pan.cn/{user_id}/{file_id} |
⚠️ 暴露 user_id | ✅ |
上传流程(V2 API)
⚠️ 2026-05 验证:以下流程经过实际 API 调用验证,修正了早期文档中的错误。
两个域名
| 域名 | 用途 | 端点 |
|---|---|---|
https://open-api.123pan.com |
主 API(认证、文件管理、chunked create) | /api/v1/*, /api/v2/*, /upload/v2/file/create |
https://openapi-upload.123242.com |
上传专用(获取上传域名返回此值) | /upload/v2/file/single/create, /upload/v2/file/slice, /upload/v2/file/upload_complete |
获取上传域名:GET /upload/v2/file/domain → 返回 ["https://openapi-upload.123242.com"](列表,非对象)
单文件上传(<100MB)
1. GET open-api.123pan.com/upload/v2/file/domain → 获取上传服务器地址
2. POST openapi-upload.123242.com/upload/v2/file/single/create → multipart/form-data 上传
关键坑点:
single/create必须用 multipart/form-data,不能用 JSON body。JSON 会导致 500 服务器崩溃。- 表单字段:
parentFileID(text),filename(text),etag(text),size(text),file(file) duplicate字段:不要传0(会导致 "duplicate参数错误")。不传默认覆盖,或传1(重命名)/2(覆盖)。- 响应:
{"code":0, "data":{"fileID": 12345, "completed": true}}— 无需额外上传步骤。
分片上传(100MB-10GB)
1. POST open-api.123pan.com/upload/v2/file/create → 创建上传任务(主域名)
2. POST openapi-upload.123242.com/upload/v2/file/slice → 逐片上传(上传域名)
3. POST openapi-upload.123242.com/upload/v2/file/upload_complete → 完成上传(上传域名)
关键坑点:
create调用主 API 域名,不是上传域名!slice和upload_complete调用上传域名。slice请求体字段名为partMd5(注意:不是sliceMD5,后者会导致 500)。- 分片大小由
create响应中的sliceSize决定(通常 16MB)。
SHA1 秒传
# create_file 响应中 reuse=true 表示文件已存在,跳过上传
if create_result["reuse"]:
return {"file_id": create_result["file_id"], ...}
上传校验轮询
# upload_complete 响应中 completed=false 时需轮询
# 建议间隔:1 秒
# 最大等待:~5 分钟/GB(10GB 文件约 50 分钟)
# 文件大小越大,校验时间越长
for attempt in range(max_retries):
resp = api_post("/upload/v2/file/upload_complete", {"preuploadID": preupload_id})
if resp["data"].get("completed"):
return resp["data"] # 校验完成
time.sleep(1) # 按 API 文档要求,每秒轮询一次
MD5 作为 Etag
上传创建时需要提供文件的 MD5 作为 etag 字段:
import hashlib
etag = hashlib.md5(open(file_path, "rb").read()).hexdigest()
WebDAV 上传(>10GB 文件)
API 上传上限 10GB,超大文件可用 WebDAV + rclone:
# 1. 配置 rclone(隔离配置,避免读取其他云服务凭证)
rclone config --config ~/123pan-rclone.conf
# 添加 "123pan-webdav" remote
# 2. 上传
RCLONE_CONFIG=~/123pan-rclone.conf rclone copy /path/to/large/file 123pan-webdav:/folder -P
# 3. 上传后通过 API 查找文件(WebDAV 上传有 30-90 秒索引延迟)
# 需要轮询 file/list 接口等待文件出现
注意: WebDAV 上传后文件不会立即出现在 API 列表中,需要重试查找(最多 30 次,每次间隔 3 秒)。
安全实践
- rclone 配置隔离:用
RCLONE_CONFIG环境变量指定独立配置文件 - 凭证存储:用环境变量或
.env文件,不要硬编码 - Token 刷新:123yunpan.py CLI 已自动处理 401 响应时的 token 刷新