Files
Skill-123yunpan/references/competitor-upload-patterns.md
nxxy335 f0ecfa6de0 chore: 初始化 123yunpan skill 仓库 (v1.3.0)
- 完整 skill 本体:SKILL.md / README.md / manifest.json / config.json
- scripts/123yunpan.py:零依赖 CLI(含空间双配额、QPS 限流、零依赖 XLSX)
- references/ 参考资料
- 排除 .workbuddy/ 开发目录与 __pycache__
2026-09-27 22:41:43 +08:00

4.9 KiB
Raw Permalink Blame History

123云盘上传模式 & 竞品分析

来源:分析 Skillhub 上 123pan-upload skill 的实现,提取可借鉴的模式。

直链 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 刷新