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 @@
+
+
+
+
+
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())