上传文件至「Points_Based」

This commit is contained in:
2026-08-01 03:23:13 +08:00
parent 302f071c85
commit be602d0929
+338
View File
@@ -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()