mirror of
https://github.com/CHERWING/CHERWIN_SCRIPTS.git
synced 2024-11-22 09:04:11 +08:00
第一次提交
This commit is contained in:
commit
52d3612c8a
942
ALYP.py
Executable file
942
ALYP.py
Executable file
@ -0,0 +1,942 @@
|
||||
'''
|
||||
阿里云盘签到
|
||||
功能:自动签到,领取签到奖品,支持多账号(使用#分割token),支持青龙
|
||||
到这里获取token:http://qr.ziyuand.cn/
|
||||
|
||||
cron: 1 1,12 1 * * *
|
||||
by:cherwin
|
||||
'''
|
||||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
|
||||
import requests
|
||||
from os import environ, path
|
||||
from sys import exit
|
||||
import datetime
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
|
||||
|
||||
def load_send():
|
||||
global send, mg
|
||||
cur_path = path.abspath(path.dirname(__file__))
|
||||
if path.exists(cur_path + "/notify.py"):
|
||||
try:
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
except:
|
||||
send = False
|
||||
print("加载通知服务失败~")
|
||||
else:
|
||||
send = False
|
||||
print("加载通知服务失败~")
|
||||
|
||||
|
||||
load_send()
|
||||
send_msg = ''
|
||||
|
||||
|
||||
def Log(cont):
|
||||
global send_msg
|
||||
print(cont)
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
|
||||
REFRESHTOEKN_PATH = "ALYP_REFRESH_TOEKN.json"
|
||||
|
||||
|
||||
def saveRefreeshToken(data):
|
||||
# 保存数据到文件
|
||||
if os.path.isfile(REFRESHTOEKN_PATH):
|
||||
with open(REFRESHTOEKN_PATH, 'r') as file:
|
||||
try:
|
||||
refresh_tokens = json.load(file)
|
||||
except:
|
||||
refresh_tokens = {}
|
||||
else:
|
||||
refresh_tokens = {}
|
||||
refresh_tokens.update(data)
|
||||
with open(REFRESHTOEKN_PATH, 'w') as file:
|
||||
json.dump(refresh_tokens, file)
|
||||
|
||||
|
||||
def loadRefreshTokens():
|
||||
try:
|
||||
with open(REFRESHTOEKN_PATH, 'r') as file:
|
||||
file_content = file.read()
|
||||
# print(file_content)
|
||||
if file_content:
|
||||
refresh_tokens = json.loads(file_content)
|
||||
else:
|
||||
refresh_tokens = ''
|
||||
except FileNotFoundError:
|
||||
refresh_tokens = ''
|
||||
|
||||
return refresh_tokens
|
||||
|
||||
|
||||
def is_last_day_of_month():
|
||||
today = datetime.date.today()
|
||||
next_month = today.replace(day=28) + datetime.timedelta(days=4)
|
||||
last_day = next_month - datetime.timedelta(days=next_month.day)
|
||||
return today == last_day
|
||||
|
||||
|
||||
class AliDrive_CheckIn:
|
||||
def __init__(self, refresh_token, ali_reward):
|
||||
self.userAgent = "Mozilla/5.0 (Linux; U; Android 11; zh-CN; Mi9 Pro 5G Build/RKQ1.200826.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/69.0.3497.100 UWS/3.22.2.28 Mobile Safari/537.36 UCBS/3.22.2.28_210922181100 ChannelId(0) NebulaSDK/1.8.100112 Nebula InsidePlus/10.2.3 AliApp(AYSD/4.9.1) AlipayDefined(nt:WIFI,ws:393|0|2.75)zh-CN useStatusBar/true isConcaveScreen/trueAriver/1.0.0"
|
||||
self.refresh_token = refresh_token
|
||||
self.ali_reward = ali_reward
|
||||
self.file_id = ''
|
||||
self.headers = {
|
||||
"Content-Type": "application/json",
|
||||
"charset": "utf-8",
|
||||
"User-Agent": self.userAgent
|
||||
}
|
||||
|
||||
def getToken(self):
|
||||
url = 'https://auth.aliyundrive.com/v2/account/token'
|
||||
body = {
|
||||
"grant_type": "refresh_token",
|
||||
"refresh_token": self.refresh_token
|
||||
}
|
||||
response = s.post(url, headers=self.headers, json=body, verify=False)
|
||||
try:
|
||||
resp = response.json()
|
||||
if resp.get('code') == 'InvalidParameter.RefreshToken':
|
||||
Log('\nRefreshToken 有误请检查!(可能token失效了,到这里获取http://qr.ziyuand.cn)\n')
|
||||
return False
|
||||
else:
|
||||
self.aliYunPanToken = f'Bearer {resp.get("access_token", "")}'
|
||||
self.access_token = resp.get("access_token", "")
|
||||
self.aliYunPanRefreshToken = resp.get("refresh_token", "")
|
||||
print(f'refresh_token:{self.aliYunPanRefreshToken}')
|
||||
self.user_id = resp.get("user_id", "")
|
||||
self.headers['Authorization'] = self.aliYunPanToken
|
||||
Log(f">账号ID:【{self.user_id}】\n>获取token成功")
|
||||
self.getUserInfo()
|
||||
# # 保存数据到文件
|
||||
# saveData = {self.user_id: self.aliYunPanRefreshToken}
|
||||
# saveRefreeshToken(saveData)
|
||||
return True
|
||||
except:
|
||||
print(response.text)
|
||||
return False
|
||||
|
||||
def getUserInfo(self):
|
||||
url = 'https://api.aliyundrive.com/adrive/v2/user/get'
|
||||
body = {
|
||||
"addition_data": {},
|
||||
"user_id": self.user_id
|
||||
}
|
||||
response = s.post(url, headers=self.headers, json=body, verify=False)
|
||||
try:
|
||||
resp = response.json()
|
||||
self.phone = resp.get("phone", "")
|
||||
self.default_drive_id = resp.get("default_drive_id", "")
|
||||
if self.phone !='':
|
||||
self.phone = self.phone[:3] + '*' * 4 + self.phone[7:]
|
||||
Log(f">手机号:【{self.phone}】")
|
||||
# 保存数据到文件
|
||||
saveData = {self.phone: self.aliYunPanRefreshToken}
|
||||
saveRefreeshToken(saveData)
|
||||
return True
|
||||
except:
|
||||
print(response.text)
|
||||
|
||||
def get_sign_in_list(self):
|
||||
Log(f'>>>>开始签到任务')
|
||||
sign_url = 'https://member.aliyundrive.com/v2/activity/sign_in_list?_rx-s=mobile}'
|
||||
sign_body = {'isReward': False}
|
||||
sign_res = s.post(sign_url, headers=self.headers, json=sign_body, verify=False)
|
||||
|
||||
try:
|
||||
sign_resp = sign_res.json()
|
||||
result = sign_resp.get('result', {})
|
||||
self.sign_in_count = result.get('signInCount', 0)
|
||||
is_sign_in = result.get('isSignIn', False)
|
||||
|
||||
if is_sign_in:
|
||||
Log(f'>签到成功!\n>已累计签到{self.sign_in_count}天!')
|
||||
else:
|
||||
Log(f'>今日已签到!\n>已累计签到{self.sign_in_count}天!')
|
||||
|
||||
sign_in_infos = result.get('signInInfos', [])
|
||||
rewards_list = sign_in_infos[self.sign_in_count - 1].get('rewards', [])
|
||||
status = rewards_list[1].get('status', '')
|
||||
# print(status)
|
||||
remind = rewards_list[1].get('remind', '')
|
||||
complete_status_list = ["verification", "finished", "end"]
|
||||
|
||||
if status not in complete_status_list:
|
||||
self.handle_task(remind)
|
||||
else:
|
||||
print(f'>任务【{remind}】已完成')
|
||||
except Exception as e:
|
||||
print(f"获取签到列表失败:{e}")
|
||||
|
||||
def handle_task(self, task_name):
|
||||
Log(f'>>开始【{task_name}】任务')
|
||||
if task_name == '接3次好运瓶即可领取奖励':
|
||||
self.bottle_fish()
|
||||
elif task_name == '订阅官方账号「阿里盘盘酱」即可领取奖励':
|
||||
self.follow_user()
|
||||
elif task_name == '上传10个文件到备份盘即可领取奖励':
|
||||
self.fileName = '签到任务文件_喜欢可以赞赏一波_谢谢.jpg'
|
||||
self.upload_files_to_drive(10)
|
||||
elif task_name == '开启手机自动备份并持续至少一小时':
|
||||
self.update_device_extras()
|
||||
elif task_name == '备份10张照片到相册即可领取奖励':
|
||||
self.fileName = '签到任务文件_喜欢可以赞赏一波_谢谢.jpg'
|
||||
self.upload_files_to_drive(10, 'alibum')
|
||||
elif task_name == '播放1个视频30秒即可领取奖励':
|
||||
# pass
|
||||
self.get_videoList()
|
||||
elif task_name == '接好运瓶并转存任意1个文件':
|
||||
self.get_bottleShareId()
|
||||
else:
|
||||
Log(f'>【{task_name}】-暂不支持此任务,请手动完成!')
|
||||
time.sleep(2)
|
||||
|
||||
###############################文件上传任务开始###############################
|
||||
|
||||
def upload_files_to_drive(self, num_files, drive_type='Default'):
|
||||
for i in range(num_files):
|
||||
self.get_user_drive_info(drive_type)
|
||||
time.sleep(1)
|
||||
|
||||
def get_user_drive_info(self, drive_type):
|
||||
url = "https://api.aliyundrive.com/v2/drive/list_my_drives"
|
||||
response = s.post(url, headers=self.headers, json={})
|
||||
try:
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
# print(data)
|
||||
drive_list = data.get("items", [])
|
||||
if drive_list != []:
|
||||
index = None
|
||||
for i, item in enumerate(drive_list):
|
||||
if drive_type == 'alibum':
|
||||
if item['drive_name'] == 'alibum':
|
||||
index = i
|
||||
break
|
||||
else:
|
||||
if item['drive_name'] == 'Default' and item['category'] == 'backup':
|
||||
index = i
|
||||
break
|
||||
self.drive_id = drive_list[index]['drive_id']
|
||||
print(f'当前drive ID:{self.drive_id}')
|
||||
if self.drive_id:
|
||||
self.file_create(drive_type,True)
|
||||
else:
|
||||
print("获取用户云盘信息API请求失败")
|
||||
except Exception as e:
|
||||
print(f"获取用户云盘信息失败:{e}")
|
||||
|
||||
def get_file_size(self, file_path):
|
||||
try:
|
||||
# 获取文件大小
|
||||
print(f'文件大小{os.path.getsize(file_path)}')
|
||||
return os.path.getsize(file_path)
|
||||
except OSError:
|
||||
return 0
|
||||
|
||||
def download_file(self, url,filename):
|
||||
response = requests.get(url,verify=False)
|
||||
if response.status_code == 200:
|
||||
with open(filename, 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'{filename} 下载签到视频文件完成!')
|
||||
return True
|
||||
else:
|
||||
print(f'下载签到视频文件失败:{response.status_code}')
|
||||
return False
|
||||
|
||||
def get_file_pre_hash(self, file_path,HashType='content_hash'):
|
||||
if HashType =='pre_hash':
|
||||
with open(file_path, 'rb') as f:
|
||||
sha1 = hashlib.sha1()
|
||||
data = f.read(1024) # 只读取前 1KB 的数据
|
||||
sha1.update(data)
|
||||
print(f'当前文件前1K hash值:{sha1.hexdigest().upper()}')
|
||||
return sha1.hexdigest().upper()
|
||||
else:
|
||||
with open(file_path, 'rb') as f:
|
||||
sha1 = hashlib.sha1()
|
||||
while True:
|
||||
data = f.read(4096)
|
||||
if not data:
|
||||
break
|
||||
sha1.update(data)
|
||||
print(f'当前文件完整hash值:{sha1.hexdigest().upper()}')
|
||||
return sha1.hexdigest().upper()
|
||||
|
||||
|
||||
def get_signTaskFileId(self):
|
||||
url = "https://api.aliyundrive.com/v2/file/search"
|
||||
json_data = {
|
||||
'drive_id': self.default_drive_id,
|
||||
'order_by': 'name ASC',
|
||||
'query': f'name = "{self.fileName}"',
|
||||
}
|
||||
response = s.post(url, headers=self.headers, json=json_data)
|
||||
data = response.json()
|
||||
|
||||
try:
|
||||
if response.status_code == 200:
|
||||
fileList = data.get("items", [])
|
||||
if fileList:
|
||||
print(f'找到签到任务文件id:{fileList[0]["file_id"]}')
|
||||
print(f'执行覆盖上传')
|
||||
self.file_id = fileList[0]['file_id']
|
||||
return fileList[0]['file_id']
|
||||
else:
|
||||
print(f'未找到签到任务文件')
|
||||
else:
|
||||
print("搜索文件API请求失败")
|
||||
except Exception as e:
|
||||
print(f"获取签到任务文件ID失败:{e}")
|
||||
|
||||
return ''
|
||||
|
||||
def file_create(self, type,needPreHash=True):
|
||||
self.filePath = f'./{self.fileName}'
|
||||
self.size = self.get_file_size(self.filePath)
|
||||
if self.size == 0:
|
||||
print('本地未发现签到视频文件,开始远程下载')
|
||||
if self.download_file(f'{server_base_url}签到任务文件_视频.mp4',self.fileName) and self.download_file(f'{server_base_url}签到任务文件_喜欢可以赞赏一波_谢谢.jpg', self.fileName):
|
||||
self.size = self.get_file_size(self.filePath)
|
||||
json_data = {
|
||||
'name': self.fileName,
|
||||
'type': 'file',
|
||||
'parent_file_id': 'root',
|
||||
'drive_id': self.drive_id,
|
||||
'check_name_mode': 'ignore',
|
||||
'size': self.size,
|
||||
"content_hash_name": "sha1",
|
||||
}
|
||||
if needPreHash:
|
||||
pre_hash = self.get_file_pre_hash(self.filePath,'pre_hash')
|
||||
json_data['pre_hash']=pre_hash
|
||||
else:
|
||||
content_hash = self.get_file_pre_hash(self.filePath,'content_hash')
|
||||
json_data['content_hash'] = content_hash
|
||||
json_data['proof_code'] = self._get_proof_code()
|
||||
json_data['proof_version'] = "v1"
|
||||
|
||||
|
||||
|
||||
url = "https://api.aliyundrive.com/v2/file/create"
|
||||
if type == 'alibum':
|
||||
url = "https://api.aliyundrive.com/adrive/v2/biz/albums/file/create"
|
||||
json_data['proof_version'] = 'v1'
|
||||
json_data['proof_code'] = self._get_proof_code()
|
||||
json_data['content_type'] = 'image/jpeg'
|
||||
json_data['create_scene'] = 'album_autobackup'
|
||||
json_data['check_name_mode'] = 'auto_rename'
|
||||
|
||||
if self.file_id == '':
|
||||
self.file_id = self.get_signTaskFileId()
|
||||
elif self.file_id != '':
|
||||
json_data['file_id'] = self.file_id
|
||||
|
||||
response = s.post(url, headers=self.headers, json=json_data)
|
||||
data = response.json()
|
||||
|
||||
try:
|
||||
if response.status_code == 201 or response.status_code == 200:
|
||||
rapid_upload = data.get('rapid_upload', False)
|
||||
self.file_id = data.get('file_id', '')
|
||||
print(rapid_upload)
|
||||
if rapid_upload:
|
||||
Log(f"文件秒传匹配成功")
|
||||
else:
|
||||
part_info_list = data.get('part_info_list', [])
|
||||
upload_url = part_info_list[0]['upload_url']
|
||||
if type != 'alibum':
|
||||
self.upload_id = data.get('upload_id', '')
|
||||
if upload_url:
|
||||
with open(self.filePath, 'rb') as f:
|
||||
part_content = f.read(self.size)
|
||||
response = s.put(upload_url, data=part_content)
|
||||
if response.status_code != 200:
|
||||
raise Exception(f"文件上传失败")
|
||||
Log(f"文件上传成功")
|
||||
self.file_complete()
|
||||
elif response.status_code == 409:
|
||||
Log(f"文件秒传匹配成功")
|
||||
self.file_create('Default',False)
|
||||
# if rapid_upload:
|
||||
# Log(f"文件秒传成功")
|
||||
# return "文件秒传成功"
|
||||
else:
|
||||
print(f"上传文件API请求失败{data}")
|
||||
except Exception as e:
|
||||
print(f"上传文件失败:{e}")
|
||||
|
||||
return ''
|
||||
|
||||
def file_complete(self):
|
||||
url = "https://api.aliyundrive.com/v2/file/complete"
|
||||
json_data = {
|
||||
'file_id': self.file_id,
|
||||
'upload_id': self.upload_id,
|
||||
'drive_id': self.drive_id
|
||||
}
|
||||
response = s.post(url, headers=self.headers, json=json_data)
|
||||
|
||||
if response.status_code == 200:
|
||||
print(f"上传状态上报成功")
|
||||
# file_delete(file_id, drive_id)
|
||||
else:
|
||||
print("上传文件API请求失败")
|
||||
|
||||
def file_delete(self, file_id, drive_id):
|
||||
url = "https://api.aliyundrive.com/v2/file/delete"
|
||||
json_data = {
|
||||
'file_id': file_id,
|
||||
'drive_id': drive_id
|
||||
}
|
||||
response = s.post(url, headers=self.headers, json=json_data)
|
||||
if response.status_code == 204:
|
||||
# print(data)
|
||||
print(f"删除文件成功")
|
||||
else:
|
||||
print("删除文件API请求失败")
|
||||
|
||||
def _get_proof_code(self) -> str:
|
||||
"""计算proof_code"""
|
||||
md5_int = int(hashlib.md5(self.access_token.encode()).hexdigest()[:16], 16)
|
||||
# file_size = os.path.getsize(file_path)
|
||||
offset = md5_int % self.size if self.size else 0
|
||||
if self.filePath.startswith('http'):
|
||||
# noinspection PyProtectedMember
|
||||
bys = self._session.get(self.filePath, headers={
|
||||
'Range': f'bytes={offset}-{min(8 + offset, self.size) - 1}'
|
||||
}).content
|
||||
else:
|
||||
with open(self.filePath, 'rb') as file:
|
||||
file.seek(offset)
|
||||
bys = file.read(min(8, self.size - offset))
|
||||
return base64.b64encode(bys).decode()
|
||||
|
||||
###############################文件上传任务结束###############################
|
||||
#接好运瓶
|
||||
def bottle_fish(self):
|
||||
json_data = {}
|
||||
for i in range(3):
|
||||
response = s.post('https://api.aliyundrive.com/adrive/v1/bottle/fish', headers=self.headers,
|
||||
json=json_data, verify=False)
|
||||
if response.status_code == 200:
|
||||
Log('接好运瓶成功!')
|
||||
else:
|
||||
print(response.text)
|
||||
|
||||
#######################接好运瓶并转存1个文件任务
|
||||
|
||||
# 接好运瓶获取分享ID
|
||||
def get_bottleShareId(self):
|
||||
json_data = {}
|
||||
response = s.post('https://api.aliyundrive.com/adrive/v1/bottle/fish', headers=self.headers,json=json_data, verify=False)
|
||||
if response.status_code == 200:
|
||||
resp = response.json()
|
||||
self.shareid = resp.get('shareId','')
|
||||
print(f'获取到好运瓶分享ID:【{self.shareid}】')
|
||||
self.get_shareFileId()
|
||||
else:
|
||||
print(response.text)
|
||||
|
||||
#根据shareid获取分享文件file_id
|
||||
def get_shareFileId(self):
|
||||
json_data = {"share_id":self.shareid}
|
||||
response = s.post('https://api.aliyundrive.com/adrive/v2/share_link/get_share_by_anonymous', headers=self.headers,json=json_data, verify=False)
|
||||
if response.status_code == 200:
|
||||
resp = response.json()
|
||||
file_infos = resp.get('file_infos',[])
|
||||
self.share_file_id = file_infos[0]['file_id']
|
||||
print(f'获取到文件ID:【{self.share_file_id}】')
|
||||
self.get_shareToken()
|
||||
|
||||
else:
|
||||
print(response.text)
|
||||
|
||||
#保存文件
|
||||
def get_shareToken(self):
|
||||
json_data ={"share_id":self.shareid}
|
||||
response = s.post('https://api.aliyundrive.com/v2/share_link/get_share_token', headers=self.headers,json=json_data, verify=False)
|
||||
if response.status_code == 200:
|
||||
resp = response.json()
|
||||
share_token=resp.get('share_token','')
|
||||
self.headers['x-share-token'] = share_token
|
||||
self.save_shareFile()
|
||||
else:
|
||||
print(response.text)
|
||||
#保存文件
|
||||
def save_shareFile(self):
|
||||
json_data ={"requests":[{
|
||||
"body":{
|
||||
"share_id":self.shareid,
|
||||
"to_drive_id":self.default_drive_id,
|
||||
"addition_data":{"umidtoken":""},
|
||||
"auto_rename":True,"file_id":self.share_file_id,
|
||||
"to_parent_file_id":"root"},
|
||||
"headers":{"Content-Type":"application/json"},
|
||||
"id":"0","method":"POST",
|
||||
"url":"/file/copy"}],
|
||||
"resource":"file"
|
||||
}
|
||||
response = s.post('https://api.aliyundrive.com/adrive/v2/batch', headers=self.headers,json=json_data, verify=False)
|
||||
if response.status_code == 200:
|
||||
res = response.json()
|
||||
status = res["responses"][0]["status"]
|
||||
file_id = res["responses"][0]["body"]["file_id"]
|
||||
if status == 201:
|
||||
Log('文件保存成功')
|
||||
self.file_delete(file_id, self.default_drive_id)
|
||||
else:
|
||||
print('文件保存失败')
|
||||
else:
|
||||
print(response.text)
|
||||
|
||||
#接好运瓶并转存1个文件任务#######################
|
||||
|
||||
#领取版本升级奖励
|
||||
def version_reward(self):
|
||||
json_data = {"code":"newVersion490Reward","rule":"all"}
|
||||
response = s.post('https://member.aliyundrive.com/v1/users/space_goods_reward?_rx-s=mobile', headers=self.headers,
|
||||
json=json_data, verify=False)
|
||||
if response.status_code == 200:
|
||||
Log('领取版本升级奖励成功!')
|
||||
else:
|
||||
print(response.text)
|
||||
#领取奖励
|
||||
def reward_sign(self, type,sign_in_count=None):
|
||||
if sign_in_count == None:sign_in_count = self.sign_in_count
|
||||
json_data = {"signInDay": str(sign_in_count)}
|
||||
if type == 'sign_in_reward':
|
||||
url = f'https://member.aliyundrive.com/v1/activity/{type}?_rx-s=mobile'
|
||||
else:
|
||||
url = f'https://member.aliyundrive.com/v2/activity/{type}?_rx-s=mobile'
|
||||
response = s.post(url, headers=self.headers, json=json_data, verify=False)
|
||||
try:
|
||||
resp = response.json()
|
||||
if 'result' in resp and resp.get("result",None) != None:
|
||||
Log(f">{resp['result']['notice']}")
|
||||
elif 'success' in resp and resp.get("success",None) != None:
|
||||
Log(f">已领奖")
|
||||
else:
|
||||
Log(f">{resp['message']}")
|
||||
except:
|
||||
print(response.text)
|
||||
|
||||
# 订阅阿里官方账号
|
||||
def follow_user(self):
|
||||
data = {"user_id": 'ec11691148db442aa7aa374ca707543c'}
|
||||
response = s.post('https://api.aliyundrive.com/adrive/v1/member/follow_user', headers=self.headers, json=data,
|
||||
verify=False)
|
||||
if response.status_code == 200:
|
||||
Log('订阅成功!')
|
||||
else:
|
||||
print(response.text)
|
||||
|
||||
# 获取最近视频列表
|
||||
def get_videoList(self):
|
||||
self.fileName = '签到任务文件_视频.mp4'
|
||||
res = self.get_signTaskFileId()
|
||||
if res:
|
||||
# data = {}
|
||||
# response = s.post('https://api.aliyundrive.com/adrive/v2/video/list', headers=self.headers, json=data,
|
||||
# verify=False)
|
||||
# if response.status_code == 200:
|
||||
# data = response.json()
|
||||
# Video_list = data.get("items",False)
|
||||
# if Video_list:
|
||||
# Video_list_len = len(Video_list)
|
||||
# for i in range(Video_list_len):
|
||||
# Video_info = Video_list[random.randint(0,Video_list_len-1)]
|
||||
# # print(f'当前Video_info:\n{Video_info}')
|
||||
# if Video_info.get("type", "") == 'file':
|
||||
# self.file_id = Video_info['file_id']
|
||||
# self.drive_id = Video_info['drive_id']
|
||||
# self.videoUpdate()
|
||||
# duration = Video_info['duration']
|
||||
# play_cursor = str(float(Video_info['play_cursor']) + 31)
|
||||
# print(f'待上传时间:{play_cursor}')
|
||||
# self.videoUpdate(duration,play_cursor)
|
||||
# break
|
||||
self.videoUpdate()
|
||||
radomNum = round(random.uniform(200.000, 255.000), 3)
|
||||
self.videoUpdate(radomNum, radomNum)
|
||||
elif res == '未找到签到任务文件':
|
||||
print('放映室没有视频文件,尝试转存任务视频,重新获取视频信息')
|
||||
self.shareid = 't2j7bMBYAS5'
|
||||
self.get_shareFileId()
|
||||
# self.upload_files_to_drive(1)
|
||||
self.videoUpdate()
|
||||
radomNum = round(random.uniform(200.000, 255.000), 3)
|
||||
self.videoUpdate(radomNum,radomNum)
|
||||
|
||||
|
||||
else:
|
||||
print(res)
|
||||
|
||||
# 获取最近视频列表
|
||||
def videoUpdate(self,duration="0",play_cursor="0"):
|
||||
data = {
|
||||
"drive_id": self.default_drive_id,
|
||||
"duration": duration,
|
||||
"file_extension": 'mp4',
|
||||
"file_id": self.file_id,
|
||||
"play_cursor": play_cursor
|
||||
}
|
||||
response = s.post('https://api.aliyundrive.com/adrive/v2/video/update', headers=self.headers, json=data,
|
||||
verify=False)
|
||||
if response.status_code == 200:
|
||||
print('>上传观看时间成功!')
|
||||
else:
|
||||
print(response.text)
|
||||
|
||||
#弃用补签卡任务
|
||||
def join_team(self):
|
||||
check_team_data = {}
|
||||
check_team_res = s.post('https://member.aliyundrive.com/v1/activity/sign_in_team?_rx-s=mobile',
|
||||
headers=self.headers, json=check_team_data, verify=False)
|
||||
try:
|
||||
resp = check_team_res.json()
|
||||
if resp['result'] != 'null':
|
||||
act_id = resp['result']['id']
|
||||
join_team_data = {"id": act_id, "team": "blue"}
|
||||
join_team_res = requests.post('https://member.aliyundrive.com/v1/activity/sign_in_team_pk?_rx-s=mobile',
|
||||
headers=self.headers, json=join_team_data, verify=False)
|
||||
try:
|
||||
join_team_res = join_team_res.json()
|
||||
if join_team_res['success']:
|
||||
Log('>加入蓝色战队成功!')
|
||||
except:
|
||||
print(join_team_res.text)
|
||||
except:
|
||||
print(check_team_res.text)
|
||||
|
||||
#补签卡随机翻任务牌3次
|
||||
def get_cardTask(self):
|
||||
for i in range(3):
|
||||
json_data = {"position":random.randint(1,9)}
|
||||
response = s.post('https://member.aliyundrive.com/v2/activity/complement_task?_rx-s=mobile', headers=self.headers,
|
||||
json=json_data, verify=False)
|
||||
if response.status_code == 200:
|
||||
Log('翻卡成功')
|
||||
else:
|
||||
print(response.text)
|
||||
|
||||
# 获取period
|
||||
def get_period(self):
|
||||
print(f'>>>>>开始获取补签卡任务')
|
||||
json_data = {}
|
||||
response = s.post('https://member.aliyundrive.com/v2/activity/complement_task_detail?_rx-s=mobile',headers=self.headers,json=json_data, verify=False)
|
||||
if response.status_code == 200:
|
||||
resp = response.json()
|
||||
self.period = resp['result']['period']
|
||||
Tasks = resp['result']['tasks']
|
||||
# 在这里执行相应的操作
|
||||
if len(Tasks) < 3:
|
||||
self.get_cardTask()
|
||||
self.get_period()
|
||||
for task in Tasks:
|
||||
self.card_taskName = task['taskName']
|
||||
self.card_taskId = task['taskId']
|
||||
Log(f'>>当前任务:【{self.card_taskName}】')
|
||||
if task["status"] == "finished" or task["status"] == "verification":
|
||||
self.reward_cardTask()
|
||||
# Log('>本周补签卡已领取')
|
||||
return
|
||||
if self.card_taskName == '当周使用好运瓶翻3次':
|
||||
self.bottle_fish()
|
||||
break
|
||||
elif self.card_taskName == '当周观看任意一个电影时间满3分钟':
|
||||
self.get_videoList()
|
||||
break
|
||||
elif self.card_taskName == '当周备份照片满20张':
|
||||
Log(f'>任务:【{self.card_taskName}】暂不支持')
|
||||
continue
|
||||
elif self.card_taskName == '当周使用快传发送文件给好友':
|
||||
Log(f'>任务:【{self.card_taskName}】暂不支持')
|
||||
continue
|
||||
else:
|
||||
Log(f'>任务:【{self.card_taskName}】暂不支持')
|
||||
continue
|
||||
self.reward_cardTask()
|
||||
else:
|
||||
print(response.text)
|
||||
|
||||
# 获取历史设备ID
|
||||
def get_listDevice(self):
|
||||
json_data = {}
|
||||
response = s.post('https://user.aliyundrive.com/v1/deviceRoom/listDevice',headers=self.headers, json=json_data, verify=False)
|
||||
if response.status_code == 200 or response.status_code == 400:
|
||||
resp = response.json()
|
||||
# 检查响应是否包含'items'
|
||||
if 'items' in resp:
|
||||
items = response.json()['items']
|
||||
|
||||
# 检查'items'列表是否不为空
|
||||
if items:
|
||||
last_item = items[-1] # 获取最后一个元素
|
||||
self.x_device_id = last_item['id']
|
||||
print("x_device_id :", self.x_device_id )
|
||||
return True
|
||||
|
||||
else:
|
||||
print("items列表为空")
|
||||
return False
|
||||
else:
|
||||
print("响应中没有'items'字段")
|
||||
return False
|
||||
else:
|
||||
print(response.text)
|
||||
#上传备份设置,
|
||||
def update_device_extras(self):
|
||||
# 生成随机的totalSize和useSize(示例范围为256GB到1TB)
|
||||
total_size = random.randint(256 * 1024 * 1024 * 1024, 1024 * 1024 * 1024 * 1024) # 256GB到1TB
|
||||
use_size = random.randint(total_size, total_size) # useSize小于或等于totalSize,范围也是256GB到1TB
|
||||
if self.get_listDevice():
|
||||
self.headers['x-device-id'] = self.x_device_id
|
||||
json_data = {
|
||||
"albumAccessAuthority": True,
|
||||
"albumBackupLeftFileTotal": 0,
|
||||
"albumBackupLeftFileTotalSize": 0,
|
||||
"albumFile": random.randint(1,20),
|
||||
"autoBackupStatus": True,
|
||||
"brand": "xiaomi",
|
||||
"systemVersion": "Android 11",
|
||||
"totalSize": total_size,
|
||||
"umid": "",
|
||||
"useSize": use_size,
|
||||
"utdid": ""
|
||||
}
|
||||
response = s.post('https://api.aliyundrive.com/users/v1/users/update_device_extras', headers=self.headers,json=json_data, verify=False)
|
||||
if response.status_code == 200 or response.status_code == 400:
|
||||
resp = response.json()
|
||||
if 'success' in resp:
|
||||
print(f">{resp}")
|
||||
else:
|
||||
print(f">{resp['message']}")
|
||||
else:
|
||||
print(response.text)
|
||||
#领取补签卡
|
||||
def reward_cardTask(self):
|
||||
json_data = {"period":self.period,'taskId':self.card_taskId}
|
||||
response = s.post('https://member.aliyundrive.com/v2/activity/complement_task_reward?_rx-s=mobile', headers=self.headers,json=json_data, verify=False)
|
||||
if response.status_code == 200 or response.status_code == 400:
|
||||
resp = response.json()
|
||||
if 'success' in resp:
|
||||
print(f">补签卡领取成功")
|
||||
else:
|
||||
print(f">{resp['message']}")
|
||||
else:
|
||||
print(response.text)
|
||||
|
||||
|
||||
#使用补签卡
|
||||
def use_signCard(self):
|
||||
use_signCard_data = {}
|
||||
use_signCard_res = s.post('https://member.aliyundrive.com/v1/activity/complement_sign_in?_rx-s=mobile',
|
||||
headers=self.headers, json=use_signCard_data, verify=False)
|
||||
try:
|
||||
resp = use_signCard_res.json()
|
||||
if resp['code'] != 'BadRequest':
|
||||
Log('>补签成功!')
|
||||
else:
|
||||
Log(f">补签失败!原因:{resp['message']}")
|
||||
except:
|
||||
print(use_signCard_res.text)
|
||||
|
||||
def main(self, indx):
|
||||
log_message = f"\n开始执行第【{indx + 1}】个账号--------------->>>>>"
|
||||
Log(log_message)
|
||||
current_day = datetime.datetime.now().day
|
||||
if self.getToken():
|
||||
self.get_sign_in_list()
|
||||
|
||||
#新增领取版本奖励
|
||||
# self.version_reward()
|
||||
if self.ali_reward:
|
||||
Log('>>>>开始领取签到奖励')
|
||||
self.reward_sign('sign_in_reward')
|
||||
time.sleep(2)
|
||||
self.reward_sign('sign_in_task_reward')
|
||||
else:
|
||||
if not is_last_day_of_month():
|
||||
Log(f'>今天是【{current_day}】日,您设置了不自动领取奖品,不自动领取')
|
||||
else:
|
||||
Log('>今日为本月最后一天,默认领取所有奖品')
|
||||
for day in range(1, current_day + 1):
|
||||
Log(f'开始领取【第{day}天】奖品')
|
||||
self.reward_sign('sign_in_reward', day)
|
||||
self.reward_sign('sign_in_task_reward', day)
|
||||
time.sleep(1)
|
||||
self.get_period()
|
||||
self.use_signCard()
|
||||
else:
|
||||
return False
|
||||
#删除缓存
|
||||
def del_cash(file_path):
|
||||
try:
|
||||
# 删除文件
|
||||
os.remove(file_path)
|
||||
print(">缓存文件删除成功")
|
||||
return True
|
||||
except FileNotFoundError:
|
||||
print(">缓存文件不存在")
|
||||
return "缓存文件不存在"
|
||||
except Exception as e:
|
||||
print(f">缓存文件删除失败:{e}")
|
||||
return f"缓存文件删除失败:{e}"
|
||||
|
||||
# 对比缓存与环境变量 token 长度
|
||||
def len_comp(cached_tokens, env_token):
|
||||
global refresh_tokens, LEN
|
||||
if cached_tokens != '':
|
||||
cached_tokens = '#'.join(cached_tokens.values())
|
||||
cached_token_list = cached_tokens.split("#")
|
||||
cached_token_len = len(cached_token_list)
|
||||
else:
|
||||
cached_token_len = 0
|
||||
|
||||
env_token_list = env_token.split("&")
|
||||
env_token_len = len(env_token_list)
|
||||
|
||||
if env_token_len != cached_token_len:
|
||||
print("***缓存 freshToken 长度与环境变量长度不一致,使用【环境变量】")
|
||||
del_cash(REFRESHTOEKN_PATH)
|
||||
refresh_tokens = env_token_list
|
||||
LEN = env_token_len
|
||||
else:
|
||||
print("***缓存 freshToken 长度与环境变量长度一致,使用【缓存】")
|
||||
refresh_tokens = cached_token_list
|
||||
LEN = cached_token_len
|
||||
|
||||
def compare_versions(local_version, server_version):
|
||||
local_parts = local_version.split('.') # 将本地版本号拆分成数字部分
|
||||
server_parts = server_version.split('.') # 将服务器版本号拆分成数字部分
|
||||
|
||||
for l, s in zip(local_parts, server_parts):
|
||||
if int(l) < int(s):
|
||||
return True # 当前版本低于服务器版本
|
||||
elif int(l) > int(s):
|
||||
return False # 当前版本高于服务器版本
|
||||
|
||||
# 如果上述循环没有返回结果,则表示当前版本与服务器版本的数字部分完全相同
|
||||
if len(local_parts) < len(server_parts):
|
||||
return True # 当前版本位数较短,即版本号形如 x.y 比 x.y.z 低
|
||||
else:
|
||||
return False # 当前版本与服务器版本相同或更高
|
||||
|
||||
def check_update(local_version, server_version_url, server_script_url, script_filename):
|
||||
"""
|
||||
检查版本并更新
|
||||
|
||||
Args:
|
||||
local_version (str): 本地版本号
|
||||
server_version_url (str): 服务器版本文件地址
|
||||
server_script_url (str): 服务器脚本地址
|
||||
script_filename (str): 要保存的脚本文件名
|
||||
|
||||
Returns:
|
||||
bool: 是否进行了更新操作
|
||||
"""
|
||||
# 获取服务器版本号
|
||||
response = requests.get(server_version_url,verify=False)
|
||||
if response.status_code == 200:
|
||||
server_version = response.text.strip() # 去除首尾空格
|
||||
print(f'当前版本:【{local_version}】')
|
||||
print(f'服务器版本:【{server_version}】')
|
||||
|
||||
if compare_versions(local_version, server_version):
|
||||
# 需要更新,下载服务器脚本
|
||||
AUTO_UPDATE =os.getenv("ALYP_UPDATE", "True").lower() != "false"
|
||||
# print(AUTO_UPDATE)
|
||||
if AUTO_UPDATE:
|
||||
print(">>>>>>>发现新版本的脚本,默认自动更新,准备更新...")
|
||||
print(">>>>>>>禁用更新请定义变量export ALYP_UPDATE = 'False'")
|
||||
response = requests.get(server_script_url,verify=False,timeout=10)
|
||||
if response.status_code == 200:
|
||||
with open(script_filename, 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'{script_filename} 下载完成!')
|
||||
return True
|
||||
else:
|
||||
print(f'下载失败:{response.status_code}')
|
||||
else:
|
||||
print(">>>>>>>发现新版本的脚本,您禁用了自动更新,如需启用请删除变量ALYP_UPDATE")
|
||||
else:
|
||||
print(f'当前版本高于或等于服务器版本')
|
||||
else:
|
||||
print(f'获取服务器版本失败:{response.status_code}')
|
||||
|
||||
return False
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('''
|
||||
✨✨✨ 阿里云盘任务脚本✨✨✨
|
||||
✨脚本更新地址:https://pan.ziyuand.cn/%E8%BD%AF%E4%BB%B6%E8%B5%84%E6%BA%90%E7%B1%BB/%E8%84%9A%E6%9C%AC/%E9%98%BF%E9%87%8C%E4%BA%91%E7%9B%98
|
||||
✨获取refresh_token:
|
||||
https://alist.nn.ci/zh/guide/drivers/aliyundrive.html
|
||||
http://qr.ziyuand.cn/
|
||||
✨自动签到
|
||||
✨自动补签
|
||||
✨自动完成签到任务(部分)
|
||||
✨自动完成补签卡任务(部分)
|
||||
✨自动领取任务奖品(如无需自动领取请定义变量:export ali_reward="False",默认每月最后一天自动领取所有任务奖品)
|
||||
✨支持青龙(变量:export ALYP="xxxx")
|
||||
✨支持多账号(使用&分割refresh_token)
|
||||
✨脚本自动更新(禁用更新,变量:ALYP_UPDATE = "False")
|
||||
✨强制使用变量不使用缓存Token(变量:USE_ENV= "True")
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
# 检查更新
|
||||
local_version = '2023.11.05' # 本地版本
|
||||
server_base_url="http://pan.ziyuand.cn/d/软件资源类/脚本/阿里云盘/"
|
||||
server_script_url = f"{server_base_url}ALYP.py"
|
||||
server_version_url = f'{server_base_url}version.txt' # 服务器版本文件地址
|
||||
check_update(local_version, server_version_url, server_script_url, 'ALYP.py')
|
||||
|
||||
refresh_tokens = ''
|
||||
LEN = 0
|
||||
ENV = os.environ.get("ALYP")
|
||||
#强制使用环境变量,首次或增加账号后建议开启,跑一次删除变量,青龙变量 export USE_ENV = True
|
||||
USE_ENV = os.environ.get("USE_ENV") if environ.get("USE_ENV") else False
|
||||
if USE_ENV:
|
||||
print('当前强制使用变量')
|
||||
del_cash(REFRESHTOEKN_PATH)
|
||||
refresh_token = ENV if ENV else refresh_tokens
|
||||
Cach_Tokens = loadRefreshTokens()
|
||||
if refresh_token:
|
||||
len_comp(Cach_Tokens, refresh_token)
|
||||
else:
|
||||
print("******未填写 ALYP 变量。青龙可在环境变量设置 ALYP 或者在本脚本文件上方将获取到的 refresh_token 填入refresh_token后面的''中")
|
||||
exit(0)
|
||||
|
||||
#自动领取开关
|
||||
ali_reward = environ.get("ali_reward") if environ.get("ali_reward") else True
|
||||
if ali_reward:
|
||||
print('******默认自动领取奖品,如需关闭自动领取请定义变量:export ali_reward="False"\n******默认自动补签')
|
||||
else:
|
||||
print('******设置了不自动领取奖品')
|
||||
print(f'******当前使用token:\n{refresh_tokens}')
|
||||
if LEN > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{LEN}个账号<<<<<<<<<<")
|
||||
for indx, ck in enumerate(refresh_tokens):
|
||||
s = requests.session()
|
||||
s.verify = False
|
||||
# print(ck)
|
||||
Sign = AliDrive_CheckIn(ck, ali_reward).main(indx)
|
||||
if not Sign: continue
|
||||
|
||||
|
||||
send('阿里云盘签到通知', send_msg)
|
||||
286
BWCJ.py
Executable file
286
BWCJ.py
Executable file
@ -0,0 +1,286 @@
|
||||
# !/usr/bin/python3
|
||||
# -- coding: utf-8 --
|
||||
# -------------------------------
|
||||
# cron "30 1 * * *" script-path=xxx.py,tag=匹配cron用
|
||||
# const $ = new Env('霸王茶姬小程序')
|
||||
|
||||
import os
|
||||
import requests
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
# import CHERWIN_TOOLS
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
if os.path.isfile('notify.py'):
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
else:
|
||||
print("加载通知服务失败!")
|
||||
send_msg = ''
|
||||
one_msg=''
|
||||
def Log(cont=''):
|
||||
global send_msg,one_msg
|
||||
print(cont)
|
||||
if cont:
|
||||
one_msg += f'{cont}\n'
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
class RUN:
|
||||
def __init__(self,info,index):
|
||||
global one_msg
|
||||
one_msg = ''
|
||||
split_info = info.split('@')
|
||||
self.token = split_info[0]
|
||||
len_split_info = len(split_info)
|
||||
last_info = split_info[len_split_info - 1]
|
||||
self.send_UID = None
|
||||
if len_split_info > 0 and "UID_" in last_info:
|
||||
self.send_UID = last_info
|
||||
self.index = index + 1
|
||||
Log(f"\n---------开始执行第{self.index}个账号>>>>>")
|
||||
self.s = requests.session()
|
||||
self.s.verify = False
|
||||
|
||||
self.headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x6309080f) XWEB/8555',
|
||||
'work-wechat-userid': '',
|
||||
'multi-store-id': '',
|
||||
'gdt-vid': '',
|
||||
'qz-gtd': '',
|
||||
'scene': '1006',
|
||||
'Qm-From': 'wechat',
|
||||
'store-id': '49006',
|
||||
'Qm-User-Token': self.token,
|
||||
'channelCode': '',
|
||||
'Qm-From-Type': 'catering',
|
||||
'promotion-code': '',
|
||||
'work-staff-name': '',
|
||||
'work-staff-id': '',
|
||||
'Accept': 'v=1.0',
|
||||
'Accept-Encoding': 'gzip,compress,br,deflate',
|
||||
'Referer': 'https://servicewechat.com/wxafec6f8422cb357b/87/page-frame.html'
|
||||
}
|
||||
self.s.headers.update(self.headers)
|
||||
self.appid = 'wxafec6f8422cb357b'
|
||||
self.activity_id='947079313798000641'
|
||||
|
||||
def personal_info(self):
|
||||
personal_info_valid = False
|
||||
|
||||
try:
|
||||
# 请求的参数
|
||||
params = {'appid': self.appid}
|
||||
|
||||
# 发送GET请求
|
||||
response = self.s.get('https://webapi.qmai.cn/web/catering/crm/personal-info', json=params)
|
||||
result = response.json()
|
||||
|
||||
# 检查请求是否成功
|
||||
if result.get('code','-1') == '0':
|
||||
personal_info_valid = True
|
||||
# 提取个人信息
|
||||
mobile_phone = result['data']['mobilePhone'] if 'data' in result and 'mobilePhone' in result[
|
||||
'data'] else None
|
||||
self.mobile_phone = mobile_phone[:3] + "*" * 4 + mobile_phone[7:]
|
||||
self.name = result['data']['name'] if 'data' in result and 'name' in result['data'] else None
|
||||
|
||||
Log(f"账号[{self.index}]登陆成功!\n用户名:【{self.name}】 \n手机号:【{self.mobile_phone}】")
|
||||
else:
|
||||
# 如果请求不成功,则打印错误信息
|
||||
message = result.get('message', '')
|
||||
Log(f'登录失败: {message}')
|
||||
|
||||
except Exception as e:
|
||||
# 捕获任何异常并打印
|
||||
print(e)
|
||||
|
||||
finally:
|
||||
# 最终返回请求是否成功的标志
|
||||
return personal_info_valid
|
||||
|
||||
def user_sign_statistics(self):
|
||||
try:
|
||||
|
||||
json_data = {
|
||||
'activityId': self.activity_id,
|
||||
'appid': self.appid
|
||||
}
|
||||
|
||||
# Send the POST request
|
||||
response = self.s.post('https://webapi.qmai.cn/web/cmk-center/sign/userSignStatistics', json=json_data)
|
||||
result = response.json()
|
||||
status_code = response.status_code
|
||||
|
||||
# Check if the request was successful
|
||||
if result.get('code', status_code) == 0:
|
||||
data = result.get('data', {})
|
||||
sign_days = data.get('signDays', '')
|
||||
sign_status = data.get('signStatus', 0) == 1
|
||||
Log(f'新版签到今天{"已" if sign_status else "未"}签到, 已连续签到{sign_days}天')
|
||||
if not sign_status:
|
||||
self.take_part_in_sign()
|
||||
return sign_status, sign_days
|
||||
else:
|
||||
message = result.get('message', '')
|
||||
Log(f'查询新版签到失败: {message}')
|
||||
return False, 0
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False, 0
|
||||
|
||||
def take_part_in_sign(self):
|
||||
try:
|
||||
json_data = {
|
||||
'activityId': self.activity_id,
|
||||
'appid': self.appid
|
||||
}
|
||||
response = self.s.post('https://webapi.qmai.cn/web/cmk-center/sign/takePartInSign', json=json_data)
|
||||
result = response.json()
|
||||
status_code = response.status_code
|
||||
|
||||
if result.get('code', status_code) == 0:
|
||||
data = result.get('data',{})
|
||||
rewardDetailList = data.get('rewardDetailList',[{}])
|
||||
if rewardDetailList:
|
||||
rewardName = rewardDetailList[0].get('rewardName','')
|
||||
sendNum = rewardDetailList[0].get('sendNum','')
|
||||
Log(f'新版签到成功,获得【{sendNum}】{rewardName}')
|
||||
return True
|
||||
else:
|
||||
Log(f'签到失败:【{result.get("message","")}】')
|
||||
return True
|
||||
else:
|
||||
message = result.get('message', '')
|
||||
Log(f'新版签到失败: {message}')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
def points_info(self):
|
||||
try:
|
||||
json_data = {
|
||||
'appid': self.appid
|
||||
}
|
||||
|
||||
response = self.s.post('https://webapi.qmai.cn/web/catering/crm/points-info', json=json_data)
|
||||
result = response.json()
|
||||
status_code = response.status_code
|
||||
|
||||
if result.get('code', status_code) == '0':
|
||||
data = result.get('data', {})
|
||||
soon_expired_points = data.get('soonExpiredPoints', 0)
|
||||
total_points = data.get('totalPoints', 0)
|
||||
expired_time = data.get('expiredTime', '')
|
||||
|
||||
if soon_expired_points:
|
||||
Log(f'有【{soon_expired_points}】积分将于( {expired_time})过期')
|
||||
|
||||
Log(f'当前积分: 【{total_points}】')
|
||||
return total_points, soon_expired_points, expired_time
|
||||
else:
|
||||
message = result.get('message', '')
|
||||
Log(f'查询积分失败: {message}')
|
||||
return None
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
def main(self):
|
||||
if not self.personal_info() :
|
||||
Log("用户信息无效,请更新CK")
|
||||
return False
|
||||
self.user_sign_statistics()
|
||||
self.points_info()
|
||||
self.sendMsg()
|
||||
return True
|
||||
|
||||
def sendMsg(self, help=False):
|
||||
if self.send_UID:
|
||||
push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME, help)
|
||||
print(push_res)
|
||||
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
|
||||
def import_Tools():
|
||||
global CHERWIN_TOOLS,ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode
|
||||
import CHERWIN_TOOLS
|
||||
ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME,local_version)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP_NAME = '霸王茶姬小程序'
|
||||
ENV_NAME = 'BWCJ'
|
||||
CK_NAME = 'qm-user-token'
|
||||
print(f'''
|
||||
✨✨✨ {APP_NAME}签到✨✨✨
|
||||
✨ 功能:
|
||||
积分签到
|
||||
✨ 抓包步骤:
|
||||
打开{APP_NAME}
|
||||
授权登陆
|
||||
打开抓包工具
|
||||
找请求头带{CK_NAME}的URl
|
||||
复制里面的{CK_NAME}参数值
|
||||
✨ ✨✨wxpusher一对一推送功能,
|
||||
✨需要定义变量export WXPUSHER=wxpusher的app_token,不设置则不启用wxpusher一对一推送
|
||||
✨需要在{ENV_NAME}变量最后添加@wxpusher的UID
|
||||
参数示例:Fks8FqmiTksnmZSj2fDvxxxxxxxxx@UID_xxxxx
|
||||
✨ 设置青龙变量:
|
||||
export {ENV_NAME}='{CK_NAME}参数值'多账号#或&分割
|
||||
export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
✨ ✨ 注意:抓完CK没事儿别打开小程序,重新打开小程序请重新抓包
|
||||
✨ 推荐cron:5 8 * * *
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
local_script_name = os.path.basename(__file__)
|
||||
local_version = '2024.04.06'
|
||||
if os.path.isfile('CHERWIN_TOOLS.py'):
|
||||
import_Tools()
|
||||
else:
|
||||
if down_file('CHERWIN_TOOLS.py', 'https://py.cherwin.cn/CHERWIN_TOOLS.py'):
|
||||
print('脚本依赖下载完成请重新运行脚本')
|
||||
import_Tools()
|
||||
else:
|
||||
print('脚本依赖下载失败,请到https://py.cherwin.cn/CHERWIN_TOOLS.py下载最新版本依赖')
|
||||
exit()
|
||||
print(TIPS)
|
||||
token = ''
|
||||
token = ENV if ENV else token
|
||||
if not token:
|
||||
print(f"未填写{ENV_NAME}变量\n青龙可在环境变量设置 {ENV_NAME} 或者在本脚本文件上方将{CK_NAME}填入token =''")
|
||||
exit()
|
||||
tokens = CHERWIN_TOOLS.ENV_SPLIT(token)
|
||||
# print(tokens)
|
||||
if len(tokens) > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<")
|
||||
for index, infos in enumerate(tokens):
|
||||
run_result = RUN(infos, index).main()
|
||||
if not run_result: continue
|
||||
if send: send(f'{APP_NAME}挂机通知', send_msg + TIPS_HTML)
|
||||
495
CHERWIN_TOOLS.py
Executable file
495
CHERWIN_TOOLS.py
Executable file
@ -0,0 +1,495 @@
|
||||
import json
|
||||
import os
|
||||
import importlib.util
|
||||
import subprocess
|
||||
import sys
|
||||
import requests
|
||||
from http import HTTPStatus
|
||||
|
||||
NOW_TOOLS_VERSION = '2024.04.06'
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
# 尝试导入包
|
||||
def import_or_install(package_name, import_name=None):
|
||||
# 如果传入了 import_name,则使用它来检查模块,否则默认与包名相同
|
||||
import_name = import_name or package_name
|
||||
|
||||
try:
|
||||
# 检查模块是否已安装
|
||||
package_spec = importlib.util.find_spec(import_name)
|
||||
|
||||
if package_spec is None:
|
||||
print(f"{package_name} 模块未安装. 开始安装...")
|
||||
subprocess.check_call([sys.executable, '-m', 'pip', 'install', package_name])
|
||||
print(f"{package_name} 模块安装完成。")
|
||||
else:
|
||||
print(f"{package_name} 模块已安装。")
|
||||
|
||||
# 尝试导入模块检查是否安装成功
|
||||
__import__(import_name)
|
||||
module = importlib.import_module(import_name)
|
||||
print(f"{import_name} 模块导入成功.")
|
||||
return module
|
||||
except ImportError as e:
|
||||
print(f"无法导入 {import_name} 模块. 错误信息: {e}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"安装 {package_name} 模块时出错. 错误信息: {e}")
|
||||
except Exception as e:
|
||||
print(f"处理 {package_name} 模块时发生错误. 错误信息: {e}")
|
||||
|
||||
def SAVE_INVITE_CODE(file_name, new_data):
|
||||
# 读取现有JSON文件(如果存在)
|
||||
try:
|
||||
with open(file_name, 'r', encoding='utf-8') as file:
|
||||
data = json.load(file)
|
||||
except FileNotFoundError:
|
||||
# 如果文件不存在,创建所需目录并一个新的空JSON文件
|
||||
directory = os.path.dirname(file_name)
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
data = {}
|
||||
|
||||
# 检查是否已存在相同的键,如果存在,合并数据
|
||||
for key, value in new_data.items():
|
||||
if key in data:
|
||||
# 如果键已存在,将新数据合并到现有数据中
|
||||
data[key].update(value)
|
||||
else:
|
||||
# 如果键不存在,直接插入新数据
|
||||
data[key] = value
|
||||
|
||||
# 将更新后的数据写入JSON文件
|
||||
with open(file_name, 'w', encoding='utf-8') as file:
|
||||
json.dump(data, file, indent=4)
|
||||
|
||||
# 将参数转换为字典
|
||||
def create_dict_from_string(self, data_string):
|
||||
params = {}
|
||||
key_value_pairs = data_string.split(',')
|
||||
for pair in key_value_pairs:
|
||||
key, value = pair.split('=')
|
||||
params[key] = value
|
||||
return params
|
||||
|
||||
def compare_versions(local_version, server_version):
|
||||
local_parts = local_version.split('.') # 将本地版本号拆分成数字部分
|
||||
server_parts = server_version.split('.') # 将服务器版本号拆分成数字部分
|
||||
|
||||
for l, s in zip(local_parts, server_parts):
|
||||
if int(l) < int(s):
|
||||
return True # 当前版本低于服务器版本
|
||||
elif int(l) > int(s):
|
||||
return False # 当前版本高于服务器版本
|
||||
|
||||
# 如果上述循环没有返回结果,则表示当前版本与服务器版本的数字部分完全相同
|
||||
if len(local_parts) < len(server_parts):
|
||||
return True # 当前版本位数较短,即版本号形如 x.y 比 x.y.z 低
|
||||
else:
|
||||
return False # 当前版本与服务器版本相同或更高
|
||||
|
||||
def CHECK_UPDATE(local_version, server_version_url, server_script_url, script_filename):
|
||||
"""
|
||||
检查版本并更新
|
||||
|
||||
Args:
|
||||
local_version (str): 本地版本号
|
||||
server_version_url (str): 服务器版本文件地址
|
||||
server_script_url (str): 服务器脚本地址
|
||||
script_filename (str): 要保存的脚本文件名
|
||||
|
||||
Returns:
|
||||
bool: 是否进行了更新操作
|
||||
"""
|
||||
try:
|
||||
# 获取服务器版本号
|
||||
response = requests.get(server_version_url, verify=False)
|
||||
response.raise_for_status() # Raises an HTTPError for bad responses
|
||||
# print(response.text)
|
||||
server_version = response.text.strip() # 去除首尾空格
|
||||
print(f'当前版本:【{local_version}】')
|
||||
print(f'服务器版本:【{server_version}】')
|
||||
|
||||
if compare_versions(local_version, server_version):
|
||||
# 需要更新,下载服务器脚本
|
||||
AUTO_UPDATE = os.getenv("SCRIPT_UPDATE", "True").lower() != "false"
|
||||
# print(AUTO_UPDATE)
|
||||
if AUTO_UPDATE:
|
||||
print(">>>>>>>发现新版本的脚本,默认自动更新,准备更新...")
|
||||
print(">>>>>>>禁用更新请定义变量export SCRIPT_UPDATE = 'False'")
|
||||
response_script = requests.get(server_script_url, verify=False, timeout=10)
|
||||
response_script.raise_for_status()
|
||||
|
||||
with open(script_filename, 'wb') as f:
|
||||
f.write(response_script.content)
|
||||
print(f'{script_filename} 下载完成!')
|
||||
print(f'尝试运行新脚本')
|
||||
import subprocess, sys
|
||||
# 使用 sys.executable 获取 Python 可执行文件的完整路径
|
||||
python_executable = sys.executable
|
||||
subprocess.Popen([python_executable, script_filename])
|
||||
|
||||
else:
|
||||
print(">>>>>>>发现新版本的脚本,您禁用了自动更新,如需启用请删除变量SCRIPT_UPDATE")
|
||||
else:
|
||||
print(f'当前版本高于或等于服务器版本')
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f'发生网络错误:{e}')
|
||||
|
||||
except Exception as e:
|
||||
print(f'发生未知错误:{e}')
|
||||
|
||||
return False # 返回 False 表示没有进行更新操作
|
||||
|
||||
def CHECK_UPDATE_NEW(local_version, server_version, server_script_url, script_filename,server_version_url=None):
|
||||
"""
|
||||
检查版本并更新
|
||||
|
||||
Args:
|
||||
local_version (str): 本地版本号
|
||||
server_version_url (str): 服务器版本文件地址
|
||||
server_script_url (str): 服务器脚本地址
|
||||
script_filename (str): 要保存的脚本文件名
|
||||
|
||||
Returns:
|
||||
bool: 是否进行了更新操作
|
||||
"""
|
||||
print(f'当前检测:【{script_filename}】')
|
||||
try:
|
||||
if server_version_url:
|
||||
# 获取服务器版本号
|
||||
response = requests.get(server_version_url, verify=False)
|
||||
response.raise_for_status() # Raises an HTTPError for bad responses
|
||||
# print(response.text)
|
||||
server_version = response.text.strip() # 去除首尾空格
|
||||
if "code" in server_version:
|
||||
print('【获取远程版本号失败,设为本地同版本】')
|
||||
server_version = local_version
|
||||
if not server_version :server_version = NOW_TOOLS_VERSION
|
||||
print(f'本地版本:【{local_version}】')
|
||||
print(f'服务器版本:【{server_version}】')
|
||||
|
||||
if compare_versions(local_version, server_version):
|
||||
# 需要更新,下载服务器脚本
|
||||
AUTO_UPDATE = os.getenv("SCRIPT_UPDATE", "True").lower() != "false"
|
||||
# print(AUTO_UPDATE)
|
||||
if AUTO_UPDATE:
|
||||
print(">>>>>>>发现新版本的脚本,默认自动更新,准备更新...")
|
||||
print(">>>>>>>禁用更新请定义变量export SCRIPT_UPDATE = 'False'")
|
||||
if down_file(script_filename,server_script_url):
|
||||
print(f'请重新运行新脚本\n')
|
||||
return True
|
||||
else:
|
||||
print(">>>>>>>发现新版本的脚本,您禁用了自动更新,如需启用请删除变量SCRIPT_UPDATE\n")
|
||||
else:
|
||||
print(f'无需更新\n')
|
||||
return False
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f'发生网络错误:{e}')
|
||||
|
||||
except Exception as e:
|
||||
print(f'发生未知错误:{e}')
|
||||
|
||||
return False # 返回 False 表示没有进行更新操作
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
def get_AuthorInviteCode(url):
|
||||
global AuthorCode
|
||||
try:
|
||||
response = requests.get(url, verify=False, timeout=10)
|
||||
if response.status_code == 200:
|
||||
content = json.loads(response.text)
|
||||
AuthorCode = list(content.values())
|
||||
# print(f'获取到作者邀请码:{AuthorCode}')
|
||||
return AuthorCode
|
||||
else:
|
||||
# print("无法获取文件。状态代码:", response.status_code)
|
||||
return {}
|
||||
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
return {}
|
||||
|
||||
|
||||
def GET_TIPS(server_base_url):
|
||||
url = f'{server_base_url}tips.txt'
|
||||
try:
|
||||
response = requests.get(url, verify=False)
|
||||
# 检查响应的编码
|
||||
encoding = response.encoding
|
||||
# print(f"编码: {encoding}")
|
||||
# 设置正确的编码(根据实际情况可能需要调整)
|
||||
response.encoding = 'utf-8'
|
||||
# 读取内容
|
||||
content = response.text
|
||||
if 'code' in content:
|
||||
content = None
|
||||
except:
|
||||
content = None
|
||||
print('获取通知内容失败')
|
||||
if content:
|
||||
return (f'''
|
||||
***********通知内容************\n
|
||||
{content}
|
||||
***********通知内容************\n
|
||||
''')
|
||||
else:
|
||||
return (f'''
|
||||
***********通知内容************\n
|
||||
@Author Cherwin
|
||||
***********通知内容************\n
|
||||
''')
|
||||
|
||||
def CHECK_PARAMENTERS(index, input_string,required_parameters):
|
||||
# required_parameters = ['deviceid', 'jysessionid', 'shopid', 'memberid', 'access_token', 'sign']
|
||||
|
||||
# 记录缺少的参数
|
||||
missing_parameters = []
|
||||
|
||||
# 将输入字符串和参数列表中的所有字符都转换为小写
|
||||
input_string_lower = input_string.lower()
|
||||
required_parameters_lower = [param.lower() for param in required_parameters]
|
||||
|
||||
# 判断字符串中是否包含所有必需的参数
|
||||
for param in required_parameters_lower:
|
||||
if param not in input_string_lower:
|
||||
missing_parameters.append(param)
|
||||
|
||||
if missing_parameters:
|
||||
print(f"\n第【{index + 1}】个账号,缺少以下参数:【{missing_parameters}】")
|
||||
return False
|
||||
else:
|
||||
print(f"\n第【{index + 1}】个账号,URL包含所有必需的参数,开始执行脚本")
|
||||
return True
|
||||
|
||||
|
||||
def QIANWEN(tongyiSysPromt, content, api_key):
|
||||
print('开始调用通义千问')
|
||||
# 检查dashscope库是否已安装
|
||||
dashscope = import_or_install('dashscope')
|
||||
if dashscope:
|
||||
dashscope.api_key = api_key
|
||||
response = dashscope.Generation.call(
|
||||
model='qwen-max',
|
||||
messages=[
|
||||
{"role": "system",
|
||||
"content": tongyiSysPromt},
|
||||
{"role": "user", "content": content}],
|
||||
seed=1234,
|
||||
top_p=0.8,
|
||||
result_format='message',
|
||||
enable_search=False,
|
||||
max_tokens=1500,
|
||||
temperature=1.0,
|
||||
repetition_penalty=1.0,
|
||||
)
|
||||
if response.status_code == HTTPStatus.OK:
|
||||
# print(response)
|
||||
video_info = response.output['choices'][0]['message']['content']
|
||||
print('通义生成【成功】!')
|
||||
return video_info
|
||||
else:
|
||||
print(f"无法解析通义返回的信息:{response}")
|
||||
return None
|
||||
else:
|
||||
print('dashscope 模块无法导入,函数无法执行。')
|
||||
|
||||
# 取环境变量,并分割
|
||||
def ENV_SPLIT(input_str):
|
||||
parts = []
|
||||
if '&' in input_str:
|
||||
amp_parts = input_str.split('&')
|
||||
for part in amp_parts:
|
||||
if '#' in part:
|
||||
hash_parts = part.split('#')
|
||||
for hash_part in hash_parts:
|
||||
parts.append(hash_part)
|
||||
else:
|
||||
parts.append(part)
|
||||
# print(parts)
|
||||
return(parts)
|
||||
|
||||
elif '#' in input_str:
|
||||
hash_parts = input_str.split('#')
|
||||
# print(hash_parts)
|
||||
return(hash_parts)
|
||||
else:
|
||||
out_str = str(input_str)
|
||||
# print([out_str])
|
||||
return([out_str])
|
||||
|
||||
# 使用导入的模块进行验证码识别
|
||||
def CAPCODE(captcha_slider, captcha_bg):
|
||||
ddddocr = import_or_install('ddddocr')
|
||||
if ddddocr:
|
||||
slide = ddddocr.DdddOcr(det=False, ocr=False)
|
||||
with open(captcha_slider, 'rb') as f:
|
||||
target_bytes = f.read()
|
||||
with open(captcha_bg, 'rb') as f:
|
||||
background_bytes = f.read()
|
||||
res = slide.slide_match(target_bytes, background_bytes, simple_target=True)
|
||||
# print(res['target'][0])
|
||||
# print(type(res['target'][0]))
|
||||
return res['target'][0]
|
||||
else:
|
||||
print('ddddocr 模块无法导入,函数无法执行。')
|
||||
return False
|
||||
#
|
||||
# def OCR_API(target_b64str,bg_b64str):
|
||||
# import base64
|
||||
# host = 'http://192.168.10.160'
|
||||
# jsonstr = json.dumps({'target_img': target_b64str, 'bg_img': bg_b64str})
|
||||
# api_url = f"{host}/slide/match/b64/json"
|
||||
# resp = requests.post(api_url, data=base64.b64encode(jsonstr.encode()).decode())
|
||||
# print(f"{api_url=}, {resp.text=}")
|
||||
# return resp.json().get('target_y',0)
|
||||
#
|
||||
#
|
||||
# def BASE64_TO_IMG(base64_string, output_path):
|
||||
# import base64
|
||||
# import io
|
||||
# Image = import_or_install('Pillow', 'PIL.Image')
|
||||
#
|
||||
# if Image:
|
||||
# try:
|
||||
# # 解码base64字符串
|
||||
# image_data = base64.b64decode(base64_string)
|
||||
# # 将字节数据转换为字节流
|
||||
# image_buf = Image.open(io.BytesIO(image_data))
|
||||
# # 转换为RGB模式
|
||||
# image_buf = image_buf.convert('RGB')
|
||||
# # 保存图片到指定路径
|
||||
# image_buf.save(output_path, format='JPEG')
|
||||
# return True
|
||||
# except Exception as e:
|
||||
# print(f'发生错误:{e}')
|
||||
# return False
|
||||
# else:
|
||||
# print('需要的模块[PIL]无法导入,函数无法执行。')
|
||||
# return False
|
||||
|
||||
def send_wxpusher(UID, one_msg, APP_NAME, help=False):
|
||||
WXPUSHER = os.environ.get('WXPUSHER', False)
|
||||
if WXPUSHER:
|
||||
if help:
|
||||
push_res = wxpusher(WXPUSHER, APP_NAME + '互助', one_msg, UID, TIPS_HTML)
|
||||
else:
|
||||
push_res = wxpusher(WXPUSHER, APP_NAME, one_msg, UID, TIPS_HTML)
|
||||
print(push_res)
|
||||
|
||||
|
||||
def wxpusher(UID,msg,title,help=False):
|
||||
"""利用 wxpusher 的 web api 发送 json 数据包,实现微信信息的发送"""
|
||||
WXPUSHER = os.environ.get('WXPUSHER', False)
|
||||
if WXPUSHER:
|
||||
if help:title = title+'互助'
|
||||
print('\n------开始wxpusher推送------')
|
||||
print(f'标题:【{title}】\n内容:{msg}')
|
||||
webapi = 'http://wxpusher.zjiecode.com/api/send/message'
|
||||
msg = msg.replace("\n", "<br>")
|
||||
tips = TIPS_HTML.replace("\n", "<br>")
|
||||
data = {
|
||||
"appToken": WXPUSHER,
|
||||
"content": f'{title}<br>{msg}<br>{tips}',
|
||||
# "summary": msg[:99], # 该参数可选,默认为 msg 的前10个字符
|
||||
"summary":title,
|
||||
"contentType": 2,
|
||||
"uids": [UID],
|
||||
"url": "https://gj.cherwin.cn"
|
||||
}
|
||||
|
||||
try:
|
||||
result = requests.post(url=webapi, json=data)
|
||||
result.raise_for_status() # 对于非2xx状态码,抛出异常
|
||||
response_json = result.json()
|
||||
if response_json["success"]:
|
||||
return "------消息发送成功------\n"
|
||||
else:
|
||||
return f"消息发送失败。错误信息:{response_json['msg']}"
|
||||
except requests.exceptions.RequestException as e:
|
||||
return f"发送消息时发生错误:{str(e)}"
|
||||
except Exception as e:
|
||||
return f"发生意外错误:{str(e)}"
|
||||
|
||||
def RESTART_SCRIPT(RESTART_SCRIPT_NAME):
|
||||
python = sys.executable
|
||||
os.execl(python, RESTART_SCRIPT_NAME, *sys.argv[1:])
|
||||
|
||||
def CHECK():
|
||||
global CHERWIN_SCRIPT_CONFIG
|
||||
print('>>>>>>>开始获取版本信息...')
|
||||
baseurl = 'https://py.cherwin.cn/'
|
||||
TOOLS_NAME = 'CHERWIN_TOOLS.py'
|
||||
server_script_url = f'{baseurl}{TOOLS_NAME}'
|
||||
try:
|
||||
response = requests.get(f'{baseurl}CHERWIN_SCRIPT_CONFIG.json', verify=False)
|
||||
response.encoding = 'utf-8'
|
||||
# 读取内容
|
||||
CHERWIN_SCRIPT_CONFIG = response.json()
|
||||
if 'code' in CHERWIN_SCRIPT_CONFIG:
|
||||
CHERWIN_SCRIPT_CONFIG = None
|
||||
server_version = CHERWIN_SCRIPT_CONFIG.get('TOOLS_VERSION', NOW_TOOLS_VERSION)
|
||||
if CHECK_UPDATE_NEW(NOW_TOOLS_VERSION, server_version, server_script_url, TOOLS_NAME):
|
||||
print('更新脚本完成')
|
||||
# print(f'重新检测[{TOOLS_NAME}]版本')
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
except:
|
||||
print('获取CHERWIN_SCRIPT_CONFIG.json失败')
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def main(APP_NAME,local_script_name,ENV_NAME,local_version):
|
||||
global APP_INFO,TIPS,TIPS_HTML
|
||||
server_base_url = f"https://py.cherwin.cn/{APP_NAME}/"
|
||||
server_script_url = f"{server_base_url}{local_script_name}"
|
||||
if CHECK():
|
||||
APP_INFO = CHERWIN_SCRIPT_CONFIG.get("APP_CONFIG", {}).get(ENV_NAME, {})
|
||||
# print(APP_INFO)
|
||||
server_version = APP_INFO.get('NEW_VERSION', '')
|
||||
if CHECK_UPDATE_NEW(local_version, server_version, server_script_url, local_script_name):
|
||||
print('更新成功,请重新运行脚本!')
|
||||
|
||||
if not APP_INFO.get('ENABLE', False):
|
||||
print('当前脚本未开放')
|
||||
exit()
|
||||
TIPS = APP_INFO.get('NTC', '') if APP_INFO.get('NTC', '') else CHERWIN_SCRIPT_CONFIG.get('GLOBAL_NTC', '')
|
||||
|
||||
TIPS_HTML = APP_INFO.get('NTC', '') if APP_INFO.get('NTC', '') else CHERWIN_SCRIPT_CONFIG.get('GLOBAL_NTC_HTML','')
|
||||
ENV = os.environ.get(ENV_NAME)
|
||||
AuthorCode = get_AuthorInviteCode(f'https://yhsh.ziyuand.cn/{ENV_NAME}_INVITE_CODE.json')
|
||||
|
||||
return ENV,APP_INFO,TIPS,TIPS_HTML,AuthorCode
|
||||
else:
|
||||
exit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pass
|
||||
425
DBKD.py
Executable file
425
DBKD.py
Executable file
@ -0,0 +1,425 @@
|
||||
# !/usr/bin/python3
|
||||
# -- coding: utf-8 --
|
||||
# -------------------------------
|
||||
# ✨✨✨ @Author CHERWIN✨✨✨
|
||||
# -------------------------------
|
||||
# cron "0 6 * * *" script-path=xxx.py,tag=匹配cron用
|
||||
# const $ = new Env('中通快递小程序签到')
|
||||
|
||||
import os
|
||||
import requests
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
|
||||
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
if os.path.isfile('notify.py'):
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
else:
|
||||
print("加载通知服务失败!")
|
||||
send_msg = ''
|
||||
one_msg=''
|
||||
def Log(cont=''):
|
||||
global send_msg,one_msg
|
||||
print(cont)
|
||||
if cont:
|
||||
one_msg += f'{cont}\n'
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
class RUN:
|
||||
def __init__(self,info,index):
|
||||
global one_msg
|
||||
one_msg = ''
|
||||
split_info = info.split('@')
|
||||
token = split_info[0]
|
||||
len_split_info = len(split_info)
|
||||
last_info = split_info[len_split_info - 1]
|
||||
self.send_UID = None
|
||||
if len_split_info > 0 and "UID_" in last_info:
|
||||
print('检测到设置了UID')
|
||||
print(last_info)
|
||||
self.send_UID = last_info
|
||||
self.index = index + 1
|
||||
self.s = requests.session()
|
||||
self.s.verify = False
|
||||
|
||||
self.token = token
|
||||
self.headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x6309080f) XWEB/9079',
|
||||
'Referer': 'https://servicewechat.com/wxa1ebeeb0ed47f0b2/633/page-frame.html'
|
||||
}
|
||||
self.baseUrl = 'https://api.ztomember.com/api/'
|
||||
|
||||
|
||||
def do_request(self, method, url, params=None, data=None, headers=None):
|
||||
if not headers:
|
||||
headers = self.headers
|
||||
try:
|
||||
response = self.s.request(method, url, params=params, json=data, headers=headers)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
print(f"请求错误: {e}")
|
||||
return None
|
||||
|
||||
def login(self):
|
||||
try:
|
||||
data= {
|
||||
"code": self.token,
|
||||
"loginType": "AUTH_CODE_SESSION_KEY_WECHAT_MINI",
|
||||
"sysCode": "WECHAT_MINI"
|
||||
}
|
||||
response = self.do_request('POST', 'https://www.deppon.com/ndcc-gwapi/userService/eco/user/login',data=data)
|
||||
if response and response.get('status') == 'success':
|
||||
mobile = response['result']['mobile']
|
||||
self.mobile = mobile[:3] + "*" * 4 + mobile[7:]
|
||||
Log(f'\n手机号:【{self.mobile}】')
|
||||
return self.generate_tmp_token()
|
||||
else:
|
||||
Log(f"查询账户失败: {response.get('message')}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"查询账户异常: {e}")
|
||||
return False
|
||||
|
||||
def generate_tmp_token(self):
|
||||
try:
|
||||
response = self.do_request('GET', 'https://www.deppon.com/ndcc-gwapi/userService/eco/user/token/secure/generateTmpToken')
|
||||
if response and response.get('status') == 'success':
|
||||
print(f'临时Token获取成功!')
|
||||
return self.login_verify(response['result'])
|
||||
else:
|
||||
print(f"获取临时token失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"获取临时token异常: {e}")
|
||||
return False
|
||||
|
||||
def login_verify(self, code):
|
||||
try:
|
||||
data = {'code': code, 'flag': True}
|
||||
self.headers['Content-Type'] = 'application/json'
|
||||
response = self.do_request('POST', 'https://mas.deppon.com/crm-api/login/verify', data=data)
|
||||
if response and response.get('code') == 200:
|
||||
# print(response)
|
||||
Log(f"登录验证成功!")
|
||||
self.phone = response['data']['mobile']
|
||||
self.token = response['data']['token']
|
||||
self.headers['mobile'] = self.phone
|
||||
self.headers['token'] = self.token
|
||||
#
|
||||
# print(f"PHONE:【{self.phone}】")
|
||||
# print(f"TOKEN:【{self.token}】")
|
||||
return True
|
||||
else:
|
||||
Log(f"登录验证失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"登录验证异常: {e}")
|
||||
return False
|
||||
|
||||
def getSvipNewestInfo(self,end="执行前"):
|
||||
print('\n获取用户最新信息------>>>')
|
||||
try:
|
||||
# data ={"phone":self.phone}
|
||||
response = self.do_request('GET', 'https://www.deppon.com/ndcc-gwapi/memberService/eco/member/grade/secure/getSvipNewestInfo')
|
||||
if response and response.get('status') == "success":
|
||||
data = response.get('result', {})
|
||||
points = data.get('points', 0)
|
||||
Log(f'{end}积分:【{points}】')
|
||||
else:
|
||||
Log(f"获取用户最新信息失败: {response}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"获取用户最新信息异常: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def signIn_info(self):
|
||||
print('获取签到信息------>>>')
|
||||
try:
|
||||
data = {"phone": self.phone}
|
||||
response = self.do_request('POST', 'https://mas.deppon.com/crm-api/deppon/signIn/info',data = data)
|
||||
if response and response.get('code') == 200:
|
||||
data = response.get('data', {})
|
||||
is_sign_in = data.get('isSignIn')
|
||||
sign_in_day = data.get('signInDay')
|
||||
record_dtos = data.get('recordDTOS')
|
||||
if not is_sign_in and record_dtos and record_dtos[0]:
|
||||
self.remark = record_dtos[0].get('remark','')
|
||||
self.name = record_dtos[0].get('name','')
|
||||
self.taskRuleId = record_dtos[0].get('taskRuleId','')
|
||||
self.signIn()
|
||||
else:
|
||||
Log(f'[领券签到]今天已签到, 已签到{sign_in_day}天')
|
||||
return response['data']
|
||||
else:
|
||||
print(f"获取签到信息失败: {response}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"获取签到信息异常: {e}")
|
||||
return None
|
||||
|
||||
def signIn(self):
|
||||
print('执行签到------>>>')
|
||||
try:
|
||||
data = {"phone": self.phone,'taskRuleId':self.taskRuleId}
|
||||
response = self.do_request('POST', 'https://mas.deppon.com/crm-api/deppon/signIn',data=data)
|
||||
if response and response.get('code') == 200:
|
||||
data = response.get('data', [])
|
||||
remarks = []
|
||||
for item in data:
|
||||
if item.get('remark'):
|
||||
remarks.append(item['remark'])
|
||||
remarks_str = ', '.join(remarks) if remarks else ''
|
||||
Log('签到成功: ' + remarks_str)
|
||||
else:
|
||||
print(f"签到失败: {response}")
|
||||
except Exception as e:
|
||||
print(f"签到异常: {e}")
|
||||
return None
|
||||
|
||||
def points_signIn_info(self):
|
||||
print('获取积分签到信息------>>>')
|
||||
try:
|
||||
data = {"phone": self.phone}
|
||||
response = self.do_request('POST', 'https://mas.deppon.com/crm-api/deppon/points/task/signIn/info',data = data)
|
||||
if response and response.get('code') == 200:
|
||||
data = response.get('data', {})
|
||||
is_sign_in = data.get('isSignIn')
|
||||
sign_in_day = data.get('signInDay')
|
||||
sign_in_day_info = data.get('signInDayInfo')
|
||||
record_DTOS = data.get('recordDTOS', [])
|
||||
if is_sign_in:
|
||||
for record in record_DTOS:
|
||||
note = sign_in_day_info
|
||||
self.name = record.get('name', '')
|
||||
self.taskRuleId = record.get('taskRuleId', '')
|
||||
self.task_receive(note)
|
||||
else:
|
||||
Log(f'[积分签到]今天已签到, 已签到{sign_in_day}天')
|
||||
else:
|
||||
print(f"获取积分签到信息失败: {response}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"获取积分签到信息异常: {e}")
|
||||
return None
|
||||
|
||||
def task_list(self):
|
||||
print('获取任务列表------>>>')
|
||||
try:
|
||||
data = {"phone": self.phone}
|
||||
response = self.do_request('POST', 'https://mas.deppon.com/crm-api/deppon/points/task/list',data = data)
|
||||
if response and response.get('code') == 200:
|
||||
data = response.get('data',{})
|
||||
taskList = data.get('taskList',[{}])
|
||||
for task in taskList:
|
||||
self.taskRuleId = task.get('taskRuleId',0)
|
||||
self.remark = task.get('remark','')
|
||||
self.name = task.get('name','')
|
||||
print(f'\n当前任务:【{self.name}】 taskRuleId:【{self.taskRuleId}】')
|
||||
rightsClaimStatus = task.get('rightsClaimStatus',0)
|
||||
if rightsClaimStatus == 0:
|
||||
if self.taskRuleId in [8, 9, 11]:
|
||||
print('任务不支持,跳过')
|
||||
break
|
||||
self.changeStatus()
|
||||
elif rightsClaimStatus == 1:
|
||||
self.task_receive()
|
||||
else:
|
||||
print('任务已完成!')
|
||||
return response['data']
|
||||
else:
|
||||
print(f"获取任务列表失败: {response}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"获取任务列表异常: {e}")
|
||||
return None
|
||||
|
||||
def changeStatus(self):
|
||||
print('完成任务------>>>')
|
||||
try:
|
||||
data ={
|
||||
"phone":self.phone,
|
||||
"rightsClaimStatus":1,
|
||||
"taskRuleId":self.taskRuleId
|
||||
}
|
||||
response = self.do_request('POST', 'https://mas.deppon.com/crm-api/deppon/pay/member/add/package/query',data = data)
|
||||
if response and response.get('code') == 200:
|
||||
Log(f'完成任务:【{self.name}】成功!')
|
||||
return response['msg']
|
||||
else:
|
||||
print(f"完成任务【{self.name}】失败: {response}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"获取SVIP最新信息异常: {e}")
|
||||
return None
|
||||
|
||||
def task_receive(self,note=None):
|
||||
print('领取奖励------>>>')
|
||||
try:
|
||||
data = {"phone": self.phone, "taskRuleId": self.taskRuleId,"ruleId":self.taskRuleId,"note":note}
|
||||
response = self.do_request('POST', 'https://mas.deppon.com/crm-api/deppon/points/task/receive',data = data)
|
||||
if response and response.get('code') == 200:
|
||||
Log(f'领取:【{self.name}】任务奖励成功!')
|
||||
return response['msg']
|
||||
else:
|
||||
print(f"领取【{self.name}】任务奖励失败: {response}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"领取任务奖励异常: {e}")
|
||||
return None
|
||||
|
||||
def lottery(self):
|
||||
try:
|
||||
data = {"phone": self.phone,"gameId":'Zv8i7IsOPZIQrvvupKXE1w=='}
|
||||
response = self.do_request('POST', 'https://mas.deppon.com/crm-api/game/draw/lottery',data = data)
|
||||
|
||||
if response and response.get('code') == 200:
|
||||
print('抽奖成功')
|
||||
print(response)
|
||||
self.pointsAvailableValue -= 1
|
||||
return response['msg']
|
||||
else:
|
||||
print(f"抽奖失败: {response}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"获取任务列表异常: {e}")
|
||||
return None
|
||||
|
||||
def lottery_query2(self):
|
||||
print('查询抽奖次数')
|
||||
try:
|
||||
data = {"phone": self.phone}
|
||||
response = self.do_request('POST', 'https://mas.deppon.com/crm-api/points/balance/query2',data = data)
|
||||
|
||||
if response and response.get('code') == 200:
|
||||
# print(response)
|
||||
data = {} if response.get('data', {})==None else response.get('data', {})
|
||||
self.pointsAvailableValue = data.get('pointsAvailableValue', 0)
|
||||
print(f'可以抽奖【{self.pointsAvailableValue}】次')
|
||||
while self.pointsAvailableValue >0:
|
||||
self.lottery()
|
||||
self.pointsAvailableValue -= 1
|
||||
|
||||
return response['msg']
|
||||
else:
|
||||
print(f"查询抽奖失败: {response}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"查询抽奖次数异常: {e}")
|
||||
return None
|
||||
|
||||
|
||||
|
||||
def main(self):
|
||||
Log(f"\n开始执行第{self.index}个账号--------------->>>>>")
|
||||
if self.login():
|
||||
self.getSvipNewestInfo()
|
||||
self.signIn_info()
|
||||
self.points_signIn_info()
|
||||
self.task_list()
|
||||
self.lottery_query2()
|
||||
self.getSvipNewestInfo('执行后')
|
||||
self.sendMsg()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def sendMsg(self):
|
||||
if self.send_UID:
|
||||
push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME)
|
||||
print(push_res)
|
||||
return True
|
||||
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
|
||||
|
||||
def import_Tools():
|
||||
global CHERWIN_TOOLS, ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode
|
||||
import CHERWIN_TOOLS
|
||||
ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME,
|
||||
local_version)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP_NAME = '德邦快递小程序'
|
||||
ENV_NAME = 'DBKD'
|
||||
CK_NAME = 'code'
|
||||
CK_URL = 'https://www.deppon.com/ndcc-gwapi/userService/eco/user/login'
|
||||
print(f'''
|
||||
✨✨✨ {APP_NAME}签到✨✨✨
|
||||
✨ 功能:
|
||||
积分签到
|
||||
✨ 抓包步骤:
|
||||
打开{APP_NAME}
|
||||
授权登陆
|
||||
打开抓包工具
|
||||
找{CK_URL}请求body里面的[{CK_NAME}]
|
||||
复制里面的[{CK_NAME}]参数值
|
||||
参数示例:0f1bjLFa1ZdedHxxxxxxxx
|
||||
✨ ✨✨wxpusher一对一推送功能,
|
||||
✨需要定义变量export WXPUSHER=wxpusher的app_token,不设置则不启用wxpusher一对一推送
|
||||
✨需要在{ENV_NAME}变量最后添加@wxpusher的UID
|
||||
✨ 设置青龙变量:
|
||||
export {ENV_NAME}='{CK_NAME}参数值'多账号#或&分割
|
||||
export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
✨ ✨ 注意:抓完CK没事儿别打开小程序,重新打开小程序请重新抓包
|
||||
✨ 推荐cron:0 6 * * *
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
local_script_name = os.path.basename(__file__)
|
||||
local_version = '2024.04.06'
|
||||
if os.path.isfile('CHERWIN_TOOLS.py'):
|
||||
import_Tools()
|
||||
else:
|
||||
if down_file('CHERWIN_TOOLS.py', 'https://py.cherwin.cn/CHERWIN_TOOLS.py'):
|
||||
print('脚本依赖下载完成请重新运行脚本')
|
||||
import_Tools()
|
||||
else:
|
||||
print('脚本依赖下载失败,请到https://py.cherwin.cn/CHERWIN_TOOLS.py下载最新版本依赖')
|
||||
exit()
|
||||
print(TIPS)
|
||||
token = ''
|
||||
token = ENV if ENV else token
|
||||
if not token:
|
||||
print(f"未填写{ENV_NAME}变量\n青龙可在环境变量设置 {ENV_NAME} 或者在本脚本文件上方将{CK_NAME}填入token =''")
|
||||
exit()
|
||||
tokens = CHERWIN_TOOLS.ENV_SPLIT(token)
|
||||
# print(tokens)
|
||||
if len(tokens) > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<")
|
||||
access_token = []
|
||||
for index, infos in enumerate(tokens):
|
||||
run_result = RUN(infos, index).main()
|
||||
if not run_result: continue
|
||||
if send: send(f'{APP_NAME}挂机通知', send_msg + TIPS_HTML)
|
||||
331
HDL.py
Executable file
331
HDL.py
Executable file
@ -0,0 +1,331 @@
|
||||
# !/usr/bin/python3
|
||||
# -- coding: utf-8 --
|
||||
# -------------------------------
|
||||
# ✨ 推荐cron:0 6 * * *
|
||||
# ✨✨✨ @Author CHERWIN✨✨✨
|
||||
# -------------------------------
|
||||
# cron "0 6 * * *" script-path=xxx.py,tag=匹配cron用
|
||||
# const $ = new Env('中通快递小程序签到')
|
||||
|
||||
import os
|
||||
from os import path
|
||||
import requests
|
||||
import hashlib
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
# import CHERWIN_TOOLS
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
if os.path.isfile('notify.py'):
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
else:
|
||||
print("加载通知服务失败!")
|
||||
send_msg = ''
|
||||
one_msg=''
|
||||
def Log(cont=''):
|
||||
global send_msg,one_msg
|
||||
print(cont)
|
||||
if cont:
|
||||
one_msg += f'{cont}\n'
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
class RUN:
|
||||
def __init__(self,info,index):
|
||||
global one_msg
|
||||
one_msg = ''
|
||||
split_info = info.split('@')
|
||||
self.openId = split_info[0]
|
||||
self.uid = split_info[1]
|
||||
len_split_info = len(split_info)
|
||||
last_info = split_info[len_split_info - 1]
|
||||
self.send_UID = None
|
||||
if len_split_info > 0 and "UID_" in last_info:
|
||||
print('检测到设置了UID')
|
||||
print(last_info)
|
||||
self.send_UID = last_info
|
||||
self.index = index + 1
|
||||
self.s = requests.session()
|
||||
self.s.verify = False
|
||||
|
||||
self.UA = 'Mozilla/5.0 (Linux; Android 14; Mi14 Pro Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160065 MMWEBSDK/20230701 MMWEBID/8701 MicroMessenger/8.0.40.2420(0x28002858) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 miniProgram/wx1ddeb67115f30d1a'
|
||||
self.headers = {
|
||||
'Host': 'superapp-public.kiwa-tech.com',
|
||||
'User-Agent': self.UA ,
|
||||
"_haidilao_app_token": "",
|
||||
"content-type": "application/json",
|
||||
"xweb_xhr": "1",
|
||||
"appid": "15",
|
||||
"appversion": "3.67.0",
|
||||
"accept": "*/*",
|
||||
"sec-fetch-site": "cross-site",
|
||||
"sec-fetch-mode": "cors",
|
||||
"sec-fetch-dest": "empty",
|
||||
"referer": "https://servicewechat.com/wx1ddeb67115f30d1a/121/page-frame.html",
|
||||
"accept-language": "zh-CN,zh;q=0.9"
|
||||
}
|
||||
def do_request(self, url , method='POST', params=None, data=None, headers=None):
|
||||
if not headers:
|
||||
headers = self.headers
|
||||
try:
|
||||
response = self.s.request(method, url, params=params, json=data, headers=headers)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
print(f"请求错误: {e}")
|
||||
return None
|
||||
|
||||
def wechatLogin(self):
|
||||
print('>>>>>>登陆获取token')
|
||||
try:
|
||||
data = {
|
||||
"type": 1,
|
||||
"country": "CN",
|
||||
"codeType": 1,
|
||||
"business": "登录",
|
||||
"terminal": "会员小程序",
|
||||
"openId": self.openId,
|
||||
"uid": self.uid
|
||||
}
|
||||
response = self.do_request( 'https://superapp-public.kiwa-tech.com/api/gateway/login/center/login/wechatLogin',data =data)
|
||||
if response and response.get('success') == True:
|
||||
data = response.get('data',{})
|
||||
id = data.get('id','')
|
||||
token = data.get('token','')
|
||||
self.haidilao_app_token=token
|
||||
self.headers['_haidilao_app_token'] = token
|
||||
Log(f'ID:【{id}】')
|
||||
return True
|
||||
else:
|
||||
print(f"登陆获取token失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"登陆获取token异常: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def queryMemberCacheInfo(self):
|
||||
Log('>>>>>>获取用户信息')
|
||||
try:
|
||||
data = {"type":1}
|
||||
response = self.do_request( 'https://superapp-public.kiwa-tech.com/activity/wxapp/applet/queryMemberCacheInfo',data =data)
|
||||
if response and response.get('success') == True:
|
||||
data = response.get('data',{})
|
||||
customerName = data.get('customerName','')
|
||||
mobile = data.get('mobile','')
|
||||
mobile = mobile[:3] + "*" * 4 + mobile[7:]
|
||||
coinNum = data.get('coinNum','')
|
||||
|
||||
Log(f'用户名:【{customerName}】\n手机号:【{mobile}】\n捞币:【{coinNum}】')
|
||||
return True
|
||||
else:
|
||||
print(f"登陆获取token失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"登陆获取token异常: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def daily_sign_getAct(self):
|
||||
Log('>>>>>>获取签到信息')
|
||||
try:
|
||||
data = {"source":1}
|
||||
response = self.do_request( 'https://superapp-public.kiwa-tech.com/activity/daily/sign/getAct',data =data)
|
||||
if response and response.get('success') == True:
|
||||
data = response.get('data',{})
|
||||
memberSignFlag = data.get('memberSignFlag',False)
|
||||
if memberSignFlag:
|
||||
print('已签到')
|
||||
else:
|
||||
print('未签到')
|
||||
self.signIn()
|
||||
|
||||
return True
|
||||
else:
|
||||
print(f"登陆获取token失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"登陆获取token异常: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def queryFragment(self):
|
||||
try:
|
||||
self.headers['referer'] =f"https://superapp-public.kiwa-tech.com/app-sign-in/?SignInToken={self.haidilao_app_token}&source=MiniApp"
|
||||
|
||||
response = self.do_request( 'https://superapp-public.kiwa-tech.com/activity/wxapp/signin/queryFragment')
|
||||
if response and response.get('success') == True:
|
||||
data = response.get('data',{})
|
||||
total = data.get('total','')
|
||||
expireDate = data.get('expireDate','').split()[0]
|
||||
today = data.get('today','').split()[0]
|
||||
|
||||
Log(f'当前拥有:【{total}】拼图碎片')
|
||||
if expireDate == today:
|
||||
Log('碎片今日到期,请及时兑换!!!!!')
|
||||
Log('碎片今日到期,请及时兑换!!!!!')
|
||||
Log('碎片今日到期,请及时兑换!!!!!')
|
||||
else:
|
||||
Log(f'本期碎片失效时间:{expireDate}')
|
||||
return True
|
||||
else:
|
||||
print(f"获取拼图失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"获取拼图异常: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def signIn(self):
|
||||
try:
|
||||
data = {"signinSource": "MiniApp"}
|
||||
self.headers['referer'] =f"https://superapp-public.kiwa-tech.com/app-sign-in/?SignInToken={self.haidilao_app_token}&source=MiniApp"
|
||||
|
||||
response = self.do_request( 'https://superapp-public.kiwa-tech.com/activity/wxapp/signin/signin',data = data)
|
||||
if response and response.get('success') == True:
|
||||
# data = response.get('data',{})
|
||||
# total = data.get('total','')
|
||||
Log(f'签到成功!')
|
||||
return True
|
||||
else:
|
||||
Log(f"签到失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"签到异常: {e}")
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
def signin_query(self):
|
||||
print('>>>>>>开始签到')
|
||||
try:
|
||||
self.headers['referer'] =f"https://superapp-public.kiwa-tech.com/app-sign-in/?SignInToken={self.haidilao_app_token}&source=MiniApp"
|
||||
|
||||
response = self.do_request( 'https://superapp-public.kiwa-tech.com/activity/wxapp/signin/query')
|
||||
if response and response.get('success') == True:
|
||||
data = response.get('data',{})
|
||||
signinOr = data.get('signinOr',0)
|
||||
activityName = data.get('activityName',0)
|
||||
signinQueryDetailList = data.get('signinQueryDetailList',[{}])
|
||||
daycount = 0
|
||||
for day in signinQueryDetailList:
|
||||
days = day.get('dailySigninStatus',1)
|
||||
if days == 2:
|
||||
daycount+=1
|
||||
if signinOr != 0 :
|
||||
Log(f'已签到,本期累计签到【{daycount}】天')
|
||||
else:
|
||||
Log(f'未签到,本期累计签到【{daycount}】天')
|
||||
self.signIn()
|
||||
return True
|
||||
else:
|
||||
print(f"签到失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"签到异常: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def main(self):
|
||||
Log(f"\n开始执行第{self.index}个账号--------------->>>>>")
|
||||
if self.wechatLogin():
|
||||
self.queryMemberCacheInfo()
|
||||
self.signin_query()
|
||||
self.queryFragment()
|
||||
self.sendMsg()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
def sendMsg(self):
|
||||
if self.send_UID:
|
||||
push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME)
|
||||
print(push_res)
|
||||
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
|
||||
def import_Tools():
|
||||
global CHERWIN_TOOLS,ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode
|
||||
import CHERWIN_TOOLS
|
||||
ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME,local_version)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP_NAME = '海底捞小程序'
|
||||
ENV_NAME = 'HDL'
|
||||
CK_NAME = 'openId@uid'
|
||||
CK_URL= 'https://superapp-public.kiwa-tech.com/api/gateway/login/center/login/wechatLogin'
|
||||
print(f'''
|
||||
✨✨✨ {APP_NAME}签到✨✨✨
|
||||
✨ 功能:
|
||||
签到
|
||||
✨ 抓包步骤:
|
||||
打开抓包工具
|
||||
打开{APP_NAME}
|
||||
授权登陆
|
||||
找{CK_URL}的URl复制请求里面的body[{CK_NAME}]
|
||||
复制里面的[{CK_NAME}]参数值
|
||||
参数示例:o4YwF5LIxxxxx@oF_Z5jh0Bwg_uZrODxxxxxxx
|
||||
✨ ✨✨wxpusher一对一推送功能,
|
||||
✨需要定义变量export WXPUSHER=wxpusher的app_token,不设置则不启用wxpusher一对一推送
|
||||
✨需要在{ENV_NAME}变量最后添加@wxpusher的UID
|
||||
✨ 设置青龙变量:
|
||||
export {ENV_NAME}='{CK_NAME}参数值'多账号#或&分割
|
||||
export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
✨ ✨ 注意:抓完CK没事儿别打开小程序,重新打开小程序请重新抓包
|
||||
✨ 推荐cron:0 6 * * *
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
local_script_name = os.path.basename(__file__)
|
||||
local_version = '2024.04.06'
|
||||
if os.path.isfile('CHERWIN_TOOLS.py'):
|
||||
import_Tools()
|
||||
else:
|
||||
if down_file('CHERWIN_TOOLS.py', 'https://py.cherwin.cn/CHERWIN_TOOLS.py'):
|
||||
print('脚本依赖下载完成请重新运行脚本')
|
||||
import_Tools()
|
||||
else:
|
||||
print('脚本依赖下载失败,请到https://py.cherwin.cn/CHERWIN_TOOLS.py下载最新版本依赖')
|
||||
exit()
|
||||
print(TIPS)
|
||||
token = ''
|
||||
token = ENV if ENV else token
|
||||
if not token:
|
||||
print(f"未填写{ENV_NAME}变量\n青龙可在环境变量设置 {ENV_NAME} 或者在本脚本文件上方将{CK_NAME}填入token =''")
|
||||
exit()
|
||||
tokens = CHERWIN_TOOLS.ENV_SPLIT(token)
|
||||
# print(tokens)
|
||||
if len(tokens) > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<")
|
||||
access_token = []
|
||||
for index, infos in enumerate(tokens):
|
||||
run_result = RUN(infos, index).main()
|
||||
if not run_result: continue
|
||||
if send: send(f'{APP_NAME}挂机通知', send_msg + TIPS_HTML)
|
||||
242
JTSD.py
Executable file
242
JTSD.py
Executable file
@ -0,0 +1,242 @@
|
||||
# !/usr/bin/python3
|
||||
# -- coding: utf-8 --
|
||||
# -------------------------------
|
||||
# ✨✨✨ 中通快递小程序签到✨✨✨
|
||||
# ✨ 功能:
|
||||
# 积分签到
|
||||
# ✨ 抓包步骤:
|
||||
# 打开中通快递小程序
|
||||
# 授权登陆
|
||||
# 打开抓包工具
|
||||
# 找URl请求头带[x-token或者token]
|
||||
# 复制里面的[x-token或者token]参数值
|
||||
# 参数示例:eyJhbGciOiJIUzUxMiJ9.eyJnZW5lcmF0ZVRpbWUixxxxxx
|
||||
# ✨ 设置青龙变量:
|
||||
# export YDKD='x-token或者token参数值'多账号#或&分割
|
||||
# export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
# ✨ ✨ 注意:抓完CK没事儿别打开小程序,重新打开小程序请重新抓包
|
||||
# ✨ 推荐cron:0 6 * * *
|
||||
# ✨✨✨ @Author CHERWIN✨✨✨
|
||||
# -------------------------------
|
||||
# cron "0 6 * * *" script-path=xxx.py,tag=匹配cron用
|
||||
# const $ = new Env('中通快递小程序签到')
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
from os import path
|
||||
import requests
|
||||
import hashlib
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
# import CHERWIN_TOOLS
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
if os.path.isfile('notify.py'):
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
else:
|
||||
print("加载通知服务失败!")
|
||||
send_msg = ''
|
||||
one_msg=''
|
||||
def Log(cont=''):
|
||||
global send_msg,one_msg
|
||||
print(cont)
|
||||
if cont:
|
||||
one_msg += f'{cont}\n'
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
class RUN:
|
||||
def __init__(self,info,index):
|
||||
global one_msg
|
||||
one_msg = ''
|
||||
split_info = info.split('@')
|
||||
self.token = split_info[0]
|
||||
len_split_info = len(split_info)
|
||||
last_info = split_info[len_split_info - 1]
|
||||
self.send_UID = None
|
||||
if len_split_info > 0 and "UID_" in last_info:
|
||||
print('检测到设置了UID')
|
||||
print(last_info)
|
||||
self.send_UID = last_info
|
||||
self.index = index + 1
|
||||
self.s = requests.session()
|
||||
self.s.verify = False
|
||||
|
||||
self.headers = {
|
||||
"Host": "applets.jtexpress.com.cn",
|
||||
"authtoken": self.token,
|
||||
"xweb_xhr": "1",
|
||||
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x6309080f) XWEB/8555",
|
||||
"content-type": "application/json;charset=UTF-8",
|
||||
"accept": "*/*",
|
||||
"sec-fetch-site": "cross-site",
|
||||
"sec-fetch-mode": "cors",
|
||||
"sec-fetch-dest": "empty",
|
||||
"referer": "https://servicewechat.com/wxe37801988179d0a5/316/page-frame.html",
|
||||
"accept-language": "zh-CN,zh;q=0.9"
|
||||
}
|
||||
|
||||
self.baseUrl = 'https://applets.jtexpress.com.cn/'
|
||||
self.news_List = []
|
||||
self.list_index = 0
|
||||
self.isFirstTask = True
|
||||
|
||||
def qureyMyselfGrow(self):
|
||||
Log('>>>>>>获取用户信息')
|
||||
response = self.s.get(f'{self.baseUrl}/applets/user/qureyMyselfGrow?', headers=self.headers)
|
||||
data_info = response.json()
|
||||
# print(point_info)
|
||||
if data_info.get('succ','') == True:
|
||||
data = data_info.get('data', {})
|
||||
mobile = data.get('mobile', '')
|
||||
mobile = mobile[:3] + "*" * 4 + mobile[7:]
|
||||
id = data.get('id', '')
|
||||
memberId = data.get('memberId', '')
|
||||
growValue = data.get('growValue', '')
|
||||
nextStartGrow = data.get('nextStartGrow', '')
|
||||
Log(f'获取用户[{self.index}]信息成功!\n手机号:【{mobile}】\n用户ID:【{memberId}】\n成长值:【{growValue}/{nextStartGrow}】')
|
||||
return True
|
||||
else:
|
||||
print('获取用户信息失败!可能token失效了')
|
||||
return False
|
||||
|
||||
def addActionRecord(self):
|
||||
print('>>>>>>进入签到详情')
|
||||
json_data = {
|
||||
"eventTimestamp": int(time.time() * 1000),
|
||||
"pagePath": "packageA/signIn/index",
|
||||
"reportAddress": "",
|
||||
"reportLocation": "",
|
||||
"phoneModel": "microsoft",
|
||||
"eventType": "enter_signIn",
|
||||
"elementContent": "",
|
||||
"elementEventName": "进入签到详情",
|
||||
"elementCode": 2
|
||||
}
|
||||
response = self.s.post(f'{self.baseUrl}/applets/user/addActionRecord', headers=self.headers,json=json_data)
|
||||
data_info = response.json()
|
||||
# print(point_info)
|
||||
if data_info.get('succ','') == True:
|
||||
msg=data_info.get('msg','')
|
||||
print(f'{msg}')
|
||||
return True
|
||||
else:
|
||||
print('进入签到详情失败!可能token失效了')
|
||||
return False
|
||||
def sign(self):
|
||||
print('>>>>>>开始签到')
|
||||
json_data = {}
|
||||
response = self.s.post(f'{self.baseUrl}/applets/user/sign', headers=self.headers,json=json_data)
|
||||
data_info = response.json()
|
||||
# print(point_info)
|
||||
if data_info.get('succ','') == True:
|
||||
msg=data_info.get('msg','')
|
||||
day=data_info.get('data', {}).get('day', {})
|
||||
Log(f'累计签到【{day}】天')
|
||||
return True
|
||||
else:
|
||||
Log('签到失败')
|
||||
return False
|
||||
|
||||
def main(self):
|
||||
Log(f"\n开始执行第{self.index}个账号--------------->>>>>")
|
||||
if self.qureyMyselfGrow():
|
||||
self.addActionRecord()
|
||||
self.sign()
|
||||
self.sendMsg()
|
||||
else:
|
||||
return False
|
||||
|
||||
def sendMsg(self):
|
||||
if self.send_UID:
|
||||
push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME)
|
||||
print(push_res)
|
||||
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
|
||||
def import_Tools():
|
||||
global CHERWIN_TOOLS,ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode
|
||||
import CHERWIN_TOOLS
|
||||
ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME,local_version)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP_NAME = '极兔速递小程序'
|
||||
ENV_NAME = 'JTSD'
|
||||
CK_NAME = 'authtoken'
|
||||
print(f'''
|
||||
✨✨✨ {APP_NAME}签到✨✨✨
|
||||
✨ 功能:
|
||||
积分签到
|
||||
✨ 抓包步骤:
|
||||
打开{APP_NAME}
|
||||
授权登陆
|
||||
打开抓包工具
|
||||
找URl请求头带[{CK_NAME}]
|
||||
复制里面的[{CK_NAME}]参数值
|
||||
参数示例:eyJhbGciOiJIUzUxMiJ9.eyJnZW5lcmF0ZVRpbWUixxxxxx
|
||||
✨ ✨✨wxpusher一对一推送功能,
|
||||
✨需要定义变量export WXPUSHER=wxpusher的app_token,不设置则不启用wxpusher一对一推送
|
||||
✨需要在{ENV_NAME}变量最后添加@wxpusher的UID
|
||||
✨ 设置青龙变量:
|
||||
export {ENV_NAME}='{CK_NAME}参数值'多账号#或&分割
|
||||
export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
✨ ✨ 注意:抓完CK没事儿别打开小程序,重新打开小程序请重新抓包
|
||||
✨ 推荐cron:0 6 * * *
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
local_script_name = os.path.basename(__file__)
|
||||
local_version = '2024.04.06'
|
||||
if os.path.isfile('CHERWIN_TOOLS.py'):
|
||||
import_Tools()
|
||||
else:
|
||||
if down_file('CHERWIN_TOOLS.py', 'https://py.cherwin.cn/CHERWIN_TOOLS.py'):
|
||||
print('脚本依赖下载完成请重新运行脚本')
|
||||
import_Tools()
|
||||
else:
|
||||
print('脚本依赖下载失败,请到https://py.cherwin.cn/CHERWIN_TOOLS.py下载最新版本依赖')
|
||||
exit()
|
||||
print(TIPS)
|
||||
token = ''
|
||||
token = ENV if ENV else token
|
||||
if not token:
|
||||
print(f"未填写{ENV_NAME}变量\n青龙可在环境变量设置 {ENV_NAME} 或者在本脚本文件上方将{CK_NAME}填入token =''")
|
||||
exit()
|
||||
tokens = CHERWIN_TOOLS.ENV_SPLIT(token)
|
||||
# print(tokens)
|
||||
if len(tokens) > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<")
|
||||
access_token = []
|
||||
for index, infos in enumerate(tokens):
|
||||
run_result = RUN(infos, index).main()
|
||||
if not run_result: continue
|
||||
if send: send(f'{APP_NAME}挂机通知', send_msg + TIPS_HTML)
|
||||
354
KFHS.py
Executable file
354
KFHS.py
Executable file
@ -0,0 +1,354 @@
|
||||
# !/usr/bin/python3
|
||||
# -- coding: utf-8 --
|
||||
# -------------------------------
|
||||
# cron "30 1 * * *" script-path=xxx.py,tag=匹配cron用
|
||||
# const $ = new Env('微信公众号:卡夫亨氏新厨艺')
|
||||
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
from datetime import date, datetime
|
||||
|
||||
import requests
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
# import CHERWIN_TOOLS
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
if os.path.isfile('notify.py'):
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
else:
|
||||
print("加载通知服务失败!")
|
||||
send_msg = ''
|
||||
one_msg=''
|
||||
def Log(cont=''):
|
||||
global send_msg,one_msg
|
||||
print(cont)
|
||||
if cont:
|
||||
one_msg += f'{cont}\n'
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
class RUN:
|
||||
def __init__(self,info,index):
|
||||
global one_msg
|
||||
one_msg = ''
|
||||
split_info = info.split('@')
|
||||
self.token = split_info[0]
|
||||
len_split_info = len(split_info)
|
||||
last_info = split_info[len_split_info - 1]
|
||||
self.send_UID = None
|
||||
if len_split_info > 0 and "UID_" in last_info:
|
||||
self.send_UID = last_info
|
||||
self.index = index + 1
|
||||
Log(f"\n---------开始执行第{self.index}个账号>>>>>")
|
||||
self.s = requests.session()
|
||||
self.s.verify = False
|
||||
|
||||
self.headers = {
|
||||
'Host': 'fscrm.kraftheinz.net.cn',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 NetType/WIFI MicroMessenger/7.0.20.1781(0x6700143B) WindowsWechat(0x63090719) XWEB/8447 Flue',
|
||||
'token': self.token,
|
||||
'Accept': '*/*',
|
||||
'Origin': 'https://fscrm.kraftheinz.net.cn',
|
||||
'Sec-Fetch-Site': 'same-origin',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
'Sec-Fetch-Dest': 'empty',
|
||||
'Referer': 'https://fscrm.kraftheinz.net.cn/?code=031NdLkl2SD8ac4BUKll2x4iqC2NdLkO&state=fid%3DN8d3E4AyKCBiu7DuBRNPlw&appid=wx65da983ae179e97b',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.9',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
}
|
||||
self.baseUrl = 'https://fscrm.kraftheinz.net.cn/crm/public/index.php/api/v1/'
|
||||
|
||||
def getUserInfo(self,End=False):
|
||||
global userid_list, username_list
|
||||
response = self.s.get(
|
||||
f'{self.baseUrl}getUserInfo',
|
||||
headers=self.headers
|
||||
)
|
||||
if response.status_code == 200:
|
||||
try:
|
||||
resp = response.json()
|
||||
data = resp.get('data',{})
|
||||
nickname = data.get('nickname','')
|
||||
openId = data.get('openId','')
|
||||
signTimes = data.get('signTimes',0)
|
||||
memberInfo = data.get('memberInfo', {})
|
||||
phone = memberInfo.get('phone', '')
|
||||
score = memberInfo.get('score', '')
|
||||
if End :
|
||||
Log(f'执行后积分:【{score}】')
|
||||
return True
|
||||
self.member_id = data.get('member_id','')
|
||||
# add = {"nickname":nickname,"member_id":member_id}
|
||||
userid_list.append(self.member_id)
|
||||
username_list.append(nickname)
|
||||
Log(f'>>>当前用户:【{nickname}】\nID:【{self.member_id}】 \nOpenID:【{openId}】 \n已连续签到【{signTimes}】天')
|
||||
serialSign = data.get('serialSign', [{}])
|
||||
|
||||
if serialSign :
|
||||
current_date = date.today()
|
||||
date_string = serialSign[0].get('createdAt',current_date)
|
||||
memberBalance = serialSign[0].get('memberBalance', 0)
|
||||
parsed_date = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S').date()
|
||||
if parsed_date == current_date:
|
||||
print(f"今日已签到,当前积分:【{memberBalance}】")
|
||||
else:
|
||||
print("今日未签到")
|
||||
wait_time = random.randint(1000, 10000) / 1000.0 # 转换为秒
|
||||
time.sleep(wait_time)
|
||||
print('随机延时1-10秒执行签到')
|
||||
self.dailySign()
|
||||
return True
|
||||
except:
|
||||
print(response.text)
|
||||
return False
|
||||
else:
|
||||
print("API访问失败!")
|
||||
return False
|
||||
|
||||
|
||||
def dailySign(self):
|
||||
print('执行签到')
|
||||
response = self.s.post(
|
||||
f'{self.baseUrl}dailySign',
|
||||
headers=self.headers
|
||||
)
|
||||
if response.status_code == 200:
|
||||
try:
|
||||
resp = response.json()
|
||||
msg = resp['msg']
|
||||
Log(f'>{msg}')
|
||||
except:
|
||||
print(response.text)
|
||||
else:
|
||||
print("API访问失败!")
|
||||
|
||||
def getCookbookIndex(self):
|
||||
global Cookid_list
|
||||
data = {
|
||||
'page': '1',
|
||||
'pagesize': '30'
|
||||
}
|
||||
response = self.s.post(
|
||||
f'{self.baseUrl}getCookbookIndex',
|
||||
headers=self.headers, data=data
|
||||
)
|
||||
if response.status_code == 200:
|
||||
try:
|
||||
resp = response.json()
|
||||
id_list = resp['data']['chineseCookbook']['data']
|
||||
for i in id_list:
|
||||
Cookid_list.append(i['id'])
|
||||
print(f'>获取到菜谱ID:【{Cookid_list}】')
|
||||
except:
|
||||
print(response.text)
|
||||
else:
|
||||
print("API访问失败!")
|
||||
|
||||
def recordScoreShare(self, cookbook_id, now_id):
|
||||
# print('')
|
||||
# self.getUserInfo()
|
||||
Log('开始互助')
|
||||
for id in userid_list:
|
||||
if now_id == id: continue
|
||||
# Log(f'>>>开始为【{id}】分享的菜谱【{cookbook_id}】助力')
|
||||
data = {
|
||||
'cookbook_id': cookbook_id,
|
||||
'invite_id': id,
|
||||
}
|
||||
response = self.s.post(
|
||||
f'{self.baseUrl}recordScoreShare',
|
||||
headers=self.headers, data=data
|
||||
)
|
||||
if response.status_code == 200:
|
||||
try:
|
||||
resp = response.json()
|
||||
msg = resp['msg']
|
||||
Log(f'>为【{id}】助力结果:【{msg}】')
|
||||
except:
|
||||
print(response.text)
|
||||
else:
|
||||
print("API访问失败!")
|
||||
|
||||
def helpAuthor(self, authorid, cookbook_id, now_id):
|
||||
Log('开始助力作者')
|
||||
if now_id != authorid:
|
||||
data = {
|
||||
'cookbook_id': cookbook_id,
|
||||
'invite_id': authorid,
|
||||
}
|
||||
response = self.s.post(
|
||||
f'{self.baseUrl}recordScoreShare',
|
||||
headers=self.headers, data=data
|
||||
)
|
||||
if response.status_code == 200:
|
||||
try:
|
||||
resp = response.json()
|
||||
msg = resp['msg']
|
||||
Log(f'>为【作者】助力结果:【{msg}】')
|
||||
except:
|
||||
print(response.text)
|
||||
else:
|
||||
print("API访问失败!")
|
||||
else:
|
||||
Log('助力对象为自身,跳过')
|
||||
|
||||
# 预留兑换函数
|
||||
def exchangeIntegralNew(self):
|
||||
data = {
|
||||
'value': '爱奇艺月卡',
|
||||
'phone': '',
|
||||
'type': '视频卡'
|
||||
}
|
||||
# data = {
|
||||
# 'value': '全网10元话费',
|
||||
# 'phone': '',
|
||||
# 'type': '话费',
|
||||
# 'memberId': '',
|
||||
# }
|
||||
response = self.s.post(
|
||||
f'{self.baseUrl}exchangeIntegralNew',
|
||||
headers=self.headers,
|
||||
data=data
|
||||
)
|
||||
if response.status_code == 200:
|
||||
try:
|
||||
resp = response.json()
|
||||
msg = resp['msg']
|
||||
Log(f'>{msg}')
|
||||
except:
|
||||
print(response.text)
|
||||
else:
|
||||
print("API访问失败!")
|
||||
|
||||
def main(self):
|
||||
# self.getUserInfo()
|
||||
# self.getCookbookIndex()
|
||||
if self.getUserInfo():
|
||||
if self.index == 1:
|
||||
self.getCookbookIndex()
|
||||
self.getUserInfo(True)
|
||||
self.sendMsg()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def help(self):
|
||||
# print(Cookid_list)
|
||||
# print(username_list)
|
||||
# print(userid_list)
|
||||
if Cookid_list and username_list and userid_list:
|
||||
cookbook_id = random.choice(Cookid_list)
|
||||
username = username_list[self.index-1]
|
||||
now_id = userid_list[self.index-1]
|
||||
Log(f'\n当前用于助力用户:【{username}】 ID:【{now_id}】')
|
||||
self.helpAuthor(662056, cookbook_id, now_id)
|
||||
self.recordScoreShare(cookbook_id, now_id)
|
||||
self.sendMsg(True)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def sendMsg(self,help=False):
|
||||
if self.send_UID:
|
||||
push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME,help)
|
||||
print(push_res)
|
||||
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
|
||||
def import_Tools():
|
||||
global CHERWIN_TOOLS,ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode
|
||||
import CHERWIN_TOOLS
|
||||
# print(APP_NAME, local_script_name, ENV_NAME,local_version)
|
||||
ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME,local_version)
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP_NAME = '卡夫亨氏新厨艺'
|
||||
ENV_NAME = 'KFHS'
|
||||
CK_NAME = 'token'
|
||||
print(f'''
|
||||
✨✨✨ {APP_NAME}签到✨✨✨
|
||||
✨ 功能:
|
||||
积分签到
|
||||
✨ 抓包步骤:
|
||||
打开{APP_NAME}
|
||||
授权登陆
|
||||
打开抓包工具
|
||||
找请求头带{CK_NAME}的URl
|
||||
复制里面的{CK_NAME}参数值
|
||||
✨ 注册链接(复制微信打开):https://fscrm.kraftheinz.net.cn/?from=N8d3E4AyKCBiu7DuBRNPlw==#/
|
||||
✨ ✨✨wxpusher一对一推送功能,
|
||||
✨需要定义变量export WXPUSHER=wxpusher的app_token,不设置则不启用wxpusher一对一推送
|
||||
✨需要在{ENV_NAME}变量最后添加@wxpusher的UID
|
||||
参数示例:Fks8FqmiTksnmZSj2fDvxxxxxxxxx@UID_xxxxx
|
||||
✨ 设置青龙变量:
|
||||
export {ENV_NAME}='{CK_NAME}参数值'多账号#或&分割
|
||||
export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
✨ ✨ 注意:token有效期7天,7天后重新抓
|
||||
✨ 推荐cron:5 8 * * *
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
local_script_name = os.path.basename(__file__)
|
||||
local_version = '2024.04.06'
|
||||
if os.path.isfile('CHERWIN_TOOLS.py'):
|
||||
import_Tools()
|
||||
else:
|
||||
if down_file('CHERWIN_TOOLS.py', 'https://py.cherwin.cn/CHERWIN_TOOLS.py'):
|
||||
print('脚本依赖下载完成请重新运行脚本')
|
||||
import_Tools()
|
||||
else:
|
||||
print('脚本依赖下载失败,请到https://py.cherwin.cn/CHERWIN_TOOLS.py下载最新版本依赖')
|
||||
exit()
|
||||
print(TIPS)
|
||||
token = ''
|
||||
token = ENV if ENV else token
|
||||
print(token)
|
||||
if not token:
|
||||
print(f"未填写{ENV_NAME}变量\n青龙可在环境变量设置 {ENV_NAME} 或者在本脚本文件上方将{CK_NAME}填入token =''")
|
||||
exit()
|
||||
tokens = CHERWIN_TOOLS.ENV_SPLIT(token)
|
||||
print(tokens)
|
||||
Cookid_list = []
|
||||
userid_list = []
|
||||
username_list = []
|
||||
if len(tokens) > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<")
|
||||
for index, infos in enumerate(tokens):
|
||||
run_result = RUN(infos, index).main()
|
||||
if not run_result: continue
|
||||
print(f"\n>>>>>>>>>>开始互助<<<<<<<<<<")
|
||||
for index, infos in enumerate(tokens):
|
||||
run_result = RUN(infos, index).help()
|
||||
if not run_result: continue
|
||||
if send: send(f'{APP_NAME}挂机通知', send_msg + TIPS_HTML)
|
||||
366
KWW.py
Executable file
366
KWW.py
Executable file
@ -0,0 +1,366 @@
|
||||
# !/usr/bin/python3
|
||||
# -- coding: utf-8 --
|
||||
# -------------------------------
|
||||
# cron "0 6 * * *" script-path=xxx.py,tag=匹配cron用
|
||||
# const $ = new Env('口味王小程序签到')
|
||||
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
|
||||
import requests
|
||||
import hashlib
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
# import CHERWIN_TOOLS
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
if os.path.isfile('notify.py'):
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
else:
|
||||
print("加载通知服务失败!")
|
||||
send_msg = ''
|
||||
one_msg=''
|
||||
def Log(cont=''):
|
||||
global send_msg,one_msg
|
||||
print(cont)
|
||||
if cont:
|
||||
one_msg += f'{cont}\n'
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
class RUN:
|
||||
def __init__(self,info,index):
|
||||
global one_msg
|
||||
one_msg = ''
|
||||
split_info = info.split('@')
|
||||
self.memberId = split_info[0]
|
||||
self.unionId = split_info[1]
|
||||
self.openId = split_info[2]
|
||||
len_split_info = len(split_info)
|
||||
last_info = split_info[len_split_info - 1]
|
||||
self.send_UID = None
|
||||
if len_split_info > 0 and "UID_" in last_info:
|
||||
print('检测到设置了UID')
|
||||
print(last_info)
|
||||
self.send_UID = last_info
|
||||
self.index = index + 1
|
||||
|
||||
|
||||
self.UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x6309080f) XWEB/9079"
|
||||
|
||||
self.headers = {
|
||||
"Host": "member.kwwblcj.com",
|
||||
"xweb_xhr": "1",
|
||||
"User-Agent": self.UA,
|
||||
"user-paramname": "memberId",
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "/",
|
||||
"Sec-Fetch-Site": "cross-site",
|
||||
"Sec-Fetch-Mode": "cors",
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Referer": "https://servicewechat.com/wxfb0905b0787971ad/101/page-frame.html",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9"
|
||||
}
|
||||
|
||||
def wxHeards(self):
|
||||
timestamp = int(time.time() * 1000)
|
||||
random_num = random.randint(0, 31)
|
||||
u = [
|
||||
"A", "Z", "B", "Y", "C", "X", "D", "T", "E", "S", "F", "R", "G", "Q", "H", "P", "I", "O", "J", "N", "k",
|
||||
"M", "L", "a", "c", "d", "f", "h", "k", "p", "y", "n"]
|
||||
r = f"{timestamp}{self.memberId}{u[random_num]}"
|
||||
sign = hashlib.md5(r.encode()).hexdigest()
|
||||
update_headers = {
|
||||
"user-sign": sign,
|
||||
"user-paramname": "memberId",
|
||||
"user-timestamp": str(timestamp),
|
||||
"user-random": str(random_num)
|
||||
}
|
||||
self.headers.update(update_headers)
|
||||
|
||||
return
|
||||
def do_request(self, url , method='POST', params=None, data=None, headers=None):
|
||||
self.wxHeards()
|
||||
if not headers:
|
||||
headers = self.headers
|
||||
try:
|
||||
response = s.request(method, url, params=params, json=data, headers=headers)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
print(f"请求错误: {e}")
|
||||
return None
|
||||
|
||||
def memberInfo(self):
|
||||
print('>>>>>>获取用户信息')
|
||||
try:
|
||||
url = f"https://member.kwwblcj.com/member/api/info/?userKeys=v1.0&pageName=member-info-index-search&formName=searchForm&kwwMember.memberId={self.memberId}&kwwMember.unionid={self.unionId}&memberId={self.memberId}"
|
||||
response = self.do_request(url,'GET')
|
||||
if response and response.get('msg') == "查询成功":
|
||||
result = response.get('result',{})
|
||||
memberInfo = result.get('memberInfo',{})
|
||||
self.userCname = memberInfo.get('userCname','')
|
||||
Log(f'当前用户:【{self.userCname}】')
|
||||
return True
|
||||
else:
|
||||
print(f"登陆获取token失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"登陆获取token异常: {e}")
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def get_task_list(self):
|
||||
print('>>>>>>获取任务列表')
|
||||
# try:
|
||||
url = f"https://member.kwwblcj.com/member/api/list/?userKeys=v1.0&pageName=select-task-list&formName=searchForm&page=1&rows=20&memberId={self.memberId}"
|
||||
response = self.do_request(url,'GET')
|
||||
if response and response.get('msg') == "查询成功":
|
||||
rows = response.get('rows',[{}])
|
||||
for task in rows:
|
||||
self.taskLimit = task.get('taskLimit','')
|
||||
self.taskTitle = task.get('taskTitle','')
|
||||
self.subTitle = task.get('subTitle','')
|
||||
self.complete = task.get('complete','')
|
||||
self.rewardScore = task.get('rewardScore','')
|
||||
self.ruleType = task.get('ruleType','')
|
||||
self.infoId = task.get('infoId','')
|
||||
# print(f'\n当前任务:【{self.taskTitle}】\n任务要求:【{self.subTitle}】\n任务奖励:【{self.rewardScore}】\ninfoId:【{self.infoId}】\nruleType:【{self.ruleType}】')
|
||||
print(f'当前任务:【{self.taskTitle}】')
|
||||
if self.complete == '1':
|
||||
print('任务已完成!')
|
||||
continue
|
||||
if self.taskTitle == '每日阅读':
|
||||
self.ReadTask()
|
||||
|
||||
elif self.taskTitle == "收青果":
|
||||
self.activity()
|
||||
|
||||
# elif self.taskTitle == "每日答题":
|
||||
# pass
|
||||
# self.loginFreePlugin()
|
||||
else:
|
||||
print('暂不支持此任务')
|
||||
wait_time = random.randint(2, 4) # 转换为秒
|
||||
time.sleep(wait_time) # 等待
|
||||
return True
|
||||
else:
|
||||
print(f"获取任务列表失败: {response}")
|
||||
return False
|
||||
# except Exception as e:
|
||||
# print(f"获取任务列表异常: {e}")
|
||||
# return False
|
||||
|
||||
def activity(self):
|
||||
print(f'>>>>>>{self.taskTitle}')
|
||||
try:
|
||||
url = f"https://member.kwwblcj.com/member/api/list/?userKeys=v1.0&pageName=activeTaskFlag&formName=editForm&memberId={self.memberId}&userCname={self.userCname}&page=1&rows=2"
|
||||
|
||||
response = self.do_request(url,'GET')
|
||||
|
||||
# url2 = f"https://member.kwwblcj.com/member/api/list/?userKeys=v1.0&pageName=memberTaskInfo&formName=searchForm&page=1&rows=2&memberId={self.memberId}"
|
||||
# response = self.do_request(url2, 'GET')
|
||||
#
|
||||
if response and response.get('flag') == "T":
|
||||
print(f'访问:【{self.taskTitle}】成功!')
|
||||
return True
|
||||
else:
|
||||
print(f"{self.taskTitle}失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"{self.taskTitle}异常: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def ReadTask(self):
|
||||
print(f'>>>>>>{self.taskTitle}')
|
||||
try:
|
||||
url = f"https://member.kwwblcj.com/member/api/list/?userKeys=v1.0&pageName=setNewsReadTaskFlag&formName=addForm&memberId={self.memberId}&userCname={self.userCname}&articleTitle=3.15&actionType=articleRead&actionDesc=3.15https%3A%2F%2Fmp.weixin.qq.com%2Fs%2F_2N3AQ12lbXfBSSPja-Q0Q&memberName={self.userCname}&objId=C01&page=1&rows=2"
|
||||
|
||||
response = self.do_request(url,'GET')
|
||||
|
||||
if response and response.get('flag') == "T":
|
||||
|
||||
print(f'阅读成功!')
|
||||
return True
|
||||
else:
|
||||
print(f"{self.taskTitle}失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"{self.taskTitle}异常: {e}")
|
||||
return False
|
||||
|
||||
def getPoint(self):
|
||||
try:
|
||||
url = f"https://member.kwwblcj.com/member/api/list/?userKeys=v1.0&pageName=me-funds&formName=searchForm&userId={self.memberId}&page=1&rows=2&memberId={self.memberId}"
|
||||
|
||||
response = self.do_request(url,'GET')
|
||||
if response and response.get('flag') == "T":
|
||||
rows = response.get('rows',{})
|
||||
balance = rows.get('balance','')
|
||||
# print(response)
|
||||
Log(f'当前积分:【{balance}】\n')
|
||||
return True
|
||||
else:
|
||||
print(f"获取积分信息失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"获取积分信息异常: {e}")
|
||||
return False
|
||||
|
||||
def loginFreePlugin(self):
|
||||
print(f'>>>>>>{self.taskTitle}')
|
||||
try:
|
||||
url = f"https://member.kwwblcj.com/member/api/info/?userKeys=v1.0&pageName=loginFreePlugin&formName=searchForm&uid={self.memberId}&levelCode=K1&redirect=https%3A%2F%2F89420.activity-20.m.duiba.com.cn%2Fprojectx%2Fp129446ea%2Findex.html%3FappID%3D89420&memberId={self.memberId}"
|
||||
response = self.do_request(url,'GET')
|
||||
if response and response.get('msg') == "信息获取成功!":
|
||||
result = response.get('result',{})
|
||||
self.autologin(result)
|
||||
return True
|
||||
else:
|
||||
print(f"{self.taskTitle}失败: {response}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"{self.taskTitle}异常: {e}")
|
||||
return False
|
||||
|
||||
def autologin(self,url):
|
||||
try:
|
||||
headers = {
|
||||
"Host": "89420.activity-20.m.duiba.com.cn",
|
||||
"upgrade-insecure-requests": "1",
|
||||
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x6309080f) XWEB/9079",
|
||||
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||||
"sec-fetch-site": "none",
|
||||
"sec-fetch-mode": "navigate",
|
||||
"sec-fetch-user": "?1",
|
||||
"sec-fetch-dest": "document",
|
||||
"accept-language": "zh-CN,zh;q=0.9"
|
||||
}
|
||||
|
||||
response = s.get(url, headers=headers,allow_redirects=True)
|
||||
print(response.text)
|
||||
url = 'https://89420.activity-20.m.duiba.com.cn/projectx/p129446ea/coop_frontVariable.query?user_type=0&is_from_share=1&_t=1710789863411'
|
||||
|
||||
response = s.get(url, headers=headers)
|
||||
print(response.text)
|
||||
# if response and response.get('msg') == "信息获取成功!":
|
||||
# result = response.get('result',{})
|
||||
#
|
||||
# return True
|
||||
# else:
|
||||
# print(f"{self.taskTitle}失败: {response}")
|
||||
# return False
|
||||
except Exception as e:
|
||||
print(f"{self.taskTitle}异常: {e}")
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def main(self):
|
||||
print(f"\n开始执行第{self.index}个账号--------------->>>>>")
|
||||
# self.memberInfo()
|
||||
if self.memberInfo():
|
||||
self.get_task_list()
|
||||
self.getPoint()
|
||||
self.sendMsg()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def sendMsg(self):
|
||||
if self.send_UID:
|
||||
push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME)
|
||||
print(push_res)
|
||||
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
|
||||
def import_Tools():
|
||||
global CHERWIN_TOOLS,ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode
|
||||
import CHERWIN_TOOLS
|
||||
ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME,local_version)
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP_NAME = '口味王会员中心小程序'
|
||||
ENV_NAME = 'KWW'
|
||||
CK_NAME = 'memberId@unionid@openid'
|
||||
CK_URL= '/member/api/info/'
|
||||
print(f'''
|
||||
✨✨✨ {APP_NAME}签到✨✨✨
|
||||
✨ 功能:
|
||||
积分签到
|
||||
部分积分任务
|
||||
✨ 抓包步骤:
|
||||
打开抓包工具
|
||||
打开{APP_NAME}
|
||||
授权登陆
|
||||
找{CK_URL}的URl提取请求[{CK_NAME}](@符号连接)
|
||||
参数示例:4249095xxxxxx@oWmTE6IqrlDFRzxxxxx@o_V6_5btlEBzxxxxxx
|
||||
✨ ✨✨wxpusher一对一推送功能,
|
||||
✨需要定义变量export WXPUSHER=wxpusher的app_token,不设置则不启用wxpusher一对一推送
|
||||
✨需要在{ENV_NAME}变量最后添加@wxpusher的UID
|
||||
✨ 设置青龙变量:
|
||||
export {ENV_NAME}='{CK_NAME}参数值'多账号#或&分割
|
||||
export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
✨ 推荐cron:0 9 * * *
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
local_script_name = os.path.basename(__file__)
|
||||
local_version = '2024.04.06'
|
||||
if os.path.isfile('CHERWIN_TOOLS.py'):
|
||||
import_Tools()
|
||||
else:
|
||||
if down_file('CHERWIN_TOOLS.py', 'https://py.cherwin.cn/CHERWIN_TOOLS.py'):
|
||||
print('脚本依赖下载完成请重新运行脚本')
|
||||
import_Tools()
|
||||
else:
|
||||
print('脚本依赖下载失败,请到https://py.cherwin.cn/CHERWIN_TOOLS.py下载最新版本依赖')
|
||||
exit()
|
||||
print(TIPS)
|
||||
token = ''
|
||||
token = ENV if ENV else token
|
||||
if not token:
|
||||
print(f"未填写{ENV_NAME}变量\n青龙可在环境变量设置 {ENV_NAME} 或者在本脚本文件上方将{CK_NAME}填入token =''")
|
||||
exit()
|
||||
tokens = CHERWIN_TOOLS.ENV_SPLIT(token)
|
||||
# print(tokens)
|
||||
if len(tokens) > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<")
|
||||
access_token = []
|
||||
for index, infos in enumerate(tokens):
|
||||
s = requests.session()
|
||||
s.verify = False
|
||||
run_result = RUN(infos, index).main()
|
||||
if not run_result: continue
|
||||
if send: send(f'{APP_NAME}挂机通知', send_msg + TIPS_HTML)
|
||||
|
||||
|
||||
|
||||
335
NXDD.py
Executable file
335
NXDD.py
Executable file
@ -0,0 +1,335 @@
|
||||
# !/usr/bin/python3
|
||||
# -- coding: utf-8 --
|
||||
# -------------------------------
|
||||
# @Author CHERWIN✨✨✨
|
||||
# -------------------------------
|
||||
# cron "30 1 * * *" script-path=xxx.py,tag=匹配cron用
|
||||
# const $ = new Env('奈雪小程序签到')
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import requests
|
||||
import hashlib
|
||||
import hmac
|
||||
import base64
|
||||
import time
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
if os.path.isfile('notify.py'):
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
else:
|
||||
print("加载通知服务失败!")
|
||||
send_msg = ''
|
||||
one_msg=''
|
||||
def Log(cont=''):
|
||||
global send_msg,one_msg
|
||||
print(cont)
|
||||
if cont:
|
||||
one_msg += f'{cont}\n'
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
class RUN:
|
||||
def __init__(self,info,index):
|
||||
global one_msg
|
||||
one_msg = ''
|
||||
split_info = info.split('@')
|
||||
token = split_info[0]
|
||||
len_split_info = len(split_info)
|
||||
last_info = split_info[len_split_info - 1]
|
||||
self.send_UID = None
|
||||
if len_split_info > 0 and "UID_" in last_info:
|
||||
print('检测到设置了UID')
|
||||
print(last_info)
|
||||
self.send_UID = last_info
|
||||
self.index = index + 1
|
||||
self.s = requests.session()
|
||||
self.s.verify = False
|
||||
|
||||
self.token = f'Bearer {token}'
|
||||
self.UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF XWEB/6945'
|
||||
self.openId = 'QL6ZOftGzbziPlZwfiXM'
|
||||
|
||||
def random_string(self,length=6, chars='123456789'):
|
||||
return ''.join(random.choice(chars) for _ in range(length))
|
||||
|
||||
def get_body(self):
|
||||
nonce = int(self.random_string())
|
||||
timestamp = int(time.time())
|
||||
url_path = f'nonce={nonce}&openId={self.openId}×tamp={timestamp}'
|
||||
signature = base64.b64encode(
|
||||
hmac.new('sArMTldQ9tqU19XIRDMWz7BO5WaeBnrezA'.encode(), url_path.encode(), hashlib.sha1).digest()).decode()
|
||||
common = {
|
||||
'platform': 'wxapp',
|
||||
'version': '5.1.8',
|
||||
'imei': '',
|
||||
'osn': 'microsoft',
|
||||
'sv': 'Windows 10 x64',
|
||||
'lang': 'zh_CN',
|
||||
'currency': 'CNY',
|
||||
'timeZone': '',
|
||||
'nonce': nonce,
|
||||
'openId': self.openId,
|
||||
'timestamp': timestamp,
|
||||
'signature': signature
|
||||
}
|
||||
params = {
|
||||
'businessType': 1,
|
||||
'brand': 26000252,
|
||||
'tenantId': 1,
|
||||
'channel': 2,
|
||||
'stallType': None,
|
||||
'storeId': None
|
||||
}
|
||||
|
||||
requestData = {
|
||||
'common': common,
|
||||
'params': params
|
||||
}
|
||||
return requestData
|
||||
|
||||
def task_api(self,api_options=None):
|
||||
if api_options is None:
|
||||
api_options = {}
|
||||
try:
|
||||
# 首先解析URL,获得主机名
|
||||
host_name = api_options['url'].replace('//', '/').split('/')[1]
|
||||
full_url = api_options['url']
|
||||
if 'queryParam' in api_options:
|
||||
# 如果存在查询参数,将其附加到URL
|
||||
query_str = "&".join(f"{k}={v}" for k, v in api_options['queryParam'].items())
|
||||
full_url += '?' + query_str
|
||||
# 定义请求头
|
||||
headers = {
|
||||
'Host': host_name,
|
||||
'Connection': 'keep-alive',
|
||||
'User-Agent': self.UA,
|
||||
'Authorization': self.token,
|
||||
'Referer': 'https://tm-web.pin-dao.cn/',
|
||||
'Origin': 'https://tm-web.pin-dao.cn'
|
||||
}
|
||||
# 准备请求体
|
||||
data = None
|
||||
if 'body' in api_options:
|
||||
body = self.get_body()
|
||||
body['params'].update(api_options['body'])
|
||||
content_type = api_options.get('Content-Type', 'application/json')
|
||||
headers['Content-Type'] = content_type
|
||||
if 'json' in content_type:
|
||||
data = json.dumps(body)
|
||||
else:
|
||||
data = "&".join(f"{k}={json.dumps(v) if isinstance(v, dict) else v}" for k, v in body.items())
|
||||
headers['Content-Length'] = str(len(data))
|
||||
# 如果有额外的URL参数或头部参数,合并到请求中
|
||||
if 'urlObjectParam' in api_options:
|
||||
# 这里根据需要处理urlObjectParam
|
||||
pass
|
||||
if 'headerParam' in api_options:
|
||||
headers.update(api_options['headerParam'])
|
||||
# 发出请求
|
||||
response = requests.request(method=api_options.get('method', 'GET'), url=full_url, headers=headers,
|
||||
data=data, timeout=20,verify=False)
|
||||
# 打印状态码
|
||||
if response.status_code != 200:
|
||||
print(f"[{api_options.get('fn', 'unknown function')}]返回[{response.status_code}]")
|
||||
|
||||
# 解析结果
|
||||
try:
|
||||
result = response.json()
|
||||
except ValueError:
|
||||
result = response.text
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
return {}
|
||||
|
||||
def base_userinfo(self):
|
||||
try:
|
||||
api_options = {
|
||||
'fn': 'baseUserinfo',
|
||||
'method': 'post',
|
||||
'url': 'https://tm-web.pin-dao.cn/user/base-userinfo',
|
||||
'body': {}
|
||||
}
|
||||
response = self.task_api(api_options)
|
||||
if response['code'] == 0:
|
||||
# 登录成功的逻辑处理
|
||||
phone = response['data']['phone']
|
||||
self.phone = phone[:3] + "*" * 4 + phone[7:]
|
||||
self.userId = response['data']['userId']
|
||||
self.nickName = response['data']['nickName']
|
||||
Log(f'账号[{self.index}]登录成功!\n手机号:[{self.phone}] ID[{self.userId}]')
|
||||
# print(one_msg)
|
||||
return True
|
||||
else:
|
||||
# 登录失败的逻辑处理
|
||||
Log(f"账号登录失败: {response['message']}")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def user_account(self):
|
||||
try:
|
||||
api_options = {
|
||||
'fn': 'userAccount',
|
||||
'method': 'post',
|
||||
'url': 'https://tm-web.pin-dao.cn/user/account/user-account',
|
||||
'body': {}
|
||||
}
|
||||
response = self.task_api(api_options)
|
||||
if response['code'] == 0:
|
||||
# 查询成功的逻辑处理
|
||||
coin = response['data']['coin']
|
||||
Log(f'账号[{self.index}]当前奈雪币: {coin}')
|
||||
else:
|
||||
# 查询失败的逻辑处理
|
||||
Log(f'账号[{self.index}]查询失败')
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def sign_record(self):
|
||||
try:
|
||||
sign_date = datetime.datetime.now().replace(day=1).strftime('%Y-%m-%d')
|
||||
today_date = datetime.datetime.now().strftime('%Y-%m-%d')
|
||||
api_options = {
|
||||
'fn': 'signRecord',
|
||||
'method': 'post',
|
||||
'url': 'https://tm-web.pin-dao.cn/user/sign/records',
|
||||
'body': {
|
||||
'signDate': sign_date,
|
||||
'startDate': today_date
|
||||
}
|
||||
}
|
||||
response = self.task_api(api_options)
|
||||
if response['code'] == 0:
|
||||
Log(f"今天{'已' if response['data']['status'] else '未'}签到,已签到{response['data']['signCount']}天")
|
||||
if not response['data']['status']:
|
||||
self.sign_save()
|
||||
else:
|
||||
Log(f"查询签到失败: {response['message']}")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def sign_save(self):
|
||||
try:
|
||||
sign_date = datetime.datetime.now().strftime('%Y-%m-%d')
|
||||
api_options = {
|
||||
'fn': 'signSave',
|
||||
'method': 'post',
|
||||
'url': 'https://tm-web.pin-dao.cn/user/sign/save',
|
||||
'body': {
|
||||
'signDate': sign_date
|
||||
}
|
||||
}
|
||||
response = self.task_api(api_options)
|
||||
if response['code'] == 0:
|
||||
if response['data']['flag']:
|
||||
Log('签到成功')
|
||||
else:
|
||||
Log('今天已经签到过了')
|
||||
else:
|
||||
print(f"签到失败: {response['message']}")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def main(self):
|
||||
Log(f"\n开始执行第{self.index}个账号--------------->>>>>")
|
||||
base_userinfo_result = self.base_userinfo()
|
||||
if not base_userinfo_result:
|
||||
Log("用户信息无效,请更新CK")
|
||||
return False
|
||||
self.sign_record()
|
||||
self.user_account()
|
||||
self.sendMsg()
|
||||
return True
|
||||
|
||||
def sendMsg(self, help=False):
|
||||
if self.send_UID:
|
||||
push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME, help)
|
||||
print(push_res)
|
||||
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
|
||||
def import_Tools():
|
||||
global CHERWIN_TOOLS,ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode
|
||||
import CHERWIN_TOOLS
|
||||
ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME,local_version)
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP_NAME = '奈雪点单小程序'
|
||||
ENV_NAME = 'NXDD'
|
||||
CK_NAME = 'Authorization'
|
||||
print(f'''
|
||||
✨✨✨ {APP_NAME}签到✨✨✨
|
||||
✨ 功能:
|
||||
积分签到
|
||||
✨ 抓包步骤:
|
||||
打开{APP_NAME}
|
||||
授权登陆
|
||||
打开抓包工具
|
||||
找请求头带{CK_NAME}的URl
|
||||
复制里面的{CK_NAME}参数值【不要】前面的Bearer 【不要】前面的Bearer 【不要】前面的Bearer
|
||||
参数示例:eyJhbGciOiJxxxxxxxxxxxx
|
||||
✨ 设置青龙变量:
|
||||
export {ENV_NAME}='{CK_NAME}参数值【不要】前面的Bearer'多账号#或&分割
|
||||
export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
✨ ✨ 注意:抓完CK没事儿别打开小程序,重新打开小程序请重新抓包
|
||||
✨ 推荐cron:30 1 * * *
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
local_script_name = os.path.basename(__file__)
|
||||
local_version = '2024.04.06'
|
||||
if os.path.isfile('CHERWIN_TOOLS.py'):
|
||||
import_Tools()
|
||||
else:
|
||||
if down_file('CHERWIN_TOOLS.py', 'https://py.cherwin.cn/CHERWIN_TOOLS.py'):
|
||||
print('脚本依赖下载完成请重新运行脚本')
|
||||
import_Tools()
|
||||
else:
|
||||
print('脚本依赖下载失败,请到https://py.cherwin.cn/CHERWIN_TOOLS.py下载最新版本依赖')
|
||||
exit()
|
||||
print(TIPS)
|
||||
token = ''
|
||||
token = ENV if ENV else token
|
||||
if not token:
|
||||
print(f"未填写{ENV_NAME}变量\n青龙可在环境变量设置 {ENV_NAME} 或者在本脚本文件上方将{CK_NAME}填入token =''")
|
||||
exit()
|
||||
tokens = CHERWIN_TOOLS.ENV_SPLIT(token)
|
||||
# print(tokens)
|
||||
if len(tokens) > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<")
|
||||
access_token = []
|
||||
for index, infos in enumerate(tokens):
|
||||
run_result = RUN(infos, index).main()
|
||||
if not run_result: continue
|
||||
if send: send(f'{APP_NAME}挂机通知', send_msg + TIPS_HTML)
|
||||
554
PPCS.py
Executable file
554
PPCS.py
Executable file
@ -0,0 +1,554 @@
|
||||
'''
|
||||
!/usr/bin/python3
|
||||
-- coding: utf-8 --
|
||||
-------------------------------
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
cron "0 9 * * *" script-path=xxx.py,tag=匹配cron用
|
||||
const $ = new Env('朴朴超市APP')
|
||||
'''
|
||||
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
from sys import exit
|
||||
from datetime import datetime, timedelta
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import requests
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
if os.path.isfile('notify.py'):
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
else:
|
||||
print("加载通知服务失败!")
|
||||
|
||||
send_msg = ''
|
||||
one_msg=''
|
||||
def Log(cont=''):
|
||||
global send_msg,one_msg
|
||||
print(cont)
|
||||
if cont:
|
||||
one_msg += f'{cont}\n'
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
inviteCode = {}
|
||||
|
||||
class RUN:
|
||||
def __init__(self, info,index,access_token=None,user_id=None):
|
||||
global one_msg
|
||||
one_msg = ''
|
||||
split_info = info.split('@')
|
||||
self.refresh_token = split_info[0]
|
||||
len_split_info = len(split_info)
|
||||
last_info = split_info[len_split_info - 1]
|
||||
self.send_UID = None
|
||||
if len_split_info > 0 and "UID_" in last_info:
|
||||
self.send_UID = last_info
|
||||
self.index = index + 1
|
||||
|
||||
Log(f"\n---------开始执行第{self.index}个账号>>>>>")
|
||||
self.s = requests.session()
|
||||
self.s.verify = False
|
||||
self.UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x6309080f) XWEB/8555'
|
||||
self.headers = {
|
||||
'Authorization': '',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'User-Agent': self.UA,
|
||||
'Origin': 'https://ma.pupumall.com',
|
||||
'Sec-Fetch-Site': 'cross-site',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
'Sec-Fetch-Dest': 'empty',
|
||||
'Referer': 'https://ma.pupumall.com/',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.9',
|
||||
'pp-os': '0'
|
||||
}
|
||||
# print(self.refresh_token)
|
||||
self.team_need_help = False
|
||||
self.teamId = ''
|
||||
self.location = {}
|
||||
self.store_id = None
|
||||
self.zip = None
|
||||
self.lng = None
|
||||
self.lat = None
|
||||
self.params = {
|
||||
'supplement_id': '',
|
||||
'lat_y': '',
|
||||
'lng_x': '',
|
||||
}
|
||||
if access_token:
|
||||
self.access_token=access_token
|
||||
self.headers['Authorization'] = access_token
|
||||
self.headers['pp-userid'] = user_id
|
||||
self.near_location_by_city()
|
||||
self.wait_time = random.randint(1000, 3000) / 1000.0 # 转换为秒
|
||||
|
||||
|
||||
|
||||
def make_request(self, url, method='post',headers={},params='',data={}):
|
||||
parsed_url = urlparse(url)
|
||||
host = parsed_url.netloc
|
||||
self.headers['Host'] = host
|
||||
if headers == {}:
|
||||
headers = self.headers
|
||||
if data =={}:
|
||||
data = self.params
|
||||
try:
|
||||
if method.lower() == 'get':
|
||||
response = self.s.get(url, headers=headers, verify=False,params=params)
|
||||
elif method.lower() == 'post':
|
||||
response = self.s.post(url, headers=headers, json=data, verify=False)
|
||||
else:
|
||||
raise ValueError("不支持的请求方法: " + method)
|
||||
|
||||
return response.json()
|
||||
except requests.exceptions.RequestException as e:
|
||||
print("请求异常:", e)
|
||||
except ValueError as e:
|
||||
print("值错误或不支持的请求方法:", e)
|
||||
except Exception as e:
|
||||
print("发生了未知错误:", e)
|
||||
|
||||
def near_location_by_city(self):
|
||||
print('>>>>>>开始随机选择位置')
|
||||
url = 'https://j1.pupuapi.com/client/store/place/near_location_by_city/v2'
|
||||
# 生成随机的四位数
|
||||
random_digits = ''.join(random.choices('0123456789', k=4))
|
||||
# 准备查询参数
|
||||
search_params = {
|
||||
'lng': '119.31' + random_digits,
|
||||
'lat': '26.06' + random_digits
|
||||
}
|
||||
try:
|
||||
result =self.make_request(url,method='get',params=search_params)
|
||||
errcode = result.get('errcode', -1)
|
||||
if errcode == 0:
|
||||
data = result.get('data')
|
||||
# 假设randomList是一个选择列表中随机元素的方法
|
||||
self.location = self.randomList(data)
|
||||
self.store_id = self.location['service_store_id']
|
||||
self.zip = self.location['city_zip']
|
||||
self.lng = str(self.location['lng_x'])
|
||||
self.lat = str(self.location['lat_y'])
|
||||
self.params['lat_y'] = self.lat
|
||||
self.params['lat_x'] = self.lng
|
||||
# 更新请求头部
|
||||
self.headers['pp_storeid'] = self.store_id
|
||||
self.headers['pp-cityzip'] = str(self.zip)
|
||||
print('>选取随机地点成功')
|
||||
else:
|
||||
errmsg = result.get('errmsg', '')
|
||||
print(f'>选取随机地点失败[{errcode}]: {errmsg}')
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def randomList(self, lst):
|
||||
# 返回列表中的随机项
|
||||
return random.choice(lst)
|
||||
|
||||
def get_AccessToken(self):
|
||||
# Log('获取access_token')
|
||||
url = "https://cauth.pupuapi.com/clientauth/user/refresh_token"
|
||||
data = {
|
||||
"refresh_token": self.refresh_token
|
||||
}
|
||||
headers = {
|
||||
"User-Agent": "Pupumall/4.7.3;Android/11;dda37894d1b4c3ed09b6272c55b37cf2",
|
||||
"Content-Type": "application/json; charset=UTF-8",
|
||||
"Host": "cauth.pupuapi.com",
|
||||
"Connection": "Keep-Alive",
|
||||
"Accept-Encoding": "gzip"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.put(url, headers=headers, data=json.dumps(data), verify=False)
|
||||
response.raise_for_status()
|
||||
|
||||
json_response = response.json()
|
||||
print(json_response)
|
||||
data = json_response.get('data', {})
|
||||
access_token = data.get('access_token', '')
|
||||
if access_token:
|
||||
self.access_token = f'Bearer '+access_token
|
||||
self.user_id = data.get('user_id')
|
||||
self.name = data.get('nick_name', '')
|
||||
self.headers['Authorization'] = self.access_token
|
||||
self.headers['pp-userid'] = self.user_id
|
||||
append_data = {
|
||||
'access_token':self.access_token,
|
||||
'user_id':self.user_id
|
||||
}
|
||||
access_token_li.append(append_data)
|
||||
# print(f'账号【{self.index}】access_token:{self.access_token}')
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
except requests.exceptions.HTTPError as http_err:
|
||||
Log(f"HTTP请求出错: {http_err}")
|
||||
except requests.exceptions.ConnectionError as conn_err:
|
||||
Log(f"网络连接出错: {conn_err}")
|
||||
except requests.exceptions.Timeout as timeout_err:
|
||||
Log(f"请求超时: {timeout_err}")
|
||||
except requests.exceptions.RequestException as req_err:
|
||||
Log(f"出现了一个意外的请求错误: {req_err}")
|
||||
except json.JSONDecodeError as json_err:
|
||||
Log(f"JSON解码错误: {json_err}")
|
||||
return False
|
||||
|
||||
|
||||
def getUserInfo(self):
|
||||
global inviteCode
|
||||
Log(f'>>>>>>获取用户信息')
|
||||
url = "https://cauth.pupuapi.com/clientauth/user/info"
|
||||
|
||||
# response = self.do_request(url, headers=headers,req_type='get')
|
||||
response = self.make_request(url,method='get')
|
||||
# print(response)
|
||||
if 'errcode' in response and response.get('errcode', '') == 0:
|
||||
data = response.get('data')
|
||||
self.user_id = data.get('user_id')
|
||||
phone_number = data['phone']
|
||||
self.phone = phone_number[:3] + '****' + phone_number[7:]
|
||||
self.invite_code = data['invite_code']
|
||||
Log(f'手机号:【{self.phone}】')
|
||||
print(f'用户ID:【{self.user_id}】\n邀请码:【{self.invite_code}】')
|
||||
# new_data = {
|
||||
# self.user_id:
|
||||
# {
|
||||
# 'phone': self.phone,
|
||||
# 'invite_code': self.invite_code
|
||||
# }
|
||||
# }
|
||||
# CHERWIN_TOOLS.SAVE_INVITE_CODE("INVITE_CODE/PPCS_INVITE_CODE.json", new_data)
|
||||
return True
|
||||
else:
|
||||
Log(f'>获取用户信息失败')
|
||||
print(response)
|
||||
return False
|
||||
|
||||
def signStu(self):
|
||||
Log(f'>>>>>>获取签到状态')
|
||||
url = 'https://j1.pupuapi.com/client/game/sign/v2/index'
|
||||
try:
|
||||
result = self.make_request(url, 'get')
|
||||
errcode = result.get('errcode', 1)
|
||||
if errcode == 0:
|
||||
data = result.get('data', {})
|
||||
is_signed = data.get('is_signed', 0)
|
||||
if is_signed:
|
||||
Log('今天已签到')
|
||||
else:
|
||||
self.sign()
|
||||
else:
|
||||
errmsg = result.get('errmsg', '')
|
||||
print('查询签到信息失败[{}]: {}'.format(errcode, errmsg))
|
||||
except Exception as e:
|
||||
print('签到索引过程中发生错误: {}'.format(e))
|
||||
|
||||
def getCoinInfo(self):
|
||||
url = "https://j1.pupuapi.com/client/coin"
|
||||
# response = self.do_request(url, req_type='get')
|
||||
response = self.make_request(url,method='get')
|
||||
# print(response)
|
||||
if 'errcode' in response and response.get('errcode', '') == 0:
|
||||
data = response.get('data')
|
||||
# 当前朴分
|
||||
coin = data['balance']
|
||||
Log(f'当前朴分:【{coin}】')
|
||||
else:
|
||||
Log(f'>获取当前朴分失败')
|
||||
print(response)
|
||||
|
||||
|
||||
|
||||
def sign(self):
|
||||
Log(f'>>>>>>开始签到')
|
||||
url = "https://j1.pupuapi.com/client/game/sign/v2?supplement_id="
|
||||
# 签到
|
||||
data = {'supplement_id': ''}
|
||||
try:
|
||||
result = self.make_request(url, 'post', data=data)
|
||||
errcode = result.get('errcode', 1)
|
||||
if errcode == 0:
|
||||
data = result.get('data', {})
|
||||
daily_sign_coin = data.get('daily_sign_coin', 0)
|
||||
coupon_list = data.get('coupon_list', [])
|
||||
|
||||
rewards = [str(daily_sign_coin) + '积分']
|
||||
for coupon in coupon_list:
|
||||
condition_amount = '{:.2f}'.format(coupon['condition_amount'] / 100)
|
||||
discount_amount = '{:.2f}'.format(coupon['discount_amount'] / 100)
|
||||
rewards.append('满{}减{}券'.format(condition_amount, discount_amount))
|
||||
Log('签到成功: ' + ', '.join(rewards))
|
||||
else:
|
||||
errmsg = result.get('errmsg', '')
|
||||
Log('签到失败[{}]: {}'.format(errcode, errmsg))
|
||||
except Exception as e:
|
||||
Log('签到过程中发生错误: {}'.format(e))
|
||||
|
||||
# 发起组队
|
||||
def creatTeam(self):
|
||||
global inviteCode
|
||||
Log(f'>>>>>>开始发起组队')
|
||||
url = "https://j1.pupuapi.com/client/game/coin_share/team"
|
||||
response = self.make_request(url)
|
||||
# print(response)
|
||||
if 'errcode' in response and response.get('errcode', '') == 0:
|
||||
data = response.get('data')
|
||||
self.teamId = data
|
||||
Log(f'>发起组队成功,ID:【{data}】')
|
||||
return True
|
||||
elif 'errcode' in response and response.get('errcode', '') != 0:
|
||||
Log(f'>发起组队失败:【{response.get("errmsg", "")}】')
|
||||
else:
|
||||
Log(f'>发起组队失败')
|
||||
print(response)
|
||||
return False
|
||||
|
||||
def get_myTeam(self):
|
||||
Log(f'>>>>>>开始查询历史组队')
|
||||
# 获取当前日期
|
||||
today = datetime.now().date()
|
||||
# 构建当天的23:59:59时间
|
||||
end_of_day = datetime.combine(today, datetime.max.time()) + timedelta(hours=23, minutes=59, seconds=59)
|
||||
# 将时间转换为时间戳(毫秒为单位)
|
||||
timestamp = int(end_of_day.timestamp() * 1000)
|
||||
# 将日期格式化为字符串
|
||||
formatted_date = today.strftime("%Y-%m-%d")
|
||||
# print(timestamp)
|
||||
# print(formatted_date)
|
||||
url = f'https://j1.pupuapi.com/client/game/coin_share/records?time_from=1704038400000&time_to={timestamp}&page=1&size=20'
|
||||
try:
|
||||
result = self.make_request(url,method='get')
|
||||
errcode = result.get('errcode', -1)
|
||||
isCreatTeam = False
|
||||
if errcode == 0:
|
||||
data = result.get('data',[{}])
|
||||
for team in data:
|
||||
# print(team)
|
||||
record_type = team.get('record_type','')
|
||||
time_create = team.get('time_create','')
|
||||
# 将时间戳转换为 datetime 对象
|
||||
timestamp = time_create / 1000 # 将时间戳转换为秒
|
||||
dt = datetime.fromtimestamp(timestamp)
|
||||
# 将日期格式化为字符串
|
||||
formatted_time_create = dt.strftime("%Y-%m-%d")
|
||||
team_id = team.get('team_id','')
|
||||
# print(record_type)
|
||||
# print(formatted_time_create)
|
||||
# print(team_id)
|
||||
if record_type == 0 and formatted_time_create == formatted_date:
|
||||
self.teamId = team_id
|
||||
isCreatTeam =True
|
||||
break
|
||||
if isCreatTeam:
|
||||
Log(f'今日已创建ID:【{self.teamId}】队伍')
|
||||
self.check_my_team()
|
||||
else:
|
||||
self.creatTeam()
|
||||
else:
|
||||
errmsg = result.get('errmsg', '')
|
||||
print(f'查询组队历史信息失败[{errcode}]: {errmsg}')
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
|
||||
def check_my_team(self):
|
||||
Log(f'>>>>>>开始查询组队详情')
|
||||
url = f'https://j1.pupuapi.com/client/game/coin_share/teams/{self.teamId}'
|
||||
try:
|
||||
result = self.make_request(url,method='get')
|
||||
errcode = result.get('errcode', -1)
|
||||
if errcode == 0:
|
||||
data = result.get('data')
|
||||
status = data.get('status')
|
||||
if status == 10:
|
||||
self.team_need_help = True
|
||||
self.team_max_help = data.get('target_team_member_num')
|
||||
self.team_helped_count = data.get('current_team_member_num')
|
||||
Log(f'组队未完成: {self.team_helped_count}/{self.team_max_help}')
|
||||
elif status == 30:
|
||||
self.team_need_help = False
|
||||
coins = data.get('current_user_reward_coin')
|
||||
Log(f'已组队成功, 获得了{coins}积分')
|
||||
else:
|
||||
Log(f'组队状态[{status}]')
|
||||
print(f': {json.dumps(data)}')
|
||||
else:
|
||||
errmsg = result.get('errmsg', '')
|
||||
print(f'查询组队信息失败[{errcode}]: {errmsg}')
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
# 组队
|
||||
def joinAuthorTeam(self):
|
||||
Log(f'>>>>>>第1个账号开始助力作者')
|
||||
if len(AuthorCode) > 0:
|
||||
for code in AuthorCode:
|
||||
# print(code['teamId'])
|
||||
url = f"https://j1.pupuapi.com/client/game/coin_share/teams/{code['teamId']}/join"
|
||||
response = self.make_request(url)
|
||||
# print(response)
|
||||
if 'errcode' in response and response.get('errcode', '') == 0:
|
||||
print(f'>入队成功:【{code}】')
|
||||
break
|
||||
# elif 'errcode' in response and response.get('errcode', '') != 0:
|
||||
# print(f'>入队失败:【{response.get("errmsg", "")}】')
|
||||
# else:
|
||||
# print(f'>入队失败')
|
||||
# print(response)
|
||||
# 组队
|
||||
def joinTeam(self):
|
||||
global inviteCode
|
||||
Log(f'>>>>>>开始本地组队')
|
||||
with open('INVITE_CODE/PPCS_INVITE_CODE.json', 'r') as file:
|
||||
data = json.load(file)
|
||||
inviteCode = list(data.values())
|
||||
for code in inviteCode:
|
||||
teamId = code.get('teamId',False)
|
||||
if not teamId:continue
|
||||
url = f"https://j1.pupuapi.com/client/game/coin_share/teams/{code['teamId']}/join"
|
||||
response = self.make_request(url)
|
||||
# print(response)
|
||||
if 'errcode' in response and response.get('errcode', '') == 0:
|
||||
Log(f">入队成功:【{code['teamId']}】")
|
||||
elif 'errcode' in response and response.get('errcode', '') != 0:
|
||||
Log(f'>入队失败:【{response.get("errmsg", "")}】')
|
||||
else:
|
||||
Log(f'>入队失败')
|
||||
print(response)
|
||||
|
||||
def main(self):
|
||||
# print(self.refresh_token)
|
||||
if self.get_AccessToken():
|
||||
print('成功获取了access token.')
|
||||
self.getUserInfo()
|
||||
self.signStu()
|
||||
self.getCoinInfo()
|
||||
self.get_myTeam()
|
||||
new_data = {
|
||||
self.user_id:
|
||||
{
|
||||
'phone': self.phone,
|
||||
'invite_code': self.invite_code
|
||||
}
|
||||
}
|
||||
if self.teamId:new_data[self.user_id]['teamId']=self.teamId
|
||||
CHERWIN_TOOLS.SAVE_INVITE_CODE("INVITE_CODE/PPCS_INVITE_CODE.json", new_data)
|
||||
return True
|
||||
else:
|
||||
Log( f'账号[{self.index}] {CK_NAME}:\n【{self.refresh_token}】\n已失效请及时更新')
|
||||
return False
|
||||
self.sendMsg()
|
||||
|
||||
def help(self):
|
||||
if self.get_AccessToken():
|
||||
|
||||
if self.index == 1:
|
||||
Log('--------签到组队--------')
|
||||
self.joinAuthorTeam()
|
||||
else:
|
||||
Log('--------签到组队--------')
|
||||
self.joinTeam()
|
||||
return True
|
||||
else:
|
||||
Log(f'账号[{self.index}] {CK_NAME}:\n【{self.refresh_token}】\n已失效请及时更新')
|
||||
return False
|
||||
self.sendMsg(True)
|
||||
|
||||
def sendMsg(self, help=False):
|
||||
if self.send_UID:
|
||||
push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME, help)
|
||||
print(push_res)
|
||||
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
|
||||
def import_Tools():
|
||||
global CHERWIN_TOOLS,ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode
|
||||
import CHERWIN_TOOLS
|
||||
ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME,local_version)
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP_NAME = '朴朴超市'
|
||||
ENV_NAME = 'PPCS'
|
||||
CK_NAME = 'refresh_token'
|
||||
print(f'''
|
||||
✨✨✨ 朴朴超市脚本✨✨✨
|
||||
✨ 功能:
|
||||
积分签到
|
||||
组队互助
|
||||
✨ 抓包步骤:
|
||||
打开朴朴超市APP
|
||||
已登录先退出
|
||||
打开抓包
|
||||
登陆
|
||||
找https://cauth.pupuapi.com/clientauth/user/verify_login
|
||||
复制返回body中的{CK_NAME}
|
||||
多个账号可清理APP数据进行换号别点退出否则token失效
|
||||
✨ 设置青龙变量:
|
||||
export {ENV_NAME}= 'E0oXq3++6a4LG4xxxxxxxx'多账号#分割
|
||||
export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
✨ 多账号默认第一个账号与作者组队,其余互助
|
||||
✨ 推荐定时:0 9 * * *
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
|
||||
local_script_name = os.path.basename(__file__)
|
||||
local_version = '2024.04.06'
|
||||
if os.path.isfile('CHERWIN_TOOLS.py'):
|
||||
import_Tools()
|
||||
else:
|
||||
if down_file('CHERWIN_TOOLS.py', 'https://py.cherwin.cn/CHERWIN_TOOLS.py'):
|
||||
print('脚本依赖下载完成请重新运行脚本')
|
||||
import_Tools()
|
||||
else:
|
||||
print('脚本依赖下载失败,请到https://py.cherwin.cn/CHERWIN_TOOLS.py下载最新版本依赖')
|
||||
exit()
|
||||
print(TIPS)
|
||||
token = ''
|
||||
token = ENV if ENV else token
|
||||
if not token:
|
||||
print(f"未填写{ENV_NAME}变量\n青龙可在环境变量设置 {ENV_NAME} 或者在本脚本文件上方将{CK_NAME}填入token =''")
|
||||
exit()
|
||||
tokens = CHERWIN_TOOLS.ENV_SPLIT(token)
|
||||
# print(tokens)
|
||||
if len(tokens) > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<")
|
||||
access_token_li=[]
|
||||
for index, infos in enumerate(tokens):
|
||||
run_result = RUN(infos, index).main()
|
||||
if not run_result: continue
|
||||
|
||||
for index, infos in enumerate(tokens):
|
||||
RUN(infos, index).help()
|
||||
if not run_result: continue
|
||||
if send: send(f'{APP_NAME}挂机通知', send_msg + TIPS_HTML)
|
||||
|
||||
|
||||
280
TYYP.py
Executable file
280
TYYP.py
Executable file
@ -0,0 +1,280 @@
|
||||
# !/usr/bin/python3
|
||||
# -- coding: utf-8 --
|
||||
# -------------------------------
|
||||
# const $ = new Env('天翼云盘签到');
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import requests
|
||||
import rsa
|
||||
from os import path
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
# import CHERWIN_TOOLS
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
if os.path.isfile('notify.py'):
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
else:
|
||||
print("加载通知服务失败!")
|
||||
send_msg = ''
|
||||
one_msg=''
|
||||
def Log(cont=''):
|
||||
global send_msg,one_msg
|
||||
print(cont)
|
||||
if cont:
|
||||
one_msg += f'{cont}\n'
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
class RUN:
|
||||
def __init__(self,info,index):
|
||||
global one_msg
|
||||
one_msg = ''
|
||||
split_info = info.split('@')
|
||||
self.userid = split_info[0]
|
||||
self.pwd = split_info[1]
|
||||
len_split_info = len(split_info)
|
||||
last_info = split_info[len_split_info - 1]
|
||||
self.send_UID = None
|
||||
if len_split_info > 0 and "UID_" in last_info:
|
||||
print('检测到设置了UID')
|
||||
print(last_info)
|
||||
self.send_UID = last_info
|
||||
self.index = index + 1
|
||||
|
||||
self.b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
self.UA = 'Mozilla/5.0 (Linux; Android 5.1.1; SM-G930K Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Ecloud/8.6.3 Android/22 clientId/355325117317828 clientModel/SM-G930K imsi/460071114317824 clientChannelId/qq proVersion/1.0.6'
|
||||
self.headers = {
|
||||
'User-Agent': self.UA,
|
||||
"Referer": "https://m.cloud.189.cn/zhuanti/2016/sign/index.jsp?albumBackupOpened=1",
|
||||
"Host": "m.cloud.189.cn",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def int2char(a):
|
||||
return list("0123456789abcdefghijklmnopqrstuvwxyz")[a]
|
||||
|
||||
def b64tohex(self, a):
|
||||
d = ""
|
||||
e = 0
|
||||
c = 0
|
||||
for i in range(len(a)):
|
||||
if list(a)[i] != "=":
|
||||
v = self.b64map.index(list(a)[i])
|
||||
if e == 0:
|
||||
e = 1
|
||||
d += self.int2char(v >> 2)
|
||||
c = 3 & v
|
||||
elif e == 1:
|
||||
e = 2
|
||||
d += self.int2char(c << 2 | v >> 4)
|
||||
c = 15 & v
|
||||
elif e == 2:
|
||||
e = 3
|
||||
d += self.int2char(c)
|
||||
d += self.int2char(v >> 2)
|
||||
c = 3 & v
|
||||
else:
|
||||
e = 0
|
||||
d += self.int2char(c << 2 | v >> 4)
|
||||
d += self.int2char(15 & v)
|
||||
if e == 1:
|
||||
d += self.int2char(c << 2)
|
||||
return d
|
||||
|
||||
def rsa_encode(self, j_rsakey, string):
|
||||
rsa_key = f"-----BEGIN PUBLIC KEY-----\n{j_rsakey}\n-----END PUBLIC KEY-----"
|
||||
pubkey = rsa.PublicKey.load_pkcs1_openssl_pem(rsa_key.encode())
|
||||
return self.b64tohex(
|
||||
(base64.b64encode(rsa.encrypt(f"{string}".encode(), pubkey))).decode()
|
||||
)
|
||||
|
||||
def login(self):
|
||||
# https://m.cloud.189.cn/login2014.jsp?redirectURL=https://m.cloud.189.cn/zhuanti/2021/shakeLottery/index.html
|
||||
url = ""
|
||||
urlToken = "https://m.cloud.189.cn/udb/udb_login.jsp?pageId=1&pageKey=default&clientType=wap&redirectURL=https://m.cloud.189.cn/zhuanti/2021/shakeLottery/index.html"
|
||||
r = s.get(urlToken)
|
||||
pattern = r"https?://[^\s'\"]+" # 匹配以http或https开头的url
|
||||
match = re.search(pattern, r.text) # 在文本中搜索匹配
|
||||
if match: # 如果找到匹配
|
||||
url = match.group() # 获取匹配的字符串
|
||||
# print(url) # 打印url
|
||||
else: # 如果没有找到匹配
|
||||
print("没有找到url")
|
||||
|
||||
r = s.get(url)
|
||||
# print(r.text)
|
||||
pattern = r"<a id=\"j-tab-login-link\"[^>]*href=\"([^\"]+)\"" # 匹配id为j-tab-login-link的a标签,并捕获href引号内的内容
|
||||
match = re.search(pattern, r.text) # 在文本中搜索匹配
|
||||
if match: # 如果找到匹配
|
||||
href = match.group(1) # 获取捕获的内容
|
||||
r = s.get(href)
|
||||
# print("href:" + href) # 打印href链接
|
||||
else: # 如果没有找到匹配
|
||||
print("没有找到href链接")
|
||||
exit()
|
||||
|
||||
captchaToken = re.findall(r"captchaToken' value='(.+?)'", r.text)[0]
|
||||
lt = re.findall(r'lt = "(.+?)"', r.text)[0]
|
||||
returnUrl = re.findall(r"returnUrl= '(.+?)'", r.text)[0]
|
||||
paramId = re.findall(r'paramId = "(.+?)"', r.text)[0]
|
||||
j_rsakey = re.findall(r'j_rsaKey" value="(\S+)"', r.text, re.M)[0]
|
||||
s.headers.update({"lt": lt})
|
||||
|
||||
username = self.rsa_encode(j_rsakey, self.userid)
|
||||
password = self.rsa_encode(j_rsakey, self.pwd)
|
||||
url = "https://open.e.189.cn/api/logbox/oauth2/loginSubmit.do"
|
||||
headers = {
|
||||
'User-Agent': self.UA,
|
||||
'Referer': 'https://open.e.189.cn/',
|
||||
}
|
||||
data = {
|
||||
"appKey": "cloud",
|
||||
"accountType": '01',
|
||||
"userName": f"{{RSA}}{username}",
|
||||
"password": f"{{RSA}}{password}",
|
||||
"validateCode": "",
|
||||
"captchaToken": captchaToken,
|
||||
"returnUrl": returnUrl,
|
||||
"mailSuffix": "@189.cn",
|
||||
"paramId": paramId
|
||||
}
|
||||
r = s.post(url, data=data, headers=headers, timeout=5)
|
||||
if (r.json()['result'] == 0):
|
||||
Log('登陆成功!')
|
||||
print(r.json()['msg'])
|
||||
else:
|
||||
Log('登陆失败!')
|
||||
print(r.json()['msg'])
|
||||
redirect_url = r.json()['toUrl']
|
||||
r = s.get(redirect_url)
|
||||
if r.status_code == 200:
|
||||
return r
|
||||
else:
|
||||
return False
|
||||
|
||||
def signIn(self):
|
||||
Log('>>>>>>签到')
|
||||
rand = str(round(time.time() * 1000))
|
||||
# print(rand)
|
||||
surl = f'https://api.cloud.189.cn/mkt/userSign.action?rand={rand}&clientType=TELEANDROID&version=8.6.3&model=SM-G930K'
|
||||
|
||||
response = s.get(surl, headers=self.headers)
|
||||
netdiskBonus = response.json()['netdiskBonus']
|
||||
if (response.json().get('isSign','false') == "false"):
|
||||
Log(f"未签到,签到获得{netdiskBonus}M空间\n")
|
||||
else:
|
||||
Log(f"已经签到过了,签到获得{netdiskBonus}M空间\n")
|
||||
|
||||
def lottery(self):
|
||||
Log('>>>>>>抽奖')
|
||||
url_list = ['https://m.cloud.189.cn/v2/drawPrizeMarketDetails.action?taskId=TASK_SIGNIN&activityId=ACT_SIGNIN',
|
||||
'https://m.cloud.189.cn/v2/drawPrizeMarketDetails.action?taskId=TASK_SIGNIN_PHOTOS&activityId=ACT_SIGNIN',
|
||||
'https://m.cloud.189.cn/v2/drawPrizeMarketDetails.action?taskId=TASK_2022_FLDFS_KJ&activityId=ACT_SIGNIN']
|
||||
for index, urls in enumerate(url_list):
|
||||
response = s.get(urls, headers=self.headers)
|
||||
if ("errorCode" in response.text):
|
||||
Log(f"链接{index + 1}抽奖失败")
|
||||
print(response.text)
|
||||
else:
|
||||
description = response.json()['prizeName']
|
||||
Log(f"链接{index + 1}抽奖获得{description}\n")
|
||||
|
||||
def main(self):
|
||||
Log(f"\n开始执行第{self.index}个账号【{self.userid[-4:]}】--------------->>>>>")
|
||||
if not self.login():
|
||||
print(f'\n第{self.index}个账号【{self.userid[-4:]}登陆失败!')
|
||||
return False
|
||||
self.signIn()
|
||||
self.lottery()
|
||||
self.sendMsg()
|
||||
return True
|
||||
|
||||
def sendMsg(self):
|
||||
if self.send_UID:
|
||||
push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME)
|
||||
print(push_res)
|
||||
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
|
||||
def import_Tools():
|
||||
global CHERWIN_TOOLS,ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode
|
||||
import CHERWIN_TOOLS
|
||||
ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME,local_version)
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP_NAME = '天翼云盘'
|
||||
ENV_NAME = 'TYYP'
|
||||
CK_NAME = '手机号@密码'
|
||||
print(f'''
|
||||
✨✨✨ {APP_NAME}签到抽奖✨✨✨
|
||||
✨ 功能:
|
||||
签到
|
||||
抽奖
|
||||
参数示例:18888888888@123456
|
||||
✨ 设置青龙变量:
|
||||
export {ENV_NAME}='{CK_NAME}参数值'多账号#或&分割
|
||||
export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
✨ 推荐cron:0 9 * * *
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
local_script_name = os.path.basename(__file__)
|
||||
local_version = '2024.04.06'
|
||||
if os.path.isfile('CHERWIN_TOOLS.py'):
|
||||
import_Tools()
|
||||
else:
|
||||
if down_file('CHERWIN_TOOLS.py', 'https://py.cherwin.cn/CHERWIN_TOOLS.py'):
|
||||
print('脚本依赖下载完成请重新运行脚本')
|
||||
import_Tools()
|
||||
else:
|
||||
print('脚本依赖下载失败,请到https://py.cherwin.cn/CHERWIN_TOOLS.py下载最新版本依赖')
|
||||
exit()
|
||||
print(TIPS)
|
||||
token = ''
|
||||
token = ENV if ENV else token
|
||||
if not token:
|
||||
print(f"未填写{ENV_NAME}变量\n青龙可在环境变量设置 {ENV_NAME} 或者在本脚本文件上方将{CK_NAME}填入token =''")
|
||||
exit()
|
||||
tokens = CHERWIN_TOOLS.ENV_SPLIT(token)
|
||||
# print(tokens)
|
||||
if len(tokens) > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<")
|
||||
access_token = []
|
||||
for index, infos in enumerate(tokens):
|
||||
s = requests.session()
|
||||
s.verify=False
|
||||
run_result = RUN(infos, index).main()
|
||||
if not run_result: continue
|
||||
if send: send(f'{APP_NAME}挂机通知', send_msg + TIPS_HTML)
|
||||
368
YDKD.py
Executable file
368
YDKD.py
Executable file
@ -0,0 +1,368 @@
|
||||
# !/usr/bin/python3
|
||||
# -- coding: utf-8 --
|
||||
# -------------------------------
|
||||
# @Author : cherwin
|
||||
# ✨✨✨ 韵达快递小程序签到✨✨✨
|
||||
# ✨ 功能:
|
||||
# 积分签到
|
||||
# ✨ 抓包步骤:
|
||||
# 打开韵达快递小程序
|
||||
# 授权登陆
|
||||
# 打开抓包工具
|
||||
# 找URl请求头带openID
|
||||
# 复制里面的openID参数值
|
||||
# 参数示例:at965eoakumxxxxxxxx
|
||||
# ✨ 设置青龙变量:
|
||||
# export YDKD='openID参数值'多账号#或&分割
|
||||
# export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
# ✨ ✨ 注意:抓完CK没事儿别打开小程序,重新打开小程序请重新抓包
|
||||
# ✨ 推荐cron:0 6 * * *
|
||||
# ✨✨✨ @Author CHERWIN✨✨✨
|
||||
# -------------------------------
|
||||
# cron "30 6 * * *" script-path=xxx.py,tag=匹配cron用
|
||||
# const $ = new Env('韵达快递小程序签到')
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
from os import path
|
||||
import requests
|
||||
import hashlib
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
# import CHERWIN_TOOLS
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
if os.path.isfile('notify.py'):
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
else:
|
||||
print("加载通知服务失败!")
|
||||
send_msg = ''
|
||||
one_msg=''
|
||||
def Log(cont=''):
|
||||
global send_msg,one_msg
|
||||
print(cont)
|
||||
if cont:
|
||||
one_msg += f'{cont}\n'
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
class RUN:
|
||||
def __init__(self,info,index):
|
||||
global one_msg
|
||||
one_msg = ''
|
||||
split_info = info.split('@')
|
||||
self.token = split_info[0]
|
||||
len_split_info = len(split_info)
|
||||
last_info = split_info[len_split_info - 1]
|
||||
self.send_UID = None
|
||||
if len_split_info > 0 and "UID_" in last_info:
|
||||
print('检测到设置了UID')
|
||||
print(last_info)
|
||||
self.send_UID = last_info
|
||||
self.index = index + 1
|
||||
self.headers = {
|
||||
'Host': 'op.yundasys.com',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'Authorization': self.token,
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF XWEB/6945',
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Sec-Fetch-Site': 'same-origin',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
'Sec-Fetch-Dest': 'empty',
|
||||
'Referer': 'https://op.yundasys.com/mb-ext-channel/index.html',
|
||||
'Accept-Language': 'zh-CN,zh'
|
||||
}
|
||||
|
||||
self.baseUrl = 'https://op.yundasys.com/gateway/ydmb-integral/ydintegral/'
|
||||
self.news_List = []
|
||||
self.list_index = 0
|
||||
self.isFirstTask = True
|
||||
|
||||
def get_point(self):
|
||||
Log('>>>>>>获取积分信息')
|
||||
json_data = {
|
||||
"channelId": "wxapp",
|
||||
"reqTime": int(time.time()),
|
||||
"accountSrc": "wxapp",
|
||||
"accountId": self.token
|
||||
}
|
||||
response = s.post(f'{self.baseUrl}member/integral/info', headers=self.headers,json=json_data)
|
||||
point_info = response.json()
|
||||
# print(point_info)
|
||||
if point_info['code']== 200:
|
||||
point=point_info['data']['total']
|
||||
userId=point_info['data']['userId']
|
||||
Log(f'>>当前用户:【{userId}】')
|
||||
Log(f'>>当前积分:【{point}】')
|
||||
return True
|
||||
else:
|
||||
Log('可能token失效了')
|
||||
return False
|
||||
|
||||
def sign(self):
|
||||
Log('>>>>>>签到')
|
||||
json_data = {
|
||||
'channelId': 'wxapp',
|
||||
'itgType': 'sign',
|
||||
'reqTime': int(time.time()),
|
||||
'accountSrc': 'wxapp',
|
||||
'accountId': self.token
|
||||
}
|
||||
response = s.post(f'{self.baseUrl}obtain/event/integral', headers=self.headers,json=json_data)
|
||||
point_info = response.json()
|
||||
# print(point_info)
|
||||
if point_info['code']== 200:
|
||||
msg=point_info['message']
|
||||
Log(f'>>签到成功,,{msg}')
|
||||
else:
|
||||
print(f">>{point_info['message']}")
|
||||
# print(response.text)
|
||||
def get_TaskList(self):
|
||||
Log('>>>>>>获取任务列表')
|
||||
json_data ={
|
||||
"channelId": "wxapp",
|
||||
"pageNum": 1,
|
||||
"pageSize": 100,
|
||||
"businessType": "goldBetter",
|
||||
"reqTime": int(time.time()),
|
||||
"accountSrc": "wxapp",
|
||||
"accountId": self.token
|
||||
}
|
||||
response = s.post(f'{self.baseUrl}integral/event/list', headers=self.headers,json=json_data)
|
||||
# try:
|
||||
json_data = response.json()
|
||||
# print(json_data)
|
||||
skip_type=['关注公众号','实名认证','完善个人信息','累计消耗积分','寄快递','购买超级会员','兑换商品']
|
||||
complete = {}
|
||||
if json_data['message'] == '请求成功':
|
||||
data=json_data['data']
|
||||
list = data['items']
|
||||
for i in list:
|
||||
eventStatus = i['eventStatus']
|
||||
eventCode = i['eventCode']
|
||||
#可完成次数
|
||||
surplusCount = i['surplusCount']
|
||||
title = i['eventName']
|
||||
if title == '本月寄满3件': surplusCount = 1
|
||||
if title in skip_type:continue
|
||||
stu = {"0":"已完成","1":"未完成"}
|
||||
Log(f'当前任务【{title}】,{stu[eventStatus]}')
|
||||
for t in range(surplusCount):
|
||||
if eventStatus != "1" :
|
||||
self.doTask(eventCode,title)
|
||||
if title == '观看精彩视频':
|
||||
self.watchAd(title)
|
||||
else:
|
||||
complete[title] = 0
|
||||
time.sleep(2)
|
||||
time.sleep(2)
|
||||
|
||||
if all(value == 0 for value in complete.values()):
|
||||
Log(">>>任务已全部完成")
|
||||
return True
|
||||
# print(f'>>当前积分:【{point}】')
|
||||
# except:
|
||||
# print(response.text)
|
||||
def watchAd(self,title):
|
||||
json_data = {
|
||||
"action":"ydmbintegral.ydintegral.obtain.event.integral",
|
||||
"appid":"wjvxmno358lze827",
|
||||
"req_time":int(time.time()),
|
||||
"options":"false",
|
||||
"data":{
|
||||
"accountId":self.token,
|
||||
"accountSrc":"wxapp",
|
||||
"reqTime":int(time.time()),"itgType":"wechat_viewadv"
|
||||
},
|
||||
"version":"V1.0"}
|
||||
response = s.post(f'{self.baseUrl}obtain/event/integral', headers=self.headers, json=json_data)
|
||||
point_info = response.json()
|
||||
# print(point_info)
|
||||
if point_info['code'] == 200:
|
||||
msg = point_info['message']
|
||||
print(f'>>{title},{msg}')
|
||||
else:
|
||||
print(f">>{title},{point_info['message']}")
|
||||
|
||||
def doTask(self,eventCode,title):
|
||||
json_data = {
|
||||
'channelId': 'wxapp',
|
||||
'itgType': f'{eventCode}',
|
||||
'reqTime': int(time.time()),
|
||||
'accountSrc': 'wxapp',
|
||||
'accountId': self.token
|
||||
}
|
||||
response = s.post(f'{self.baseUrl}obtain/event/integral', headers=self.headers, json=json_data)
|
||||
point_info = response.json()
|
||||
# print(point_info)
|
||||
if point_info['code'] == 200:
|
||||
msg = point_info['message']
|
||||
print(f'>>{title},{msg}')
|
||||
else:
|
||||
print(f">>{title},{point_info['message']}")
|
||||
|
||||
def getDrawInfo(self):
|
||||
self.DrawHeaders = {
|
||||
'Host': 'op.yundasys.com',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'Authorization': self.token,
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF XWEB/8259',
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Sec-Fetch-Site': 'same-origin',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
'Sec-Fetch-Dest': 'empty',
|
||||
'Referer': 'https://op.yundasys.com/mb-ext-channel/index.html',
|
||||
'Accept-Language': 'zh-CN,zh',
|
||||
}
|
||||
json_data = {
|
||||
"reqTime": int(time.time()),
|
||||
"accountId": self.token,
|
||||
"accountSrc": "wxapp"
|
||||
}
|
||||
response = s.post(f'https://op.yundasys.com/gateway/ydmbaccount/ydaccount/mc/Itg/store/token', headers=self.DrawHeaders, json=json_data)
|
||||
point_info = response.json()
|
||||
# print(point_info)
|
||||
if point_info['code'] == 200:
|
||||
data = point_info['data']
|
||||
if data:
|
||||
self.getDrawNumber(data)
|
||||
else:
|
||||
print(f">>{point_info['message']}")
|
||||
|
||||
def getDrawNumber(self,data):
|
||||
json_data = {
|
||||
'activityId': 16,
|
||||
'plum_session_applet': data,
|
||||
'suid': 'gmrtxvrye6',
|
||||
'mwl_client_flag': 'wxapp',
|
||||
}
|
||||
resp = s.post(f'https://op.yundasys.com/itgstoresys/api/lottery/drawNumber', headers=self.DrawHeaders, json=json_data)
|
||||
res_info = resp.json()
|
||||
if res_info['code'] == 200:
|
||||
freeDrawNumber = res_info['data']['freeDrawNumber']
|
||||
print(f'>>剩余免费抽奖次数:【{freeDrawNumber}】')
|
||||
if freeDrawNumber == 1:
|
||||
self.doDraw(data)
|
||||
|
||||
else:
|
||||
print(f">>{res_info['message']}")
|
||||
|
||||
def doDraw(self,data):
|
||||
res_data = {
|
||||
'activityId': 16,
|
||||
'plum_session_applet': data,
|
||||
'suid': 'gmrtxvrye6',
|
||||
'mwl_client_flag': 'wxapp',
|
||||
}
|
||||
resp = s.post(f'https://op.yundasys.com/itgstoresys/api/lottery/draw', headers=self.DrawHeaders, json=res_data)
|
||||
res_info = resp.json()
|
||||
if res_info['code'] == "200":
|
||||
msg = res_info['message']
|
||||
prizeName = res_info['data']['prizeName']
|
||||
Log(f'>>{msg},获得{prizeName}')
|
||||
else:
|
||||
Log(f">>{res_info['message']}")
|
||||
|
||||
|
||||
def main(self):
|
||||
Log(f"\n开始执行第{self.index}个账号--------------->>>>>")
|
||||
if not self.get_point():
|
||||
return False
|
||||
self.sign()
|
||||
self.get_TaskList()
|
||||
self.getDrawInfo()
|
||||
self.sendMsg()
|
||||
return True
|
||||
|
||||
def sendMsg(self):
|
||||
if self.send_UID:
|
||||
push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME)
|
||||
print(push_res)
|
||||
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
|
||||
def import_Tools():
|
||||
global CHERWIN_TOOLS,ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode
|
||||
import CHERWIN_TOOLS
|
||||
ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME,local_version)
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP_NAME = '韵达快递小程序'
|
||||
ENV_NAME = 'YDKD'
|
||||
CK_NAME = 'Authorization'
|
||||
print(f'''
|
||||
✨✨✨ {APP_NAME}签到✨✨✨
|
||||
✨ 功能:
|
||||
积分签到
|
||||
积分抽奖
|
||||
✨ 抓包步骤:
|
||||
打开{APP_NAME}
|
||||
授权登陆
|
||||
打开抓包工具
|
||||
找URl请求头带{CK_NAME}
|
||||
复制里面的{CK_NAME}参数值
|
||||
参数示例:oPJUI0eZ5cm8BpR7xxxx
|
||||
✨ 设置青龙变量:
|
||||
export {ENV_NAME}='{CK_NAME}参数值'多账号#或&分割
|
||||
export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
✨ ✨ 注意:抓完CK没事儿别打开小程序,重新打开小程序请重新抓包
|
||||
✨ 推荐cron:0 6 * * *
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
local_script_name = os.path.basename(__file__)
|
||||
local_version = '2024.04.06'
|
||||
if os.path.isfile('CHERWIN_TOOLS.py'):
|
||||
import_Tools()
|
||||
else:
|
||||
if down_file('CHERWIN_TOOLS.py', 'https://py.cherwin.cn/CHERWIN_TOOLS.py'):
|
||||
print('脚本依赖下载完成请重新运行脚本')
|
||||
import_Tools()
|
||||
else:
|
||||
print('脚本依赖下载失败,请到https://py.cherwin.cn/CHERWIN_TOOLS.py下载最新版本依赖')
|
||||
exit()
|
||||
print(TIPS)
|
||||
token = ''
|
||||
token = ENV if ENV else token
|
||||
if not token:
|
||||
print(f"未填写{ENV_NAME}变量\n青龙可在环境变量设置 {ENV_NAME} 或者在本脚本文件上方将{CK_NAME}填入token =''")
|
||||
exit()
|
||||
tokens = CHERWIN_TOOLS.ENV_SPLIT(token)
|
||||
# print(tokens)
|
||||
if len(tokens) > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<")
|
||||
access_token = []
|
||||
for index, infos in enumerate(tokens):
|
||||
s = requests.session()
|
||||
s.verify = False
|
||||
run_result = RUN(infos, index).main()
|
||||
if not run_result: continue
|
||||
if send: send(f'{APP_NAME}挂机通知', send_msg + TIPS_HTML)
|
||||
237
ZTKD.py
Executable file
237
ZTKD.py
Executable file
@ -0,0 +1,237 @@
|
||||
# !/usr/bin/python3
|
||||
# -- coding: utf-8 --
|
||||
# -------------------------------
|
||||
# ✨✨✨ 中通快递小程序签到✨✨✨
|
||||
# ✨ 功能:
|
||||
# 积分签到
|
||||
# ✨ 抓包步骤:
|
||||
# 打开中通快递小程序
|
||||
# 授权登陆
|
||||
# 打开抓包工具
|
||||
# 找URl请求头带[x-token或者token]
|
||||
# 复制里面的[x-token或者token]参数值
|
||||
# 参数示例:eyJhbGciOiJIUzUxMiJ9.eyJnZW5lcmF0ZVRpbWUixxxxxx
|
||||
# ✨ 设置青龙变量:
|
||||
# export YDKD='x-token或者token参数值'多账号#或&分割
|
||||
# export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
# ✨ ✨ 注意:抓完CK没事儿别打开小程序,重新打开小程序请重新抓包
|
||||
# ✨ 推荐cron:0 6 * * *
|
||||
# ✨✨✨ @Author CHERWIN✨✨✨
|
||||
# -------------------------------
|
||||
# cron "0 6 * * *" script-path=xxx.py,tag=匹配cron用
|
||||
# const $ = new Env('中通快递小程序签到')
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
from datetime import datetime, date
|
||||
from os import path
|
||||
import requests
|
||||
import hashlib
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
# import CHERWIN_TOOLS
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
#
|
||||
if os.path.isfile('DEV_ENV.py'):
|
||||
import DEV_ENV
|
||||
if os.path.isfile('notify.py'):
|
||||
from notify import send
|
||||
print("加载通知服务成功!")
|
||||
else:
|
||||
print("加载通知服务失败!")
|
||||
send_msg = ''
|
||||
one_msg=''
|
||||
def Log(cont=''):
|
||||
global send_msg,one_msg
|
||||
print(cont)
|
||||
if cont:
|
||||
one_msg += f'{cont}\n'
|
||||
send_msg += f'{cont}\n'
|
||||
|
||||
class RUN:
|
||||
def __init__(self,info,index):
|
||||
global one_msg
|
||||
one_msg = ''
|
||||
split_info = info.split('@')
|
||||
self.token = split_info[0]
|
||||
len_split_info = len(split_info)
|
||||
last_info = split_info[len_split_info - 1]
|
||||
self.send_UID = None
|
||||
if len_split_info > 0 and "UID_" in last_info:
|
||||
print('检测到设置了UID')
|
||||
print(last_info)
|
||||
self.send_UID = last_info
|
||||
self.index = index + 1
|
||||
|
||||
self.headers = {
|
||||
'Host': 'api.ztomember.com',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF XWEB/6945',
|
||||
'token': self.token,
|
||||
'Content-Type': 'application/json;charset=UTF-8',
|
||||
'Accept': '*/*',
|
||||
'Sec-Fetch-Site': 'same-site',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
'Sec-Fetch-Dest': 'empty',
|
||||
'Referer': 'https://h5.ztomember.com/',
|
||||
'Accept-Language': 'zh-CN,zh',
|
||||
|
||||
}
|
||||
|
||||
self.baseUrl = 'https://api.ztomember.com/api/'
|
||||
self.news_List = []
|
||||
self.list_index = 0
|
||||
self.isFirstTask = True
|
||||
|
||||
def get_point(self):
|
||||
Log('>>>>>>获取积分信息')
|
||||
json_data = {}
|
||||
response = s.post(f'{self.baseUrl}user/point/get', headers=self.headers,json=json_data)
|
||||
point_info = response.json()
|
||||
# print(point_info)
|
||||
code = point_info.get('code',-1)
|
||||
if point_info.get('success',False) == True and code == 10000:
|
||||
data = point_info.get('data',[{}])
|
||||
point=data.get('point',0)
|
||||
mobile=data.get('mobile','')
|
||||
mobile=mobile[:3] + "*" * 4 + mobile[7:]
|
||||
Log(f'>>当前用户:【{mobile}】')
|
||||
Log(f'>>当前积分:【{point}】')
|
||||
return True
|
||||
else:
|
||||
Log('可能token失效了')
|
||||
return False
|
||||
|
||||
def Check_sign(self):
|
||||
Log('>>>>>>查询签到')
|
||||
json_data = {"calendarType":0}
|
||||
response = s.post(f'{self.baseUrl}member/sign/v2/calendar', headers=self.headers,json=json_data)
|
||||
response = response.json()
|
||||
# print(point_info)
|
||||
code = response.get('code', -1)
|
||||
if response['success']== True and response['data'] != None and code == 10000:
|
||||
data=response.get('data',{})
|
||||
dayList=data.get('dayList',[{}])
|
||||
signDays=data.get('signDays',0)
|
||||
Len_dayList=len(dayList)
|
||||
dates = dayList[Len_dayList-1].get('date','')
|
||||
current_date = date.today()
|
||||
parsed_date = datetime.strptime(dates, '%Y-%m-%d').date()
|
||||
if parsed_date == current_date:
|
||||
Log(f'今日已签到,连续签到【{signDays}】天')
|
||||
else:
|
||||
self.sign()
|
||||
else:
|
||||
Log(f"查询签到失败,{response['msg']}")
|
||||
def sign(self):
|
||||
Log('>>>>>>签到')
|
||||
json_data = {}
|
||||
response = s.post(f'{self.baseUrl}member/sign/v2/userSignIn', headers=self.headers,json=json_data)
|
||||
point_info = response.json()
|
||||
# print(point_info)
|
||||
code = point_info.get('code', -1)
|
||||
if point_info['success']== True and point_info['data'] != None and code == 10000:
|
||||
point=point_info['data']['point']
|
||||
Log(f'>>签到成功获得:【{point}】积分')
|
||||
else:
|
||||
Log(f"签到失败,{point_info['msg']}")
|
||||
|
||||
|
||||
|
||||
def main(self):
|
||||
print(f"\n开始执行第{self.index}个账号--------------->>>>>")
|
||||
if self.get_point():
|
||||
self.Check_sign()
|
||||
self.get_point()
|
||||
time.sleep(2)
|
||||
self.sendMsg()
|
||||
else:
|
||||
return False
|
||||
|
||||
def sendMsg(self):
|
||||
if self.send_UID:
|
||||
push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME)
|
||||
print(push_res)
|
||||
|
||||
|
||||
def down_file(filename, file_url):
|
||||
print(f'开始下载:{filename},下载地址:{file_url}')
|
||||
try:
|
||||
response = requests.get(file_url, verify=False, timeout=10)
|
||||
response.raise_for_status()
|
||||
with open(filename + '.tmp', 'wb') as f:
|
||||
f.write(response.content)
|
||||
print(f'【{filename}】下载完成!')
|
||||
|
||||
# 检查临时文件是否存在
|
||||
temp_filename = filename + '.tmp'
|
||||
if os.path.exists(temp_filename):
|
||||
# 删除原有文件
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# 重命名临时文件
|
||||
os.rename(temp_filename, filename)
|
||||
print(f'【{filename}】重命名成功!')
|
||||
return True
|
||||
else:
|
||||
print(f'【{filename}】临时文件不存在!')
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f'【{filename}】下载失败:{str(e)}')
|
||||
return False
|
||||
|
||||
def import_Tools():
|
||||
global CHERWIN_TOOLS,ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode
|
||||
import CHERWIN_TOOLS
|
||||
ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME,local_version)
|
||||
|
||||
if __name__ == '__main__':
|
||||
APP_NAME = '中通快递小程序'
|
||||
ENV_NAME = 'ZTKD'
|
||||
CK_NAME = 'x-token或者token'
|
||||
print(f'''
|
||||
✨✨✨ {APP_NAME}签到✨✨✨
|
||||
✨ 功能:
|
||||
积分签到
|
||||
✨ 抓包步骤:
|
||||
打开{APP_NAME}
|
||||
授权登陆
|
||||
打开抓包工具
|
||||
找URl请求头带[{CK_NAME}]
|
||||
复制里面的[{CK_NAME}]参数值
|
||||
参数示例:eyJhbGciOiJIUzUxMiJ9.eyJnZW5lcmF0ZVRpbWUixxxxxx
|
||||
✨ 设置青龙变量:
|
||||
export {ENV_NAME}='{CK_NAME}参数值'多账号#或&分割
|
||||
export SCRIPT_UPDATE = 'False' 关闭脚本自动更新,默认开启
|
||||
✨ ✨ 注意:抓完CK没事儿别打开小程序,重新打开小程序请重新抓包
|
||||
✨ 推荐cron:0 6 * * *
|
||||
✨✨✨ @Author CHERWIN✨✨✨
|
||||
''')
|
||||
local_script_name = os.path.basename(__file__)
|
||||
local_version = '2024.04.06'
|
||||
if os.path.isfile('CHERWIN_TOOLS.py'):
|
||||
import_Tools()
|
||||
else:
|
||||
if down_file('CHERWIN_TOOLS.py', 'https://py.cherwin.cn/CHERWIN_TOOLS.py'):
|
||||
print('脚本依赖下载完成请重新运行脚本')
|
||||
import_Tools()
|
||||
else:
|
||||
print('脚本依赖下载失败,请到https://py.cherwin.cn/CHERWIN_TOOLS.py下载最新版本依赖')
|
||||
exit()
|
||||
print(TIPS)
|
||||
token = ''
|
||||
token = ENV if ENV else token
|
||||
if not token:
|
||||
print(f"未填写{ENV_NAME}变量\n青龙可在环境变量设置 {ENV_NAME} 或者在本脚本文件上方将{CK_NAME}填入token =''")
|
||||
exit()
|
||||
tokens = CHERWIN_TOOLS.ENV_SPLIT(token)
|
||||
# print(tokens)
|
||||
if len(tokens) > 0:
|
||||
print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<")
|
||||
access_token = []
|
||||
for index, infos in enumerate(tokens):
|
||||
s = requests.session()
|
||||
s.verify = False
|
||||
run_result = RUN(infos, index).main()
|
||||
if not run_result: continue
|
||||
if send: send(f'{APP_NAME}挂机通知', send_msg + TIPS_HTML)
|
||||
552
notify.py
Executable file
552
notify.py
Executable file
@ -0,0 +1,552 @@
|
||||
#!/usr/bin/env python3
|
||||
# _*_ coding:utf-8 _*_
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import threading
|
||||
import time
|
||||
import urllib.parse
|
||||
|
||||
import requests
|
||||
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
# 禁用安全请求警告
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
# 创建 session 对象,全局设置 verify=False
|
||||
session = requests.Session()
|
||||
session.verify = False
|
||||
|
||||
# 原先的 print 函数和主线程的锁
|
||||
_print = print
|
||||
mutex = threading.Lock()
|
||||
|
||||
|
||||
# 定义新的 print 函数
|
||||
def print(text, *args, **kw):
|
||||
"""
|
||||
使输出有序进行,不出现多线程同一时间输出导致错乱的问题。
|
||||
"""
|
||||
with mutex:
|
||||
_print(text, *args, **kw)
|
||||
|
||||
# 通知服务
|
||||
# fmt: off
|
||||
push_config = {
|
||||
'HITOKOTO': False, # 启用一言(随机句子)
|
||||
|
||||
'BARK_PUSH': '', # bark IP 或设备码,例:https://api.day.app/DxHcxxxxxRxxxxxxcm/
|
||||
'BARK_ARCHIVE': '', # bark 推送是否存档
|
||||
'BARK_GROUP': '', # bark 推送分组
|
||||
'BARK_SOUND': '', # bark 推送声音
|
||||
|
||||
'CONSOLE': True, # 控制台输出
|
||||
|
||||
'DD_BOT_SECRET': '', # 钉钉机器人的 DD_BOT_SECRET
|
||||
'DD_BOT_TOKEN': '', # 钉钉机器人的 DD_BOT_TOKEN
|
||||
|
||||
'FSKEY': '', # 飞书机器人的 FSKEY
|
||||
|
||||
'GOBOT_URL': '', # go-cqhttp
|
||||
# 推送到个人QQ:http://127.0.0.1/send_private_msg
|
||||
# 群:http://127.0.0.1/send_group_msg
|
||||
'GOBOT_QQ': '', # go-cqhttp 的推送群或用户
|
||||
# GOBOT_URL 设置 /send_private_msg 时填入 user_id=个人QQ
|
||||
# /send_group_msg 时填入 group_id=QQ群
|
||||
'GOBOT_TOKEN': '', # go-cqhttp 的 access_token
|
||||
|
||||
'GOTIFY_URL': '', # gotify地址,如https://push.example.de:8080
|
||||
'GOTIFY_TOKEN': '', # gotify的消息应用token
|
||||
'GOTIFY_PRIORITY': 0, # 推送消息优先级,默认为0
|
||||
|
||||
'IGOT_PUSH_KEY': '', # iGot 聚合推送的 IGOT_PUSH_KEY
|
||||
|
||||
'PUSH_KEY': '', # server 酱的 PUSH_KEY,兼容旧版与 Turbo 版
|
||||
|
||||
'PUSH_PLUS_TOKEN': '', # push+ 微信推送的用户令牌
|
||||
'PUSH_PLUS_USER': '', # push+ 微信推送的群组编码
|
||||
|
||||
'QMSG_KEY': '', # qmsg 酱的 QMSG_KEY
|
||||
'QMSG_TYPE': '', # qmsg 酱的 QMSG_TYPE
|
||||
|
||||
'QYWX_AM': '', # 企业微信应用
|
||||
|
||||
'QYWX_KEY': '', # 企业微信机器人
|
||||
|
||||
'TG_BOT_TOKEN': '', # tg 机器人的 TG_BOT_TOKEN,例:
|
||||
'TG_USER_ID': '', # tg 机器人的 TG_USER_ID,例:1434078534
|
||||
'TG_API_HOST': '', # tg 代理 api
|
||||
'TG_PROXY_AUTH': '', # tg 代理认证参数
|
||||
'TG_PROXY_HOST': '', # tg 机器人的 TG_PROXY_HOST
|
||||
'TG_PROXY_PORT': '', # tg 机器人的 TG_PROXY_PORT
|
||||
}
|
||||
notify_function = []
|
||||
# fmt: on
|
||||
|
||||
# 首先读取 面板变量 或者 github action 运行变量
|
||||
for k in push_config:
|
||||
if os.getenv(k):
|
||||
v = os.getenv(k)
|
||||
push_config[k] = v
|
||||
|
||||
def bark(title: str, content: str) -> None:
|
||||
"""
|
||||
使用 bark 推送消息。
|
||||
"""
|
||||
if not push_config.get("BARK_PUSH"):
|
||||
print("bark 服务的 BARK_PUSH 未设置!!\n取消推送")
|
||||
return
|
||||
print("bark 服务启动")
|
||||
|
||||
if push_config.get("BARK_PUSH").startswith("http"):
|
||||
url = f'{push_config.get("BARK_PUSH")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}'
|
||||
else:
|
||||
url = f'https://api.day.app/{push_config.get("BARK_PUSH")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}'
|
||||
|
||||
bark_params = {
|
||||
"BARK_ARCHIVE": "isArchive",
|
||||
"BARK_GROUP": "group",
|
||||
"BARK_SOUND": "sound",
|
||||
}
|
||||
params = ""
|
||||
for pair in filter(
|
||||
lambda pairs: pairs[0].startswith("BARK_")
|
||||
and pairs[0] != "BARK_PUSH"
|
||||
and pairs[1]
|
||||
and bark_params.get(pairs[0]),
|
||||
push_config.items(),
|
||||
):
|
||||
params += f"{bark_params.get(pair[0])}={pair[1]}&"
|
||||
if params:
|
||||
url = url + "?" + params.rstrip("&")
|
||||
response = session.get(url).json()
|
||||
|
||||
if response["code"] == 200:
|
||||
print("bark 推送成功!")
|
||||
else:
|
||||
print("bark 推送失败!")
|
||||
|
||||
|
||||
def console(title: str, content: str) -> None:
|
||||
"""
|
||||
使用 控制台 推送消息。
|
||||
"""
|
||||
print(f"{title}\n\n{content}")
|
||||
|
||||
|
||||
def dingding_bot(title: str, content: str) -> None:
|
||||
"""
|
||||
使用 钉钉机器人 推送消息。
|
||||
"""
|
||||
if not push_config.get("DD_BOT_SECRET") or not push_config.get("DD_BOT_TOKEN"):
|
||||
print("钉钉机器人 服务的 DD_BOT_SECRET 或者 DD_BOT_TOKEN 未设置!!\n取消推送")
|
||||
return
|
||||
print("钉钉机器人 服务启动")
|
||||
|
||||
timestamp = str(round(time.time() * 1000))
|
||||
secret_enc = push_config.get("DD_BOT_SECRET").encode("utf-8")
|
||||
string_to_sign = "{}\n{}".format(timestamp, push_config.get("DD_BOT_SECRET"))
|
||||
string_to_sign_enc = string_to_sign.encode("utf-8")
|
||||
hmac_code = hmac.new(
|
||||
secret_enc, string_to_sign_enc, digestmod=hashlib.sha256
|
||||
).digest()
|
||||
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
|
||||
url = f'https://oapi.dingtalk.com/robot/send?access_token={push_config.get("DD_BOT_TOKEN")}×tamp={timestamp}&sign={sign}'
|
||||
headers = {"Content-Type": "application/json;charset=utf-8"}
|
||||
data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}}
|
||||
response = session.post(
|
||||
url=url, data=json.dumps(data), headers=headers, timeout=15
|
||||
).json()
|
||||
|
||||
if not response["errcode"]:
|
||||
print("钉钉机器人 推送成功!")
|
||||
else:
|
||||
print("钉钉机器人 推送失败!")
|
||||
|
||||
|
||||
def feishu_bot(title: str, content: str) -> None:
|
||||
"""
|
||||
使用 飞书机器人 推送消息。
|
||||
"""
|
||||
if not push_config.get("FSKEY"):
|
||||
print("飞书 服务的 FSKEY 未设置!!\n取消推送")
|
||||
return
|
||||
print("飞书 服务启动")
|
||||
|
||||
url = f'https://open.feishu.cn/open-apis/bot/v2/hook/{push_config.get("FSKEY")}'
|
||||
data = {"msg_type": "text", "content": {"text": f"{title}\n\n{content}"}}
|
||||
response = session.post(url, data=json.dumps(data)).json()
|
||||
|
||||
if response.get("StatusCode") == 0:
|
||||
print("飞书 推送成功!")
|
||||
else:
|
||||
print("飞书 推送失败!错误信息如下:\n", response)
|
||||
|
||||
|
||||
def go_cqhttp(title: str, content: str) -> None:
|
||||
"""
|
||||
使用 go_cqhttp 推送消息。
|
||||
"""
|
||||
if not push_config.get("GOBOT_URL") or not push_config.get("GOBOT_QQ"):
|
||||
print("go-cqhttp 服务的 GOBOT_URL 或 GOBOT_QQ 未设置!!\n取消推送")
|
||||
return
|
||||
print("go-cqhttp 服务启动")
|
||||
|
||||
url = f'{push_config.get("GOBOT_URL")}?access_token={push_config.get("GOBOT_TOKEN")}&{push_config.get("GOBOT_QQ")}&message=标题:{title}\n内容:{content}'
|
||||
response = session.get(url).json()
|
||||
|
||||
if response["status"] == "ok":
|
||||
print("go-cqhttp 推送成功!")
|
||||
else:
|
||||
print("go-cqhttp 推送失败!")
|
||||
|
||||
|
||||
def gotify(title:str,content:str) -> None:
|
||||
"""
|
||||
使用 gotify 推送消息。
|
||||
"""
|
||||
if not push_config.get("GOTIFY_URL") or not push_config.get("GOTIFY_TOKEN"):
|
||||
print("gotify 服务的 GOTIFY_URL 或 GOTIFY_TOKEN 未设置!!\n取消推送")
|
||||
return
|
||||
print("gotify 服务启动")
|
||||
|
||||
url = f'{push_config.get("GOTIFY_URL")}/message?token={push_config.get("GOTIFY_TOKEN")}'
|
||||
data = {"title": title,"message": content,"priority": push_config.get("GOTIFY_PRIORITY")}
|
||||
response = session.post(url,data=data).json()
|
||||
|
||||
if response.get("id"):
|
||||
print("gotify 推送成功!")
|
||||
else:
|
||||
print("gotify 推送失败!")
|
||||
|
||||
|
||||
def iGot(title: str, content: str) -> None:
|
||||
"""
|
||||
使用 iGot 推送消息。
|
||||
"""
|
||||
if not push_config.get("IGOT_PUSH_KEY"):
|
||||
print("iGot 服务的 IGOT_PUSH_KEY 未设置!!\n取消推送")
|
||||
return
|
||||
print("iGot 服务启动")
|
||||
|
||||
url = f'https://push.hellyw.com/{push_config.get("IGOT_PUSH_KEY")}'
|
||||
data = {"title": title, "content": content}
|
||||
headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
||||
response = session.post(url, data=data, headers=headers).json()
|
||||
|
||||
if response["ret"] == 0:
|
||||
print("iGot 推送成功!")
|
||||
else:
|
||||
print(f'iGot 推送失败!{response["errMsg"]}')
|
||||
|
||||
|
||||
def serverJ(title: str, content: str) -> None:
|
||||
"""
|
||||
通过 serverJ 推送消息。
|
||||
"""
|
||||
if not push_config.get("PUSH_KEY"):
|
||||
print("serverJ 服务的 PUSH_KEY 未设置!!\n取消推送")
|
||||
return
|
||||
print("serverJ 服务启动")
|
||||
|
||||
data = {"text": title, "desp": content.replace("\n", "\n\n")}
|
||||
if push_config.get("PUSH_KEY").index("SCT") != -1:
|
||||
url = f'https://sctapi.ftqq.com/{push_config.get("PUSH_KEY")}.send'
|
||||
else:
|
||||
url = f'https://sc.ftqq.com/${push_config.get("PUSH_KEY")}.send'
|
||||
response = session.post(url, data=data).json()
|
||||
|
||||
if response.get("errno") == 0 or response.get("code") == 0:
|
||||
print("serverJ 推送成功!")
|
||||
else:
|
||||
print(f'serverJ 推送失败!错误码:{response["message"]}')
|
||||
|
||||
|
||||
def pushplus_bot(title: str, content: str) -> None:
|
||||
"""
|
||||
通过 push+ 推送消息。
|
||||
"""
|
||||
if not push_config.get("PUSH_PLUS_TOKEN"):
|
||||
print("PUSHPLUS 服务的 PUSH_PLUS_TOKEN 未设置!!\n取消推送")
|
||||
return
|
||||
print("PUSHPLUS 服务启动")
|
||||
|
||||
url = "http://www.pushplus.plus/send"
|
||||
data = {
|
||||
"token": push_config.get("PUSH_PLUS_TOKEN"),
|
||||
"title": title,
|
||||
"content": content,
|
||||
"topic": push_config.get("PUSH_PLUS_USER"),
|
||||
}
|
||||
body = json.dumps(data).encode(encoding="utf-8")
|
||||
headers = {"Content-Type": "application/json"}
|
||||
response = session.post(url=url, data=body, headers=headers).json()
|
||||
|
||||
if response["code"] == 200:
|
||||
print("PUSHPLUS 推送成功!")
|
||||
|
||||
else:
|
||||
|
||||
url_old = "http://pushplus.hxtrip.com/send"
|
||||
headers["Accept"] = "application/json"
|
||||
response = session.post(url=url_old, data=body, headers=headers).json()
|
||||
|
||||
if response["code"] == 200:
|
||||
print("PUSHPLUS(hxtrip) 推送成功!")
|
||||
|
||||
else:
|
||||
print("PUSHPLUS 推送失败!")
|
||||
|
||||
|
||||
def qmsg_bot(title: str, content: str) -> None:
|
||||
"""
|
||||
使用 qmsg 推送消息。
|
||||
"""
|
||||
if not push_config.get("QMSG_KEY") or not push_config.get("QMSG_TYPE"):
|
||||
print("qmsg 的 QMSG_KEY 或者 QMSG_TYPE 未设置!!\n取消推送")
|
||||
return
|
||||
print("qmsg 服务启动")
|
||||
|
||||
url = f'https://qmsg.zendee.cn/{push_config.get("QMSG_TYPE")}/{push_config.get("QMSG_KEY")}'
|
||||
payload = {"msg": f'{title}\n\n{content.replace("----", "-")}'.encode("utf-8")}
|
||||
response = session.post(url=url, params=payload).json()
|
||||
|
||||
if response["code"] == 0:
|
||||
print("qmsg 推送成功!")
|
||||
else:
|
||||
print(f'qmsg 推送失败!{response["reason"]}')
|
||||
|
||||
|
||||
def wecom_app(title: str, content: str) -> None:
|
||||
"""
|
||||
通过 企业微信 APP 推送消息。
|
||||
"""
|
||||
if not push_config.get("QYWX_AM"):
|
||||
print("QYWX_AM 未设置!!\n取消推送")
|
||||
return
|
||||
QYWX_AM_AY = re.split(",", push_config.get("QYWX_AM"))
|
||||
if title == "WsKey转换脚本" :
|
||||
print("包含屏蔽词 取消推送")
|
||||
return
|
||||
if title == "WSKEY转换" :
|
||||
print("包含屏蔽词 取消推送")
|
||||
return
|
||||
if 4 < len(QYWX_AM_AY) > 5:
|
||||
print("QYWX_AM 设置错误!!\n取消推送")
|
||||
return
|
||||
print("企业微信 APP 服务启动")
|
||||
corpid = QYWX_AM_AY[0]
|
||||
corpsecret = QYWX_AM_AY[1]
|
||||
touser = QYWX_AM_AY[2]
|
||||
agentid = QYWX_AM_AY[3]
|
||||
try:
|
||||
media_id = QYWX_AM_AY[4]
|
||||
except IndexError:
|
||||
media_id = ""
|
||||
wx = WeCom(corpid, corpsecret, agentid)
|
||||
# 如果没有配置 media_id 默认就以 text 方式发送
|
||||
if not media_id:
|
||||
message = title + "\n\n" + content
|
||||
response = wx.send_text(message, touser)
|
||||
else:
|
||||
response = wx.send_mpnews(title, content, media_id, touser)
|
||||
|
||||
if response == "ok":
|
||||
print("企业微信推送成功!")
|
||||
else:
|
||||
print("企业微信推送失败!错误信息如下:\n", response)
|
||||
|
||||
|
||||
class WeCom:
|
||||
def __init__(self, corpid, corpsecret, agentid):
|
||||
self.CORPID = corpid
|
||||
self.CORPSECRET = corpsecret
|
||||
self.AGENTID = agentid
|
||||
|
||||
def get_access_token(self):
|
||||
url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"
|
||||
values = {
|
||||
"corpid": self.CORPID,
|
||||
"corpsecret": self.CORPSECRET,
|
||||
}
|
||||
req = session.post(url, params=values)
|
||||
data = json.loads(req.text)
|
||||
return data["access_token"]
|
||||
|
||||
def send_text(self, message, touser="@all"):
|
||||
send_url = (
|
||||
"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="
|
||||
+ self.get_access_token()
|
||||
)
|
||||
send_values = {
|
||||
"touser": touser,
|
||||
"msgtype": "text",
|
||||
"agentid": self.AGENTID,
|
||||
"text": {"content": message},
|
||||
"safe": "0",
|
||||
}
|
||||
send_msges = bytes(json.dumps(send_values), "utf-8")
|
||||
respone = session.post(send_url, send_msges)
|
||||
respone = respone.json()
|
||||
return respone["errmsg"]
|
||||
|
||||
def send_mpnews(self, title, message, media_id, touser="@all"):
|
||||
send_url = (
|
||||
"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="
|
||||
+ self.get_access_token()
|
||||
)
|
||||
send_values = {
|
||||
"touser": touser,
|
||||
"msgtype": "mpnews",
|
||||
"agentid": self.AGENTID,
|
||||
"mpnews": {
|
||||
"articles": [
|
||||
{
|
||||
"title": title,
|
||||
"thumb_media_id": media_id,
|
||||
"author": "Author",
|
||||
"content_source_url": "",
|
||||
"content": message.replace("\n", "<br/>"),
|
||||
"digest": message,
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
send_msges = bytes(json.dumps(send_values), "utf-8")
|
||||
respone = session.post(send_url, send_msges)
|
||||
respone = respone.json()
|
||||
return respone["errmsg"]
|
||||
|
||||
|
||||
def wecom_bot(title: str, content: str) -> None:
|
||||
"""
|
||||
通过 企业微信机器人 推送消息。
|
||||
"""
|
||||
if not push_config.get("QYWX_KEY"):
|
||||
print("企业微信机器人 服务的 QYWX_KEY 未设置!!\n取消推送")
|
||||
return
|
||||
print("企业微信机器人服务启动")
|
||||
|
||||
url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={push_config.get('QYWX_KEY')}"
|
||||
headers = {"Content-Type": "application/json;charset=utf-8"}
|
||||
data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}}
|
||||
response = session.post(
|
||||
url=url, data=json.dumps(data), headers=headers, timeout=15
|
||||
).json()
|
||||
|
||||
if response["errcode"] == 0:
|
||||
print("企业微信机器人推送成功!")
|
||||
else:
|
||||
print("企业微信机器人推送失败!")
|
||||
|
||||
|
||||
def telegram_bot(title: str, content: str) -> None:
|
||||
"""
|
||||
使用 telegram 机器人 推送消息。
|
||||
"""
|
||||
if not push_config.get("TG_BOT_TOKEN") or not push_config.get("TG_USER_ID"):
|
||||
print("tg 服务的 bot_token 或者 user_id 未设置!!\n取消推送")
|
||||
return
|
||||
print("tg 服务启动")
|
||||
|
||||
if push_config.get("TG_API_HOST"):
|
||||
url = f"https://{push_config.get('TG_API_HOST')}/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage"
|
||||
else:
|
||||
url = (
|
||||
f"https://api.telegram.org/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage"
|
||||
)
|
||||
headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
||||
payload = {
|
||||
"chat_id": str(push_config.get("TG_USER_ID")),
|
||||
"text": f"{title}\n\n{content}",
|
||||
"disable_web_page_preview": "true",
|
||||
}
|
||||
proxies = None
|
||||
if push_config.get("TG_PROXY_HOST") and push_config.get("TG_PROXY_PORT"):
|
||||
if push_config.get("TG_PROXY_AUTH") is not None and "@" not in push_config.get(
|
||||
"TG_PROXY_HOST"
|
||||
):
|
||||
push_config["TG_PROXY_HOST"] = (
|
||||
push_config.get("TG_PROXY_AUTH")
|
||||
+ "@"
|
||||
+ push_config.get("TG_PROXY_HOST")
|
||||
)
|
||||
proxyStr = "http://{}:{}".format(
|
||||
push_config.get("TG_PROXY_HOST"), push_config.get("TG_PROXY_PORT")
|
||||
)
|
||||
proxies = {"http": proxyStr, "https": proxyStr}
|
||||
response = session.post(
|
||||
url=url, headers=headers, params=payload, proxies=proxies
|
||||
).json()
|
||||
|
||||
if response["ok"]:
|
||||
print("tg 推送成功!")
|
||||
else:
|
||||
print("tg 推送失败!")
|
||||
|
||||
|
||||
def one() -> str:
|
||||
"""
|
||||
获取一条一言。
|
||||
:return:
|
||||
"""
|
||||
url = "https://v1.hitokoto.cn/"
|
||||
res = session.get(url).json()
|
||||
return res["hitokoto"] + " ----" + res["from"]
|
||||
|
||||
|
||||
if push_config.get("BARK_PUSH"):
|
||||
notify_function.append(bark)
|
||||
if push_config.get("CONSOLE"):
|
||||
notify_function.append(console)
|
||||
if push_config.get("DD_BOT_TOKEN") and push_config.get("DD_BOT_SECRET"):
|
||||
notify_function.append(dingding_bot)
|
||||
if push_config.get("FSKEY"):
|
||||
notify_function.append(feishu_bot)
|
||||
if push_config.get("GOBOT_URL") and push_config.get("GOBOT_QQ"):
|
||||
notify_function.append(go_cqhttp)
|
||||
if push_config.get("GOTIFY_URL") and push_config.get("GOTIFY_TOKEN"):
|
||||
notify_function.append(gotify)
|
||||
if push_config.get("IGOT_PUSH_KEY"):
|
||||
notify_function.append(iGot)
|
||||
if push_config.get("PUSH_KEY"):
|
||||
notify_function.append(serverJ)
|
||||
if push_config.get("PUSH_PLUS_TOKEN"):
|
||||
notify_function.append(pushplus_bot)
|
||||
if push_config.get("QMSG_KEY") and push_config.get("QMSG_TYPE"):
|
||||
notify_function.append(qmsg_bot)
|
||||
if push_config.get("QYWX_AM"):
|
||||
notify_function.append(wecom_app)
|
||||
if push_config.get("QYWX_KEY"):
|
||||
notify_function.append(wecom_bot)
|
||||
if push_config.get("TG_BOT_TOKEN") and push_config.get("TG_USER_ID"):
|
||||
notify_function.append(telegram_bot)
|
||||
|
||||
|
||||
def send(title: str, content: str) -> None:
|
||||
if not content:
|
||||
print(f"{title} 推送内容为空!")
|
||||
return
|
||||
|
||||
hitokoto = push_config.get("HITOKOTO")
|
||||
|
||||
text = one() if hitokoto else ""
|
||||
now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||||
content += "\n" + text + f"推送时间:{now}"
|
||||
|
||||
ts = [
|
||||
threading.Thread(target=mode, args=(title, content), name=mode.__name__)
|
||||
for mode in notify_function
|
||||
]
|
||||
[t.start() for t in ts]
|
||||
[t.join() for t in ts]
|
||||
|
||||
|
||||
def main():
|
||||
send("title", "content")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in New Issue
Block a user