上传文件至「Points_Based」
This commit is contained in:
@@ -0,0 +1,338 @@
|
|||||||
|
# cron: 0 8 * * *
|
||||||
|
# new Env("中通快递")
|
||||||
|
"""
|
||||||
|
脚本: 中通小程序自动签到
|
||||||
|
作者: 3iXi
|
||||||
|
创建日期: 2025-06-24
|
||||||
|
修改日期: 2025-06-27
|
||||||
|
更新内容:更换为账号密码登录,Token永不过期
|
||||||
|
----------------------
|
||||||
|
描述: 使用账号密码登录中通快递,自动签到获取积分;访问网页zto.com登录后在“个人中心”-“账户绑定”里设置密码。
|
||||||
|
环境变量:
|
||||||
|
变量名:ztozm
|
||||||
|
变量值:手机号&密码,多个账号用#分隔
|
||||||
|
签到奖励:积分,可兑东西
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import requests
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
def parse_account_credentials(credentials):
|
||||||
|
"""解析账号密码信息"""
|
||||||
|
try:
|
||||||
|
if '&' not in credentials:
|
||||||
|
print("账号密码格式错误,应为:手机号&密码")
|
||||||
|
return None
|
||||||
|
|
||||||
|
username, password = credentials.split('&', 1)
|
||||||
|
if not username or not password:
|
||||||
|
print("账号或密码不能为空")
|
||||||
|
return None
|
||||||
|
|
||||||
|
return {
|
||||||
|
"username": username.strip(),
|
||||||
|
"password": password.strip()
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
print(f"解析账号密码失败: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_timestamp():
|
||||||
|
"""获取当前13位时间戳"""
|
||||||
|
return str(int(time.time() * 1000))
|
||||||
|
|
||||||
|
def get_date_range():
|
||||||
|
"""获取查询签到记录的日期范围"""
|
||||||
|
today = datetime.now()
|
||||||
|
start_date = (today - timedelta(days=3)).strftime("%Y-%m-%d 00:00:00")
|
||||||
|
end_date = (today + timedelta(days=3)).strftime("%Y-%m-%d 23:59:59")
|
||||||
|
return start_date, end_date
|
||||||
|
|
||||||
|
def get_today_date():
|
||||||
|
"""获取今天的日期"""
|
||||||
|
return datetime.now().strftime("%Y-%m-%d")
|
||||||
|
|
||||||
|
def login_with_password(username, password):
|
||||||
|
"""使用账号密码登录获取Token"""
|
||||||
|
url = "https://hdgateway.zto.com/auth_account_loginByPassword"
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Host": "hdgateway.zto.com",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
"x-clientCode": "pc",
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
|
||||||
|
"Accept": "application/json, text/plain, */*",
|
||||||
|
"Origin": "https://auth.zto.com",
|
||||||
|
"Referer": "https://auth.zto.com/",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br, zstd",
|
||||||
|
"Accept-Language": "zh-CN,zh;q=0.9"
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"userName": username,
|
||||||
|
"password": password,
|
||||||
|
"isAgainBind": False
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.post(url, headers=headers, json=payload, timeout=30)
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
if data.get("status") == True:
|
||||||
|
token = data["result"]["token"]
|
||||||
|
print(f"账号 {username} 登录成功")
|
||||||
|
return token
|
||||||
|
else:
|
||||||
|
print(f"账号 {username} 登录失败: {data.get('message', '未知错误')}")
|
||||||
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
print(f"账号 {username} 登录请求失败: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def check_today_sign_status(token):
|
||||||
|
"""检查今日是否签到"""
|
||||||
|
url = "https://membergateway.zto.com/member/activity/queryRecentSign"
|
||||||
|
|
||||||
|
start_date, end_date = get_date_range()
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Host": "membergateway.zto.com",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"x-version": "V8.93.2",
|
||||||
|
"x-token": token,
|
||||||
|
"x-clientCode": "wechatMiniZtoHelper",
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) XWEB/13871",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"x-sv-v": "0.22.0",
|
||||||
|
"Accept": "*/*",
|
||||||
|
"Referer": "https://servicewechat.com/wx7ddec43d9d27276a/553/page-frame.html",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br",
|
||||||
|
"Accept-Language": "zh-CN,zh;q=0.9"
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"startDate": start_date,
|
||||||
|
"endDate": end_date
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.post(url, headers=headers, json=payload, timeout=30)
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
if data.get("status"):
|
||||||
|
daily_list = data["result"]["dailyList"]
|
||||||
|
today_date = get_today_date()
|
||||||
|
|
||||||
|
for day_info in daily_list:
|
||||||
|
if day_info["date"] == today_date:
|
||||||
|
return {
|
||||||
|
"is_signed": day_info["isSigned"],
|
||||||
|
"total_points": data["result"]["totalPoints"]
|
||||||
|
}
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
print(f"查询签到状态失败: {data.get('message', '未知错误')}")
|
||||||
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
print(f"查询签到状态请求失败: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def sign_in(token):
|
||||||
|
"""开始签到"""
|
||||||
|
url = "https://membergateway.zto.com/member/activity/signIn"
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Host": "membergateway.zto.com",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"x-version": "V8.93.2",
|
||||||
|
"x-token": token,
|
||||||
|
"x-clientCode": "wechatMiniZtoHelper",
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) XWEB/13871",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"x-sv-v": "0.22.0",
|
||||||
|
"Accept": "*/*",
|
||||||
|
"Referer": "https://servicewechat.com/wx7ddec43d9d27276a/553/page-frame.html",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br",
|
||||||
|
"Accept-Language": "zh-CN,zh;q=0.9"
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"signType": "TODAY_SIGN",
|
||||||
|
"signDate": f"{get_today_date()} 00:00:00",
|
||||||
|
"supplementaryScene": None
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.post(url, headers=headers, json=payload, timeout=30)
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
if data.get("status"):
|
||||||
|
points_earned = data["result"]["pointsEarned"]
|
||||||
|
print(f"签到成功,得到{points_earned}积分")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"签到失败: {data.get('message', '未知错误')}")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f"签到请求失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def check_and_claim_resign_card(token):
|
||||||
|
"""检查并领取补签卡(每月1次)"""
|
||||||
|
url = "https://membergateway.zto.com/member/activity/getMyActivityProps"
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Host": "membergateway.zto.com",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"x-version": "V8.93.2",
|
||||||
|
"x-token": token,
|
||||||
|
"x-clientCode": "wechatMiniZtoHelper",
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) XWEB/13871",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"x-sv-v": "0.22.0",
|
||||||
|
"Accept": "*/*",
|
||||||
|
"Referer": "https://servicewechat.com/wx7ddec43d9d27276a/553/page-frame.html",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br",
|
||||||
|
"Accept-Language": "zh-CN,zh;q=0.9"
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = {"propsType": "RESIGN_CARD"}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.post(url, headers=headers, json=payload, timeout=30)
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
if data.get("status"):
|
||||||
|
monthly_collection_status = data["result"]["monthlyCollectionStatus"]
|
||||||
|
if monthly_collection_status == 1:
|
||||||
|
# 领取补签卡,如果这个月领了的话就什么都不做
|
||||||
|
claim_url = "https://membergateway.zto.com/member/activity/issueProps"
|
||||||
|
claim_payload = {
|
||||||
|
"propsType": "RESIGN_CARD",
|
||||||
|
"taskType": "MONTHLY_COLLECTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
claim_response = requests.post(claim_url, headers=headers, json=claim_payload, timeout=30)
|
||||||
|
claim_data = claim_response.json()
|
||||||
|
|
||||||
|
if claim_data.get("status"):
|
||||||
|
print("每月免费领取补签卡*1成功")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"检查/领取补签卡失败: {e}")
|
||||||
|
|
||||||
|
def get_member_points(token):
|
||||||
|
"""获取积分"""
|
||||||
|
url = "https://membergateway.zto.com/member/getMemberPoints"
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Host": "membergateway.zto.com",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"x-version": "V8.93.2",
|
||||||
|
"x-token": token,
|
||||||
|
"x-clientCode": "wechatMiniZtoHelper",
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) XWEB/13871",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"x-sv-v": "0.22.0",
|
||||||
|
"Accept": "*/*",
|
||||||
|
"Referer": "https://servicewechat.com/wx7ddec43d9d27276a/553/page-frame.html",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br",
|
||||||
|
"Accept-Language": "zh-CN,zh;q=0.9"
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.post(url, headers=headers, json=payload, timeout=30)
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
if data.get("success"):
|
||||||
|
total_point = data["data"]["totalPoint"]
|
||||||
|
over_due_point = data["data"]["overDuePoint"]
|
||||||
|
over_due_message = data["data"]["overDueMessage"]
|
||||||
|
|
||||||
|
if over_due_point:
|
||||||
|
print(f"当前积分{total_point},{over_due_message}")
|
||||||
|
else:
|
||||||
|
print(f"当前积分{total_point}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"获取积分信息失败: {e}")
|
||||||
|
|
||||||
|
def process_account(credentials):
|
||||||
|
"""处理单个账户的签到流程"""
|
||||||
|
# 解析账号密码
|
||||||
|
account_info = parse_account_credentials(credentials)
|
||||||
|
if not account_info:
|
||||||
|
print("解析账号密码失败,跳过此账户")
|
||||||
|
return
|
||||||
|
|
||||||
|
username = account_info["username"]
|
||||||
|
password = account_info["password"]
|
||||||
|
|
||||||
|
print(f"\n开始处理账户: {username}")
|
||||||
|
|
||||||
|
# 使用账号密码登录获取Token
|
||||||
|
token = login_with_password(username, password)
|
||||||
|
if not token:
|
||||||
|
print("登录失败,跳过此账户")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 检查今天是否签到
|
||||||
|
sign_status = check_today_sign_status(token)
|
||||||
|
if not sign_status:
|
||||||
|
print("无法获取签到状态,跳过此账户")
|
||||||
|
return
|
||||||
|
|
||||||
|
if sign_status["is_signed"]:
|
||||||
|
print(f"今天已签到,当前积分{sign_status['total_points']}")
|
||||||
|
else:
|
||||||
|
print("今天未签到,开始签到...")
|
||||||
|
sign_in(token)
|
||||||
|
|
||||||
|
# 检查并领取补签卡
|
||||||
|
check_and_claim_resign_card(token)
|
||||||
|
|
||||||
|
# 获取积分信息
|
||||||
|
get_member_points(token)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数"""
|
||||||
|
print("中通快递自动签到脚本启动...")
|
||||||
|
|
||||||
|
# 获取环境变量
|
||||||
|
zto_credentials = os.getenv("ztozm")
|
||||||
|
if not zto_credentials:
|
||||||
|
print("未找到环境变量'ztozm',请先设置")
|
||||||
|
print("格式:手机号&密码,多个账号用#分隔")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 分割多个账号密码
|
||||||
|
credentials_list = zto_credentials.split("#")
|
||||||
|
print(f"共找到{len(credentials_list)}个账号")
|
||||||
|
|
||||||
|
# 处理每个账户
|
||||||
|
for i, credentials in enumerate(credentials_list, 1):
|
||||||
|
credentials = credentials.strip()
|
||||||
|
if not credentials:
|
||||||
|
continue
|
||||||
|
|
||||||
|
print(f"\n{'='*30}")
|
||||||
|
print(f"处理第{i}个账户")
|
||||||
|
print(f"{'='*30}")
|
||||||
|
|
||||||
|
process_account(credentials)
|
||||||
|
|
||||||
|
# 为避免请求过于频繁,添加延时
|
||||||
|
if i < len(credentials_list):
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
print(f"\n{'='*30}")
|
||||||
|
print("所有账户处理完成!")
|
||||||
|
print(f"{'='*30}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user