diff --git a/all_in_one.sh b/all_in_one.sh index 9c30d9a..07be8ec 100644 --- a/all_in_one.sh +++ b/all_in_one.sh @@ -476,11 +476,12 @@ function qrcode_mode_choose() { if [ "${2}" == "/115cookie/115cookie.py" ]; then while true; do - qrcode_apps=('alipaymini' 'web' 'ios' 'android' 'windows' 'mac' 'linux' 'wechatmini') + qrcode_apps=('alipaymini' 'web' 'ios' '115ios' 'android' '115android' '115ipad' 'tv' 'qandroid' 'wechatmini' 'harmony') + qrcode_app_names=('115生活(支付宝小程序)' '115生活(网页端)' '115生活(iOS端)' '115(iOS端)' '115生活(Android端)' '115(Android端)' '115(iPad端)' '115生活(Android电视端)' '115管理(Android端)' '115生活(微信小程序)' '115(鸿蒙端)') find_qrcode_app=false interface= for i in "${!qrcode_apps[@]}"; do - interface="${interface}$((i + 1))、${qrcode_apps[$i]}\n" + interface="${interface}$((i + 1))、${qrcode_app_names[$i]} [${qrcode_apps[$i]}]\n" done INFO "请选择扫码绑定的设备(默认 1)" echo -e "${interface}\c" diff --git a/glue_python/115cookie/115cookie.py b/glue_python/115cookie/115cookie.py index 7101553..26ee9f9 100644 --- a/glue_python/115cookie/115cookie.py +++ b/glue_python/115cookie/115cookie.py @@ -13,7 +13,6 @@ import logging import argparse import sys from io import BytesIO -from enum import Enum from json import loads from urllib.parse import urlencode from urllib.request import urlopen, Request @@ -27,41 +26,21 @@ flask_app = Flask(__name__) logging.basicConfig(level=logging.INFO) LAST_STATUS = 0 - -AppEnum = Enum( - "AppEnum", - { - "web": 1, - "ios": 6, - "115ios": 8, - "android": 9, - "115android": 11, - "115ipad": 14, - "tv": 15, - "qandroid": 16, - "windows": 19, - "mac": 20, - "linux": 21, - "wechatmini": 22, - "alipaymini": 23, - }, +QRCODE_APPS = ( + "web", + "ios", + "115ios", + "android", + "115android", + "115ipad", + "tv", + "qandroid", + "wechatmini", + "alipaymini", + "harmony", ) -def get_enum_name(val, cls): - """ - 获取值其对应的名称 - """ - if isinstance(val, cls): - return val.name - try: - if isinstance(val, str): - return cls[val].name - except KeyError: - pass - return cls(val).name - - def get_qrcode_token(): """获取登录二维码,扫码可用 GET https://qrcodeapi.115.com/api/1.0/web/1.0/token/ @@ -85,62 +64,22 @@ def get_qrcode_status(payload): def post_qrcode_result(uid, app="web"): - """获取扫码登录的结果,并且绑定设备,包含 cookie - POST https://passportapi.115.com/app/1.0/{app}/1.0/login/qrcode/ + """获取扫码登录的结果并绑定设备,返回包含 cookie 的响应。 + + POST https://qrcodeapi.115.com/app/1.0/{app}/1.0/login/qrcode/ + :param uid: 二维码的 uid,取自 `login_qrcode_token` 接口响应 - :param app: 扫码绑定的设备,可以是 int、str 或者 AppEnum - app 至少有 23 个可用值,目前找出 13 个: - - 'web', 1, AppEnum.web - - 'ios', 6, AppEnum.ios - - '115ios', 8, AppEnum['115ios'] - - 'android', 9, AppEnum.android - - '115android', 11, AppEnum['115android'] - - '115ipad', 14, AppEnum['115ipad'] - - 'tv', 15, AppEnum.tv - - 'qandroid', 16, AppEnum.qandroid - - 'windows', 19, AppEnum.windows - - 'mac', 20, AppEnum.mac - - 'linux', 21, AppEnum.linux - - 'wechatmini', 22, AppEnum.wechatmini - - 'alipaymini', 23, AppEnum.alipaymini - 还有几个备选: - - bios - - bandroid - - qios(登录机制有些不同,暂时未破解) - - 设备列表如下: - - | No. | ssoent | app | description | - |-------:|:--------|:-----------|:-----------------------| - | 01 | A1 | web | 网页版 | - | 02 | A2 | ? | 未知: android | - | 03 | A3 | ? | 未知: iphone | - | 04 | A4 | ? | 未知: ipad | - | 05 | B1 | ? | 未知: android | - | 06 | D1 | ios | 115生活(iOS端) | - | 07 | D2 | ? | 未知: ios | - | 08 | D3 | 115ios | 115(iOS端) | - | 09 | F1 | android | 115生活(Android端) | - | 10 | F2 | ? | 未知: android | - | 11 | F3 | 115android | 115(Android端) | - | 12 | H1 | ipad | 未知: ipad | - | 13 | H2 | ? | 未知: ipad | - | 14 | H3 | 115ipad | 115(iPad端) | - | 15 | I1 | tv | 115网盘(Android电视端) | - | 16 | M1 | qandriod | 115管理(Android端) | - | 17 | N1 | qios | 115管理(iOS端) | - | 18 | O1 | ? | 未知: ipad | - | 19 | P1 | windows | 115生活(Windows端) | - | 20 | P2 | mac | 115生活(macOS端) | - | 21 | P3 | linux | 115生活(Linux端) | - | 22 | R1 | wechatmini | 115生活(微信小程序) | - | 23 | R2 | alipaymini | 115生活(支付宝小程序) | + :param app: 扫码绑定的设备标识,必须是 `QRCODE_APPS` 中的值 :return: dict,包含 cookie """ - app = get_enum_name(app, AppEnum) - payload = {"app": app, "account": uid} - api = f"https://passportapi.115.com/app/1.0/{app}/1.0/login/qrcode/" - return loads(urlopen(Request(api, data=urlencode(payload).encode("utf-8"), method="POST")).read()) + if app not in QRCODE_APPS: + raise ValueError(f"不支持的扫码绑定设备: {app}") + + headers = {"User-Agent": "UPhone/1.0.0"} if app == "ios" else {} + payload = {"account": uid} + api = f"https://qrcodeapi.115.com/app/1.0/{app}/1.0/login/qrcode/" + request = Request(api, data=urlencode(payload).encode("utf-8"), headers=headers, method="POST") + return loads(urlopen(request).read()) def get_qrcode(uid: str, /) -> str: @@ -228,7 +167,13 @@ def shutdown(): if __name__ == "__main__": parser = argparse.ArgumentParser(description="115 Cookie") parser.add_argument("--qrcode_mode", type=str, required=True, help="扫码模式") - parser.add_argument("--qrcode_app", type=str, default="alipaymini", help="扫码绑定设备") + parser.add_argument( + "--qrcode_app", + type=str, + choices=QRCODE_APPS, + default="alipaymini", + help="扫码绑定设备", + ) args = parser.parse_args() if args.qrcode_mode == "web": flask_app.config["QRCODE_APP"] = args.qrcode_app diff --git a/glue_python/115cookie/README.md b/glue_python/115cookie/README.md index 3ff6f90..676653b 100644 --- a/glue_python/115cookie/README.md +++ b/glue_python/115cookie/README.md @@ -1,5 +1,20 @@ # 115 Cookie QRCODE - 115.com - - passportapi.115.com - qrcodeapi.115.com + +## 扫码绑定设备 + +当前设备选项与 `p115client` 的 `p115qrcode` 命令行工具保持一致: + +- `alipaymini`:115生活(支付宝小程序,默认) +- `web`:115生活(网页端) +- `ios`:115生活(iOS端) +- `115ios`:115(iOS端) +- `android`:115生活(Android端) +- `115android`:115(Android端) +- `115ipad`:115(iPad端) +- `tv`:115生活(Android电视端) +- `qandroid`:115管理(Android端) +- `wechatmini`:115生活(微信小程序) +- `harmony`:115(鸿蒙端)