From ba70f3ce215fe89398cd4cc26f2cafbc516390db Mon Sep 17 00:00:00 2001 From: faker447 <1206361312@qq.com> Date: Mon, 8 Jul 2024 15:48:51 +0800 Subject: [PATCH] Add files via upload --- README.md | 151 +++++++++++ image.py | 80 ++++++ recognize.py | 19 ++ requirements.txt | 7 + run.py | 647 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 904 insertions(+) create mode 100644 README.md create mode 100644 image.py create mode 100644 recognize.py create mode 100644 requirements.txt create mode 100644 run.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..1663bb5 --- /dev/null +++ b/README.md @@ -0,0 +1,151 @@ +

+ + Logo + +

PikPak自动邀请

+

+ · + 报告Bug + · + 提出新特性 +

+

+ +基于bilibili平台UP主[纸鸢花的花语](https://space.bilibili.com/67788420/)所公开的源码以及其群管理Atong的pikpak临时碰撞版脚本进行修改的PikPak自动邀请程序,附带图像识别过验证码 + + + +[![Contributors][contributors-shield]][contributors-url] +[![Forks][forks-shield]][forks-url] +[![Stargazers][stars-shield]][stars-url] +[![Issues][issues-shield]][issues-url] + + + +## 目录 + +- [作者](#作者) +- [上手指南](#上手指南) + - [本地运行](#本地运行) + - [GitHub Actions运行(每日云端定时自动运行)](#GitHubActions运行) +- [文件目录说明](#文件目录说明) +- [说明](#说明) + +### 作者 + +临渊 + +邮箱:<1577242215@qq.com> + +### 上手指南 + +#### 本地运行 + +##### 使用前的配置 + +在使用本项目前请确保你具有以下环境 + +1. Python[推荐Python3.9~~别问为什么,我就是3.9,别的我不知道能不能运行~~](如未安装请查看[Python安装教程](https://blog.csdn.net/maiya_yayaya/article/details/131828467?ops_request_misc=&request_id=&biz_id=102&utm_term=python如何安装&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-131828467.142^v100^pc_search_result_base7&spm=1018.2226.3001.4187)) +2. pip(如未安装请查看[pip安装及如何加速安装第三方组件](https://blog.csdn.net/figo0423/article/details/136146344?ops_request_misc=%7B%22request%5Fid%22%3A%22171784122216800226579490%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=171784122216800226579490&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-7-136146344-null-null.142^v100^pc_search_result_base7&utm_term=pip如何安装&spm=1018.2226.3001.4187)) + +##### **安装步骤** + +1. 克隆项目到本地,如无法克隆也可以直接从右上角下载zip压缩包到本地解压 + +```shell +git clone https://github.com/LinYuanovo/pikpak_auto_invite.git +``` + +2. 进入到项目目录 + +```shell +cd pikpak_auto_invite +``` + +3. 安装项目所需依赖(如安装有问题自行换源) + +```shell +pip install -r requirements.txt +``` + +##### 效果演示 + +在项目目录下用终端输入或利用`Pycharm`等工具直接运行`run.py` + +```shell +python run.py +``` + +![效果演示](https://raw.githubusercontent.com/LinYuanovo/pic_bed/main/pikpak_auto_invite/7c010670-6d0c-41c0-8ad5-d6dab5e6bf02.png) + +如果需要查看请求返回信息,请将主程序`run.py`的`DEBUG_MODE`参数设为True + +如果多次出现IP问题可尝试将自己所用的魔法设置为代理,即主程序`run.py`的`PROXY`参数 + +如果觉得模型不够满意也可以查看我的另一个项目[Ddddocr 自训练今日校园、PikPak验证码模型](https://github.com/LinYuanovo/ddddocr_models)里面包含了几个版本的模型以及数据集,可以自己进行训练 + +#### GitHubActions运行 + +[B站-视频教程](https://www.bilibili.com/video/BV1JZ3FeWEsF/) + +1. 点击项目右上角进行**fork**,也可以顺手点个**star** + + ![对项目进行fork](https://raw.githubusercontent.com/LinYuanovo/pic_bed/main/pikpak_auto_invite/f43174c1-1576-4ab0-b86f-31355b400887.png) + +2. 然后点击你fork的项目中的**Settings**,找到**Secrets and variables**,选中**Actions**里的**New repository secret**添加一个环境变量,名称必须为**INVITE_CODE**,内容就填你的邀请码 + + ![添加变量](https://raw.githubusercontent.com/LinYuanovo/pic_bed/main/pikpak_auto_invite/8ad57054-1c8b-4100-8e24-ab8d6ef51899.png) + + ![添加变量](https://raw.githubusercontent.com/LinYuanovo/pic_bed/main/pikpak_auto_invite/1a702216-0a12-44c4-8067-54eb8e34e7c5.png) + +3. 点击你项目上方的**Actions**,第一次打开可能需要点击 `I understand...`,来启用actions + +4. 提交修改来触发Actions,建议直接修改`run.py`,在空白的地方输入一次换行**commit**提交即可 + + ![修改run.py](https://raw.githubusercontent.com/LinYuanovo/pic_bed/main/pikpak_auto_invite/44e7cf20-658a-4400-99a3-35babc2d5834.png) + + ![提交修改](https://raw.githubusercontent.com/LinYuanovo/pic_bed/main/pikpak_auto_invite/cca72584-36be-4b16-b0bb-141899eaa1b5.png) + +5. 点开**Actions**查看运行日志 + + ![查看日志](https://raw.githubusercontent.com/LinYuanovo/pic_bed/main/pikpak_auto_invite/3e58af4c-bf57-496c-9129-d237fd0aae7d.png) + + ![查看日志](https://raw.githubusercontent.com/LinYuanovo/pic_bed/main/pikpak_auto_invite/2cbadd33-bb64-4619-bc38-f86b3bd59ed8.png) + + 至此操作完成,每天早十点、晚六点十分各定时执行一次(可以自己到`/.github/workflows/run.yml`中修改定时),可以以同样方式进入**Actions**查看日志 + +### 文件目录说明 + +``` +pikpak_auto_invite +├── /.github/ +│ │── /workflows/ +│ │ │── run.yml Github Actions配置文件 +├── README.md +├── /models/ +│ │── pikpak3.0.onnx 图像识别模型 +│ │── pikpak4.0.onnx 图像识别模型 +│ │── charsets.json 配置 +├── /temp/ 缓存验证图片 +├── run.py 程序主入口 +├── image.py 处理图片 +└── recognize.py 图像识别 +``` + +### 说明 + +- 本项目仅仅只是在UP主[纸鸢花的花语](https://space.bilibili.com/67788420/)所公开的源码以及其群管理Atong的脚本基础上进行简单修改,加入了图像识别处理验证码,并未进行任何架构上的更改。上传本项目也仅为了用于学习研究以及备份,无任何不良引导,如有侵权请联系我进行删除。如果项目对你有帮助欢迎点点star。 +- 项目依赖于GitHub Actions运行,不会泄露你的邀请码 +- 官方限制现在邀请的会员掉了人数也不会掉,所以邀请之前请查看自己人数是否超**50**人 + + + +[your-project-path]:LinYuanovo/pikpak_auto_invite +[contributors-shield]: https://img.shields.io/github/contributors/LinYuanovo/pikpak_auto_invite.svg?style=flat-square +[contributors-url]: https://github.com/LinYuanovo/pikpak_auto_invite/graphs/contributors +[forks-shield]: https://img.shields.io/github/forks/LinYuanovo/pikpak_auto_invite.svg?style=flat-square +[forks-url]: https://github.com/LinYuanovo/pikpak_auto_invite/network/members +[stars-shield]: https://img.shields.io/github/stars/LinYuanovo/pikpak_auto_invite.svg?style=flat-square +[stars-url]: https://github.com/LinYuanovo/pikpak_auto_invite/stargazers +[issues-shield]: https://img.shields.io/github/issues/LinYuanovo/pikpak_auto_invite.svg?style=flat-square +[issues-url]: https://img.shields.io/github/issues/LinYuanovo/pikpak_auto_invite.svg diff --git a/image.py b/image.py new file mode 100644 index 0000000..c4bb1de --- /dev/null +++ b/image.py @@ -0,0 +1,80 @@ +import os +import cv2 +import matplotlib.pyplot as plt +import numpy as np + + +# 导入原始图像 +def read_img(path): + img = cv2.imread(path) + # 获取图像基本信息 + height, width, channel = img.shape + return img, height, width + + +# 图像切割 +def cut_img(img, height, width, matrix): + # 切割图像 + img_list = [[0 for _ in range(len(matrix[0]))] for _ in range(len(matrix[0]))] + for i in range(len(matrix[0])): + for j in range(len(matrix[0])): + # 纵向切割 + img_list[j][i] = img[i * height // len(matrix[0]): (i + 1) * height // len(matrix[0]), + j * width // len(matrix[0]): (j + 1) * width // len(matrix[0])] + return img_list + + +# 图像重组 +def re_img(img_list, height, width, matrix): + new_img_list = [[0 for _ in range(len(matrix[0]))] for _ in range(len(matrix[0]))] + for i in range(len(matrix[0])): + for j in range(len(matrix[0])): + k, l = matrix[i][j].split(',') + new_img_list[i][j] = img_list[int(k)][int(l)] + # 图像拼接 + img = np.zeros((height, width, 3), np.uint8) + for i in range(len(matrix[0])): + for j in range(len(matrix[0])): + img[i * height // len(matrix[0]): (i + 1) * height // len(matrix[0]), + j * width // len(matrix[0]): (j + 1) * width // len(matrix[0])] = new_img_list[i][j] + return img + + +# 图像展示 +def show_img_list(img_list): + n = len(img_list) + for i in range(n): + for j in range(n): + plt.subplot(n, n, i * n + j + 1) + plt.imshow(img_list[i][j]) + plt.axis('off') + plt.show() + + +def show_img(img): + plt.imshow(img) + plt.axis('off') + plt.show() + + +# 保存图像 +def save_img(img, path): + if not os.path.exists(os.path.dirname(path)): + os.makedirs(os.path.dirname(path)) + cv2.imwrite(path, img) + + +# 删除缓存图像 +def delete_img(): + for file in os.listdir('temp/'): + os.remove(f'temp/{file}') + print('删除缓存图片成功') + + +def run(img_path, frames): + iamge, height, width = read_img(img_path) + img_list = cut_img(iamge, height, width, frames[0]['matrix']) + for i in range(len(frames)): + matrix = frames[i]['matrix'] + temp_img = re_img(img_list, height, width, matrix) + save_img(temp_img, f'temp/{i}.png') diff --git a/recognize.py b/recognize.py new file mode 100644 index 0000000..5c48caf --- /dev/null +++ b/recognize.py @@ -0,0 +1,19 @@ +import ddddocr +import os + + +def run(): + ocr = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False, import_onnx_path="models/pikpak4.0.onnx", + charsets_path="models/charsets.json") + + ima_path = 'temp/' + for file in os.listdir(ima_path): + with open(f"{ima_path}/{file}", 'rb') as f: + image_bytes = f.read() + if ocr.classification(image_bytes) == 'correct': + # print(f'{file.split(".")[0]}') + return file.split(".")[0] + + +if __name__ == '__main__': + run() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4318038 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +aiohttp==3.8.4 +ddddocr==1.4.10 +matplotlib==3.7.1 +numpy==1.23.3 +opencv_python==4.6.0.66 +opencv_python_headless==4.6.0.66 +rich==13.7.1 diff --git a/run.py b/run.py new file mode 100644 index 0000000..4cf3dff --- /dev/null +++ b/run.py @@ -0,0 +1,647 @@ +import json +import hashlib +import os +import re +import time +import asyncio +import aiohttp +import uuid +import image +import recognize +from rich import print_json + +DEBUG_MODE = False # Debug模式,是否打印请求返回信息 +# PROXY = input('请输入代理,如不需要直接回车:') # 代理,如果多次出现IP问题可尝试将自己所用的魔法设置为代理。例如:使用clash则设置为 'http://127.0.0.1:7890' +PROXY = '' +INVITE_CODE = os.getenv('INVITE_CODE') or input('请输入邀请码: ') + + +# 检查变量 +def check_env(): + if not INVITE_CODE: + print('请按照文档设置INVITE_CODE环境变量') + raise Exception('请按照文档设置INVITE_CODE环境变量') + + +# 滑块数据加密 +def r(e, t): + n = t - 1 + if n < 0: + n = 0 + r = e[n] + u = r["row"] // 2 + 1 + c = r["column"] // 2 + 1 + f = r["matrix"][u][c] + l = t + 1 + if l >= len(e): + l = t + d = e[l] + p = l % d["row"] + h = l % d["column"] + g = d["matrix"][p][h] + y = e[t] + m = 3 % y["row"] + v = 7 % y["column"] + w = y["matrix"][m][v] + b = i(f) + o(w) + x = i(w) - o(f) + return [s(a(i(f), o(f))), s(a(i(g), o(g))), s(a(i(w), o(w))), s(a(b, x))] + + +def i(e): + return int(e.split(",")[0]) + + +def o(e): + return int(e.split(",")[1]) + + +def a(e, t): + return str(e) + "^⁣^" + str(t) + + +def s(e): + t = 0 + n = len(e) + for r in range(n): + t = u(31 * t + ord(e[r])) + return t + + +def u(e): + t = -2147483648 + n = 2147483647 + if e > n: + return t + (e - n) % (n - t + 1) - 1 + if e < t: + return n - (t - e) % (n - t + 1) + 1 + return e + + +def c(e, t): + return s(e + "⁣" + str(t)) + + +def img_jj(e, t, n): + return {"ca": r(e, t), "f": c(n, t)} + + +def md5(input_string): + return hashlib.md5(input_string.encode()).hexdigest() + + +async def get_sign(xid, t): + e = [ + {"alg": "md5", "salt": "KHBJ07an7ROXDoK7Db"}, + {"alg": "md5", "salt": "G6n399rSWkl7WcQmw5rpQInurc1DkLmLJqE"}, + {"alg": "md5", "salt": "JZD1A3M4x+jBFN62hkr7VDhkkZxb9g3rWqRZqFAAb"}, + {"alg": "md5", "salt": "fQnw/AmSlbbI91Ik15gpddGgyU7U"}, + {"alg": "md5", "salt": "/Dv9JdPYSj3sHiWjouR95NTQff"}, + {"alg": "md5", "salt": "yGx2zuTjbWENZqecNI+edrQgqmZKP"}, + {"alg": "md5", "salt": "ljrbSzdHLwbqcRn"}, + {"alg": "md5", "salt": "lSHAsqCkGDGxQqqwrVu"}, + {"alg": "md5", "salt": "TsWXI81fD1"}, + {"alg": "md5", "salt": "vk7hBjawK/rOSrSWajtbMk95nfgf3"} + ] + md5_hash = f"YvtoWO6GNHiuCl7xundefinedmypikpak.com{xid}{t}" + for item in e: + md5_hash += item["salt"] + md5_hash = md5(md5_hash) + return md5_hash + + +async def get_mail(): + json_data = { + "min_name_length": 10, + "max_name_length": 10 + } + url = 'https://api.internal.temp-mail.io/api/v3/email/new' + async with aiohttp.ClientSession() as session: + async with session.post(url, json=json_data, ssl=False) as response: + response_data = await response.json() + mail = response_data['email'] + return mail + + +# 获取邮箱的验证码内容 +async def get_code(mail, max_retries=10, delay=1): + retries = 0 + while retries < max_retries: + url = f'https://api.internal.temp-mail.io/api/v3/email/{mail}/messages' + async with aiohttp.ClientSession() as session: + async with session.get(url, ssl=False) as response: + html = await response.json() + if html: + text = (html[0])['body_text'] + code = re.search('\\d{6}', text).group() + print(f'获取邮箱验证码:{code}') + return code + else: + time.sleep(delay) + retries += 1 + print("获取邮箱邮件内容失败,未收到邮件...") + return None + + +async def init(xid, mail): + url = 'https://user.mypikpak.com/v1/shield/captcha/init' + body = { + "client_id": "YvtoWO6GNHiuCl7x", + "action": "POST:/v1/auth/verification", + "device_id": xid, + "captcha_token": "", + "meta": { + "email": mail + } + } + headers = { + 'host': 'user.mypikpak.com', + 'content-length': str(len(json.dumps(body))), + 'accept': '*/*', + 'accept-encoding': 'gzip, deflate, br', + 'referer': 'https://pc.mypikpak.com', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'cross-site', + 'user-agent': 'MainWindow Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' + 'PikPak/2.3.2.4101 Chrome/100.0.4896.160 Electron/18.3.15 Safari/537.36', + 'accept-language': 'zh-CN', + 'content-type': 'application/json', + 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'x-client-id': 'YvtoWO6GNHiuCl7x', + 'x-client-version': '2.3.2.4101', + 'x-device-id': xid, + 'x-device-model': 'electron%2F18.3.15', + 'x-device-name': 'PC-Electron', + 'x-device-sign': 'wdi10.ce6450a2dc704cd49f0be1c4eca40053xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + 'x-net-work-type': 'NONE', + 'x-os-version': 'Win32', + 'x-platform-version': '1', + 'x-protocol-version': '301', + 'x-provider-name': 'NONE', + 'x-sdk-version': '6.0.0' + } + async with aiohttp.ClientSession() as session: + async with session.post(url, json=body, headers=headers, ssl=False, proxy=PROXY) as response: + response_data = await response.json() + if 'url' in response_data: + if DEBUG_MODE: + print('初始安全验证:') + print_json(json.dumps(response_data, indent=4)) + return response_data + else: + raise print('IP频繁,请更换IP或者稍后再试!!!\n', response_data['error_description']) + + +async def get_image(xid): + url = "https://user.mypikpak.com/pzzl/gen" + params = { + "deviceid": xid, + "traceid": "" + } + async with aiohttp.ClientSession() as session: + async with session.get(url, params=params, ssl=False, proxy=PROXY) as response: + imgs_json = await response.json() + frames = imgs_json["frames"] + pid = imgs_json['pid'] + traceid = imgs_json['traceid'] + if DEBUG_MODE: + print('滑块ID:') + print_json(json.dumps(pid, indent=4)) + params = { + 'deviceid': xid, + 'pid': pid, + 'traceid': traceid + } + async with session.get(f"https://user.mypikpak.com/pzzl/image", params=params, ssl=False, + proxy=PROXY) as response1: + img_data = await response1.read() + # 保存初始图片 + save_image(img_data, f'temp/1.png') + # 保存拼图图片 + image.run(f'temp/1.png', frames) + # 识别图片 + select_id = recognize.run() + # 删除缓存图片 + image.delete_img() + json_data = img_jj(frames, int(select_id), pid) + f = json_data['f'] + npac = json_data['ca'] + params = { + 'pid': pid, + 'deviceid': xid, + 'traceid': traceid, + 'f': f, + 'n': npac[0], + 'p': npac[1], + 'a': npac[2], + 'c': npac[3] + } + async with session.get(f"https://user.mypikpak.com/pzzl/verify", params=params, ssl=False, + proxy=PROXY) as response1: + response_data = await response1.json() + result = {'pid': pid, 'traceid': traceid, 'response_data': response_data} + return result + + +def save_image(img_data, img_path): + if not os.path.exists(os.path.dirname(img_path)): + os.makedirs(os.path.dirname(img_path)) + with open(img_path, "wb") as f: + f.write(img_data) + + +async def get_new_token(result, xid, captcha): + traceid = result['traceid'] + pid = result['pid'] + async with aiohttp.ClientSession() as session: + async with session.get( + f"https://user.mypikpak.com/credit/v1/report?deviceid={xid}&captcha_token={captcha}&type" + f"=pzzlSlider&result=0&data={pid}&traceid={traceid}", ssl=False, proxy=PROXY) as response2: + response_data = await response2.json() + if DEBUG_MODE: + print('获取验证TOKEN:') + print_json(json.dumps(response_data, indent=4)) + return response_data + + +async def verification(captcha_token, xid, mail): + url = 'https://user.mypikpak.com/v1/auth/verification' + body = { + "email": mail, + "target": "ANY", + "usage": "REGISTER", + "locale": "zh-CN", + "client_id": "YvtoWO6GNHiuCl7x" + } + headers = { + 'host': 'user.mypikpak.com', + 'content-length': str(len(json.dumps(body))), + 'accept': '*/*', + 'accept-encoding': 'gzip, deflate, br', + 'referer': 'https://pc.mypikpak.com', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'cross-site', + 'user-agent': 'MainWindow Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' + 'PikPak/2.3.2.4101 Chrome/100.0.4896.160 Electron/18.3.15 Safari/537.36', + 'accept-language': 'zh-CN', + 'content-type': 'application/json', + 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'x-captcha-token': captcha_token, + 'x-client-id': 'YvtoWO6GNHiuCl7x', + 'x-client-version': '2.3.2.4101', + 'x-device-id': xid, + 'x-device-model': 'electron%2F18.3.15', + 'x-device-name': 'PC-Electron', + 'x-device-sign': 'wdi10.ce6450a2dc704cd49f0be1c4eca40053xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + 'x-net-work-type': 'NONE', + 'x-os-version': 'Win32', + 'x-platform-version': '1', + 'x-protocol-version': '301', + 'x-provider-name': 'NONE', + 'x-sdk-version': '6.0.0' + } + async with aiohttp.ClientSession() as session: + async with session.post(url, json=body, headers=headers, ssl=False, proxy=PROXY) as response: + response_data = await response.json() + if DEBUG_MODE: + print('发送验证码:') + print_json(json.dumps(response_data, indent=4)) + return response_data + + +async def verify(xid, verification_id, code): + url = 'https://user.mypikpak.com/v1/auth/verification/verify' + body = { + "verification_id": verification_id, + "verification_code": code, + "client_id": "YvtoWO6GNHiuCl7x" + } + headers = { + 'host': 'user.mypikpak.com', + 'content-length': str(len(json.dumps(body))), + 'accept': '*/*', + 'accept-encoding': 'gzip, deflate, br', + 'referer': 'https://pc.mypikpak.com', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'cross-site', + 'user-agent': 'MainWindow Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' + 'PikPak/2.3.2.4101 Chrome/100.0.4896.160 Electron/18.3.15 Safari/537.36', + 'accept-language': 'zh-CN', + 'content-type': 'application/json', + 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'x-client-id': 'YvtoWO6GNHiuCl7x', + 'x-client-version': '2.3.2.4101', + 'x-device-id': xid, + 'x-device-model': 'electron%2F18.3.15', + 'x-device-name': 'PC-Electron', + 'x-device-sign': 'wdi10.ce6450a2dc704cd49f0be1c4eca40053xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + 'x-net-work-type': 'NONE', + 'x-os-version': 'Win32', + 'x-platform-version': '1', + 'x-protocol-version': '301', + 'x-provider-name': 'NONE', + 'x-sdk-version': '6.0.0' + } + async with aiohttp.ClientSession() as session: + async with session.post(url, json=body, headers=headers, ssl=False, proxy=PROXY) as response: + response_data = await response.json() + if DEBUG_MODE: + print('验证码验证结果:') + print_json(json.dumps(response_data, indent=4)) + return response_data + + +async def signup(xid, mail, code, verification_token): + url = 'https://user.mypikpak.com/v1/auth/signup' + body = { + "email": mail, + "verification_code": code, + "verification_token": verification_token, + "password": "linyuan666", + "client_id": "YvtoWO6GNHiuCl7x" + } + headers = { + 'host': 'user.mypikpak.com', + 'content-length': str(len(json.dumps(body))), + 'accept': '*/*', + 'accept-encoding': 'gzip, deflate, br', + 'referer': 'https://pc.mypikpak.com', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'cross-site', + 'user-agent': 'MainWindow Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' + 'PikPak/2.3.2.4101 Chrome/100.0.4896.160 Electron/18.3.15 Safari/537.36', + 'accept-language': 'zh-CN', + 'content-type': 'application/json', + 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'x-client-id': 'YvtoWO6GNHiuCl7x', + 'x-client-version': '2.3.2.4101', + 'x-device-id': xid, + 'x-device-model': 'electron%2F18.3.15', + 'x-device-name': 'PC-Electron', + 'x-device-sign': 'wdi10.ce6450a2dc704cd49f0be1c4eca40053xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + 'x-net-work-type': 'NONE', + 'x-os-version': 'Win32', + 'x-platform-version': '1', + 'x-protocol-version': '301', + 'x-provider-name': 'NONE', + 'x-sdk-version': '6.0.0' + } + async with aiohttp.ClientSession() as session: + async with session.post(url, json=body, headers=headers, ssl=False, proxy=PROXY) as response: + response_data = await response.json() + if DEBUG_MODE: + print('注册结果:') + print_json(json.dumps(response_data, indent=4)) + return response_data + + +async def init1(xid, access_token, sub, sign, t): + url = 'https://user.mypikpak.com/v1/shield/captcha/init' + body = { + "client_id": "YvtoWO6GNHiuCl7x", + "action": "POST:/vip/v1/activity/invite", + "device_id": xid, + "captcha_token": access_token, + "meta": { + "captcha_sign": "1." + sign, + "client_version": "undefined", + "package_name": "mypikpak.com", + "user_id": sub, + "timestamp": t + }, + } + headers = { + 'host': 'user.mypikpak.com', + 'content-length': str(len(json.dumps(body))), + 'accept': '*/*', + 'accept-encoding': 'gzip, deflate, br', + 'accept-language': 'zh-CN', + 'referer': 'https://pc.mypikpak.com', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'cross-site', + 'user-agent': 'MainWindow Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' + 'PikPak/2.3.2.4101 Chrome/100.0.4896.160 Electron/18.3.15 Safari/537.36', + 'content-type': 'application/json', + 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'x-client-id': 'YvtoWO6GNHiuCl7x', + 'x-client-version': '2.3.2.4101', + 'x-device-id': xid, + 'x-device-model': 'electron%2F18.3.15', + 'x-device-name': 'PC-Electron', + 'x-device-sign': 'wdi10.ce6450a2dc704cd49f0be1c4eca40053xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + 'x-net-work-type': 'NONE', + 'x-os-version': 'Win32', + 'x-platform-version': '1', + 'x-protocol-version': '301', + 'x-provider-name': 'NONE', + 'x-sdk-version': '6.0.0' + } + async with aiohttp.ClientSession() as session: + async with session.post(url, json=body, headers=headers, ssl=False, proxy=PROXY) as response: + response_data = await response.json() + if DEBUG_MODE: + print('二次安全验证:') + print_json(json.dumps(response_data, indent=4)) + return response_data + + +async def invite(access_token, captcha_token, xid): + url = 'https://api-drive.mypikpak.com/vip/v1/activity/invite' + body = { + "apk_extra": { + "invite_code": "" + } + } + headers = { + 'host': 'api-drive.mypikpak.com', + 'content-length': str(len(json.dumps(body))), + 'accept': '*/*', + 'accept-encoding': 'gzip, deflate, br', + 'accept-language': 'zh-CN', + 'authorization': 'Bearer ' + access_token, + 'referer': 'https://pc.mypikpak.com', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'cross-site', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) PikPak/2.3.2.4101 ' + 'Chrome/100.0.4896.160 Electron/18.3.15 Safari/537.36', + 'content-type': 'application/json', + 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'x-captcha-token': captcha_token, + 'x-client-id': 'YvtoWO6GNHiuCl7x', + 'x-client-version': '2.3.2.4101', + 'x-device-id': xid, + 'x-system-language': 'zh-CN' + } + async with aiohttp.ClientSession() as session: + async with session.post(url, json=body, headers=headers, ssl=False, proxy=PROXY) as response: + response_data = await response.json() + if DEBUG_MODE: + print('获取邀请:') + print_json(json.dumps(response_data, indent=4)) + return response_data + + +async def init2(xid, access_token, sub, sign, t): + url = 'https://user.mypikpak.com/v1/shield/captcha/init' + body = { + "client_id": "YvtoWO6GNHiuCl7x", + "action": "POST:/vip/v1/order/activation-code", + "device_id": xid, + "captcha_token": access_token, + "meta": { + "captcha_sign": "1." + sign, + "client_version": "undefined", + "package_name": "mypikpak.com", + "user_id": sub, + "timestamp": t + }, + } + headers = { + 'host': 'user.mypikpak.com', + 'content-length': str(len(json.dumps(body))), + 'accept': '*/*', + 'accept-encoding': 'gzip, deflate, br', + 'accept-language': 'zh-CN', + 'referer': 'https://pc.mypikpak.com', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'cross-site', + 'user-agent': 'MainWindow Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' + 'PikPak/2.3.2.4101 Chrome/100.0.4896.160 Electron/18.3.15 Safari/537.36', + 'content-type': 'application/json', + 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'x-client-id': 'YvtoWO6GNHiuCl7x', + 'x-client-version': '2.3.2.4101', + 'x-device-id': xid, + 'x-device-model': 'electron%2F18.3.15', + 'x-device-name': 'PC-Electron', + 'x-device-sign': 'wdi10.ce6450a2dc704cd49f0be1c4eca40053xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + 'x-net-work-type': 'NONE', + 'x-os-version': 'Win32', + 'x-platform-version': '1', + 'x-protocol-version': '301', + 'x-provider-name': 'NONE', + 'x-sdk-version': '6.0.0' + } + async with aiohttp.ClientSession() as session: + async with session.post(url, json=body, headers=headers, ssl=False, proxy=PROXY) as response: + response_data = await response.json() + if DEBUG_MODE: + print('三次安全验证:') + print_json(json.dumps(response_data, indent=4)) + return response_data + + +async def activation_code(access_token, captcha, xid, in_code): + url = 'https://api-drive.mypikpak.com/vip/v1/order/activation-code' + body = { + "activation_code": in_code, + "page": "invite" + } + headers = { + 'host': 'api-drive.mypikpak.com', + 'content-length': str(len(json.dumps(body))), + 'accept': '*/*', + 'accept-encoding': 'gzip, deflate, br', + 'accept-language': 'zh-CN', + 'authorization': 'Bearer ' + access_token, + 'referer': 'https://pc.mypikpak.com', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'cross-site', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) PikPak/2.3.2.4101 ' + 'Chrome/100.0.4896.160 Electron/18.3.15 Safari/537.36', + 'content-type': 'application/json', + 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'x-captcha-token': captcha, + 'x-client-id': 'YvtoWO6GNHiuCl7x', + 'x-client-version': '2.3.2.4101', + 'x-device-id': xid, + 'x-system-language': 'zh-CN' + } + + async with aiohttp.ClientSession() as session: + try: + async with aiohttp.ClientSession() as session: + async with session.post(url, json=body, headers=headers, ssl=False, proxy=PROXY) as response: + response_data = await response.json() + if DEBUG_MODE: + print('填写邀请:') + print_json(json.dumps(response_data, indent=4)) + return response_data + except Exception as error: + print('Error:', error) + raise error + + +async def main(): + try: + check_env() + incode = INVITE_CODE + start_time = time.time() + xid = str(uuid.uuid4()).replace("-", "") + mail = await get_mail() + Init = await init(xid, mail) + while True: + print('验证滑块中...') + img_info = await get_image(xid) + if img_info['response_data']['result'] == 'accept': + print('验证通过!!!') + break + else: + print('验证失败, 重新验证滑块中...') + captcha_token_info = await get_new_token(img_info, xid, Init['captcha_token']) + verification_id = await verification(captcha_token_info['captcha_token'], xid, mail) + code = await get_code(mail) + verification_response = await verify(xid, verification_id['verification_id'], code) + signup_response = await signup(xid, mail, code, verification_response['verification_token']) + current_time = str(int(time.time())) + sign = await get_sign(xid, current_time) + init1_response = await init1(xid, signup_response['access_token'], signup_response['sub'], sign, current_time) + await invite(signup_response['access_token'], init1_response['captcha_token'], xid) + init2_response = await init2(xid, signup_response['access_token'], signup_response['sub'], sign, current_time) + activation = await activation_code(signup_response['access_token'], init2_response['captcha_token'], xid, + incode) + end_time = time.time() + run_time = f"{(end_time - start_time):.2f}" + if activation['add_days'] == 5: + print(f'邀请码: {incode} ==> 邀请成功, 用时: {run_time} 秒') + print(f'邮箱: {mail}') + print(f'密码: linyuan666') + return + else: + print(f'邀请码: {incode} ==> 邀请失败, 用时: {run_time} 秒') + # input('按回车键再次邀请!!!') + await main() + except Exception as e: + if '环境变量' in str(e): + return + print(f'异常捕获:{e}') + print('请检查网络环境,(开启科学上网)重试!!!') + # input('按回车键重试!!!') + # await main() + + +asyncio.run(main())