Update tyyun.py

This commit is contained in:
blusunny
2025-09-11 22:05:12 +08:00
committed by GitHub
parent f0b0dd7ea7
commit d36e92afea

362
tyyun.py
View File

@@ -1,67 +1,47 @@
#!/usr/bin/python3 #!/usr/bin/env python3
# -- coding: utf-8 --
# @Time : 2023/4/8 9:23
#作者https://www.52pojie.cn/forum.php?mod=viewthread&tid=1784111&highlight=%C7%A9%B5%BD
# -------------------------------
# cron "30 4 * * *" script-path=xxx.py,tag=匹配cron用
# const $ = new Env('天翼云盘签到');
# #!/usr/bin/python3
# # -- coding: utf-8 --
# # @Time : 2023/4/4 9:23
# #作者https://www.52pojie.cn/thread-1231190-1-1.html
# # -------------------------------
# # cron "30 4 * * *" script-path=xxx.py,tag=匹配cron用
# # const $ = new Env('天翼云盘签到');
#
import time import time
import re import os
import random
import json import json
import base64 import base64
import hashlib import hashlib
import urllib.parse, hmac
import rsa import rsa
import requests import requests
import random import re
import os from urllib.parse import urlparse # 修复:导入语句完整且格式规范
# 变量 ty_username手机号,ty_password密码
ty_username = os.getenv("ty_username").split('&')
ty_password = os.getenv("ty_password").split('&')
# 推送加
plustoken = os.getenv("plustoken")
# 常量定义
BI_RM = list("0123456789abcdefghijklmnopqrstuvwxyz") BI_RM = list("0123456789abcdefghijklmnopqrstuvwxyz")
B64MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" B64MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
s = requests.Session() def mask_phone(phone):
"""
隐藏手机号中间四位
:param phone: 手机号字符串
:return: 隐藏后的手机号如138****1234
"""
return phone[:3] + "****" + phone[-4:] if len(phone) == 11 else phone
for i in range(len(ty_username)):
print(f'开始执行帐号{i+1}')
#推送函数
def Push(contents):
# 推送加
headers = {'Content-Type': 'application/json'}
json = {"token": plustoken, 'title': '天翼云签到', 'content': contents.replace('\n', '<br>'), "template": "json"}
resp = requests.post(f'http://www.pushplus.plus/send', json=json, headers=headers).json()
print('push+推送成功' if resp['code'] == 200 else 'push+推送失败')
def int2char(a): def int2char(a):
"""
将数字转换为对应的字符
:param a: 0-35的数字
:return: 对应的字符
"""
return BI_RM[a] return BI_RM[a]
def b64tohex(a): def b64tohex(a):
"""
Base64字符串转换为十六进制字符串
:param a: Base64编码的字符串
:return: 十六进制字符串
"""
d = "" d = ""
e = 0 e = 0
c = 0 c = 0
for i in range(len(a)): for i in range(len(a)):
if list(a)[i] != "=": if list(a)[i] != "=":
# 修复变量v赋值语句完整且格式规范
v = B64MAP.index(list(a)[i]) v = B64MAP.index(list(a)[i])
if 0 == e: if 0 == e:
e = 1 e = 1
@@ -84,147 +64,223 @@ for i in range(len(ty_username)):
d += int2char(c << 2) d += int2char(c << 2)
return d return d
def rsa_encode(j_rsakey, string): def rsa_encode(j_rsakey, string):
"""
使用RSA公钥加密字符串
:param j_rsakey: RSA公钥
:param string: 需要加密的字符串
:return: 加密后的字符串
"""
rsa_key = f"-----BEGIN PUBLIC KEY-----\n{j_rsakey}\n-----END PUBLIC KEY-----" rsa_key = f"-----BEGIN PUBLIC KEY-----\n{j_rsakey}\n-----END PUBLIC KEY-----"
# 修复pubkey赋值语句完整且格式规范
pubkey = rsa.PublicKey.load_pkcs1_openssl_pem(rsa_key.encode()) pubkey = rsa.PublicKey.load_pkcs1_openssl_pem(rsa_key.encode())
result = b64tohex((base64.b64encode(rsa.encrypt(f'{string}'.encode(), pubkey))).decode()) result = b64tohex((base64.b64encode(rsa.encrypt(f'{string}'.encode(), pubkey))).decode())
return result return result
def login(username, password):
"""
登录天翼云盘
:param username: 用户名
:param password: 密码
:return: 登录成功的session对象失败返回None
"""
print(" 正在执行登录流程...")
session = requests.Session() # 统一格式:赋值语句不换行
def calculate_md5_sign(params): try:
return hashlib.md5('&'.join(sorted(params.split('&'))).encode('utf-8')).hexdigest() # 获取登录令牌
url_token = "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"
response = session.get(url_token) # 统一格式:不换行
match = re.search(r"https?://[^\s'\"]+", response.text) # 统一格式:不换行
if not match:
print(" 错误:未找到动态登录页")
return None
def login(ty_username, ty_password): # 获取登录页面
# https://m.cloud.189.cn/login2014.jsp?redirectURL=https://m.cloud.189.cn/zhuanti/2021/shakeLottery/index.html url = match.group()
url = "" response = session.get(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" match = re.search(r"<a id=\"j-tab-login-link\"[^>]*href=\"([^\"]+)\"", response.text)
s = requests.Session() if not match:
r = s.get(urlToken) print(" 错误:登录入口获取失败")
pattern = r"https?://[^\s'\"]+" # 匹配以http或https开头的url return None
match = re.search(pattern, r.text) # 在文本中搜索匹配
if match: # 如果找到匹配
url = match.group() # 获取匹配的字符串
# print(url) # 打印url
else: # 如果没有找到匹配
print("没有找到url")
r = s.get(url) # 解析登录参数
# print(r.text) href = match.group(1)
pattern = r"<a id=\"j-tab-login-link\"[^>]*href=\"([^\"]+)\"" # 匹配id为j-tab-login-link的a标签并捕获href引号内的内容 response = session.get(href)
match = re.search(pattern, r.text) # 在文本中搜索匹配
if match: # 如果找到匹配
href = match.group(1) # 获取捕获的内容
# print("href:" + href) # 打印href链接
else: # 如果没有找到匹配
print("没有找到href链接")
r = s.get(href) captcha_token = re.findall(r"captchaToken' value='(.+?)'", response.text)[0]
captchaToken = re.findall(r"captchaToken' value='(.+?)'", r.text)[0] lt = re.findall(r'lt = "(.+?)"', response.text)[0]
lt = re.findall(r'lt = "(.+?)"', r.text)[0] return_url = re.findall(r"returnUrl= '(.+?)'", response.text)[0]
returnUrl = re.findall(r"returnUrl= '(.+?)'", r.text)[0] param_id = re.findall(r'paramId = "(.+?)"', response.text)[0]
paramId = re.findall(r'paramId = "(.+?)"', r.text)[0] j_rsakey = re.findall(r'j_rsaKey" value="(\S+)"', response.text, re.M)[0]
j_rsakey = re.findall(r'j_rsaKey" value="(\S+)"', r.text, re.M)[0]
s.headers.update({"lt": lt})
username = rsa_encode(j_rsakey, ty_username[i]) session.headers.update({"lt": lt})
password = rsa_encode(j_rsakey,ty_password[i])
url = "https://open.e.189.cn/api/logbox/oauth2/loginSubmit.do" # RSA加密用户名和密码
headers = { username_encrypted = rsa_encode(j_rsakey, username)
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/76.0', password_encrypted = rsa_encode(j_rsakey, password)
'Referer': 'https://open.e.189.cn/',
} # 准备登录数据
data = { data = {
"appKey": "cloud", "appKey": "cloud",
"accountType": '01', "accountType": '01',
"userName": f"{{RSA}}{username}", "userName": f"{{RSA}}{username_encrypted}",
"password": f"{{RSA}}{password}", "password": f"{{RSA}}{password_encrypted}",
"validateCode": "", "validateCode": "",
"captchaToken": captchaToken, "captchaToken": captcha_token,
"returnUrl": returnUrl, "returnUrl": return_url,
"mailSuffix": "@189.cn", "mailSuffix": "@189.cn", # 修复:邮箱后缀不换行
"paramId": paramId "paramId": param_id
} }
r = s.post(url, data=data, headers=headers, timeout=5)
if (r.json()['result'] == 0):
print(r.json()['msg'])
else:
print(r.json()['msg'])
redirect_url = r.json()['toUrl']
r = s.get(redirect_url)
return s
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/76.0',
'Referer': 'https://open.e.189.cn/', # 修复:链接不换行
}
# 提交登录请求
response = session.post(
"https://open.e.189.cn/api/logbox/oauth2/loginSubmit.do",
data=data,
headers=headers,
timeout=10
)
# 检查登录结果
if response.json().get('result', 1) != 0:
print(f" 登录错误:{response.json().get('msg')}")
return None
# 跳转到返回URL完成登录
session.get(response.json()['toUrl'])
print(" 登录成功")
return session
except Exception as e:
print(f" 登录异常:{str(e)}")
return None
def send_wxpusher(msg):
"""
发送消息到WxPusher
:param msg: 要发送的消息内容
"""
# 从环境变量获取WxPusher配置
app_token = os.getenv("WXPUSHER_APP_TOKEN")
uids = os.getenv("WXPUSHER_UID", "").split('&')
if not app_token or not uids:
print(" 未配置WxPusher跳过消息推送")
return
url = "https://wxpusher.zjiecode.com/api/send/message" # 修复:链接不换行
headers = {"Content-Type": "application/json"}
for uid in uids:
data = {
"appToken": app_token,
"content": msg,
"contentType": 3, # 3表示HTML格式
"topicIds": [],
"uids": [uid],
}
try:
response = requests.post(url, json=data, headers=headers, timeout=10)
if response.json().get('code') == 1000:
print(f" 消息推送成功 -> UID: {uid}")
else:
print(f" 消息推送失败:{response.text}")
except Exception as e:
print(f" 推送异常:{str(e)}")
def main(): def main():
s = login(ty_username, ty_password) """
rand = str(round(time.time() * 1000)) 主函数:处理所有账号的签到和抽奖
surl = f'https://api.cloud.189.cn/mkt/userSign.action?rand={rand}&clientType=TELEANDROID&version=8.6.3&model=SM-G930K' """
url = f'https://m.cloud.189.cn/v2/drawPrizeMarketDetails.action?taskId=TASK_SIGNIN&activityId=ACT_SIGNIN' print("\n=============== 天翼云盘签到开始 ===============")
url2 = f'https://m.cloud.189.cn/v2/drawPrizeMarketDetails.action?taskId=TASK_SIGNIN_PHOTOS&activityId=ACT_SIGNIN'
url3 = f'https://m.cloud.189.cn/v2/drawPrizeMarketDetails.action?taskId=TASK_2022_FLDFS_KJ&activityId=ACT_SIGNIN' # 从环境变量获取账号信息
usernames = os.getenv("ty_username", "").split('&')
passwords = os.getenv("ty_password", "").split('&')
# 检查环境变量
if not usernames or not passwords or not usernames[0] or not passwords[0]:
print(" 请设置环境变量 ty_username 和 ty_password")
return
# 确保账号密码数量匹配
if len(usernames) != len(passwords):
print(" 账号和密码数量不匹配")
return
# 组合账号信息
accounts = [{"username": u, "password": p} for u, p in zip(usernames, passwords)]
all_results = []
for acc in accounts:
username = acc["username"]
password = acc["password"]
masked_phone = mask_phone(username)
account_result = {"username": masked_phone, "sign": "", "lottery": ""}
print(f"\n 处理账号:{masked_phone}")
# 登录流程
session = login(username, password)
if not session:
account_result["sign"] = " 登录失败"
all_results.append(account_result)
continue
# 签到流程
try:
# 每日签到
rand = str(round(time.time() * 1000)) # 修复:不换行
sign_url = f'https://api.cloud.189.cn/mkt/userSign.action?rand={rand}&clientType=TELEANDROID&version=8.6.3&model=SM-G930K'
headers = { headers = {
'User-Agent': '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', 'User-Agent': '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',
"Referer": "https://m.cloud.189.cn/zhuanti/2016/sign/index.jsp?albumBackupOpened=1", "Referer": "https://m.cloud.189.cn/zhuanti/2016/sign/index.jsp?albumBackupOpened=1",
"Host": "m.cloud.189.cn", "Host": "m.cloud.189.cn",
"Accept-Encoding": "gzip, deflate",
} }
response = s.get(surl, headers=headers) response = session.get(sign_url, headers=headers).json()
netdiskBonus = response.json()['netdiskBonus']
if (response.json()['isSign'] == "false"): if 'isSign' in response:
print(f"未签到,签到获得{netdiskBonus}M空间") if response.get('isSign') == "false":
res1 = f"未签到,签到获得{netdiskBonus}M空间" account_result["sign"] = f" +{response.get('netdiskBonus', '0')}M"
else: else:
print(f"已经签到过了,签到获得{netdiskBonus}M空间") account_result["sign"] = f" 已签到+{response.get('netdiskBonus', '0')}M"
res1 = f"已经签到过了,签到获得{netdiskBonus}M空间"
headers = {
'User-Agent': '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',
"Referer": "https://m.cloud.189.cn/zhuanti/2016/sign/index.jsp?albumBackupOpened=1",
"Host": "m.cloud.189.cn",
"Accept-Encoding": "gzip, deflate",
}
response = s.get(url, headers=headers)
if ("errorCode" in response.text):
print(response.text)
res2 = ""
else: else:
description = response.json()['description'] account_result["sign"] = f" 签到失败: {response.get('errorMsg', '未知错误')}"
print(f"抽奖获得{description}")
res2 = f"抽奖获得{description}" # 单次抽奖
response = s.get(url2, headers=headers) time.sleep(random.randint(2, 5)) # 修复:不换行
if ("errorCode" in response.text): lottery_url = 'https://m.cloud.189.cn/v2/drawPrizeMarketDetails.action?taskId=TASK_SIGNIN&activityId=ACT_SIGNIN'
print(response.text) response = session.get(lottery_url, headers=headers).json()
res3 = ""
if "errorCode" in response:
account_result["lottery"] = f" {response.get('errorCode')}"
else: else:
description = response.json()['description'] prize = response.get('prizeName') or response.get('description', '未知奖品')
print(f"抽奖获得{description}") account_result["lottery"] = f" {prize}"
res3 = f"抽奖获得{description}"
response = s.get(url3, headers=headers) except Exception as e:
if ("errorCode" in response.text): account_result["sign"] = " 操作异常"
print(response.text) account_result["lottery"] = f" {str(e)}"
res4 = ""
else:
description = response.json()['description']
print(f"链接3抽奖获得{description}")
res4 = f"链接3抽奖获得{description}"
message = res1+res2+res3+res4
Push(contents=message)
all_results.append(account_result)
print(f" {account_result['sign']} | {account_result['lottery']}")
def lambda_handler(event, context): # aws default # 生成汇总表格
main() table = "### 天翼云盘签到汇总\n\n"
table += "| 账号 | 签到结果 | 每日抽奖 |\n"
table += "|:-:|:-:|:-:|\n"
def main_handler(event, context): # tencent default for res in all_results:
main() table += f"| {res['username']} | {res['sign']} | {res['lottery']} |\n"
def handler(event, context): # aliyun default
main()
# 发送汇总推送
send_wxpusher(table)
print("\n 所有账号处理完成!")
if __name__ == "__main__": if __name__ == "__main__":
time.sleep(random.randint(5, 30))
main() main()