Files
qinglong/脚本库/web版/抓包/同程旅游/2025-11-29_tclx_b49c33dc.py
2026-05-24 03:53:42 +00:00

255 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Source: https://github.com/back-101/zyqinglong/blob/main/tclx.py
# Raw: https://raw.githubusercontent.com/back-101/zyqinglong/main/tclx.py
# Repo: back-101/zyqinglong
# Path: tclx.py
# UploadedAt: 2025-11-29T06:56:58Z
# SHA256: b49c33dc10adf577eb8b1809d98ceeddc3a58a11676c70eb65a040f3d76c9035
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
# -*- coding=UTF-8 -*-
# @Project QL_TimingScript
# @fileName tclx.py
# @author Echo
# @EditTime 2025/3/14
# cron: 0 0 9 * * *
# const $ = new Env('同程旅游');
"""
开启抓包进入app 进入领福利界面点击签到查看https://app.17u.cn/welfarecenter/index/signIndex请求头
提取变量: apptoken、device
变量格式: phone#apptoken#device多个账号用@隔开
"""
import asyncio
import time
from datetime import datetime
import httpx
from fn_print import fn_print
from get_env import get_env
from sendNotify import send_notification_message_collection
tc_cookies = get_env("tc_cookie", "@")
class Tclx:
def __init__(self, cookie):
self.client = httpx.AsyncClient(base_url="https://app.17u.cn/welfarecenter",
verify=False,
timeout=60)
self.phone = cookie.split("#")[0]
self.apptoken = cookie.split("#")[1]
self.device = cookie.split("#")[2]
self.headers = {
'accept': 'application/json, text/plain, */*',
'phone': self.phone,
'channel': '1',
'apptoken': self.apptoken,
'sec-fetch-site': 'same-site',
'accept-language': 'zh-CN,zh-Hans;q=0.9',
'accept-encoding': 'gzip, deflate, br',
'sec-fetch-mode': 'cors',
'origin': 'https://m.17u.cn',
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 TcTravel/11.0.0 tctype/wk',
'referer': 'https://m.17u.cn/',
# 'content-length': str(len(payload_str.encode('utf-8'))),
'device': self.device,
'sec-fetch-dest': 'empty'
}
@staticmethod
async def get_today_date():
return datetime.now().strftime('%Y-%m-%d')
async def sign_in(self):
try:
response = await self.client.post(
url="/index/signIndex",
headers=self.headers,
json={}
)
data = response.json()
if data['code'] != 2200:
fn_print(f"用户【{self.phone}】 - token失效了请更新")
return None
else:
today_sign = data['data']['todaySign']
mileage = data['data']['mileageBalance']['mileage']
fn_print(f"用户【{self.phone}】 - 今日{'' if today_sign else ''}签到,当前剩余里程{mileage}")
return today_sign
except Exception as e:
fn_print(f"用户【{self.phone}】 - 签到请求异常!{e}")
fn_print(response.text)
return None
async def do_sign_in(self):
today_date = await self.get_today_date()
try:
response = await self.client.post(
url="/index/sign",
headers=self.headers,
json={"type": 1, "day": today_date}
)
data = response.json()
if data['code'] != 2200:
fn_print(f"用户【{self.phone}】 - 签到失败了,尝试获取任务列表")
return False
else:
fn_print(f"用户【{self.phone}】 - 签到成功!开始获取任务列表")
return True
except Exception as e:
fn_print(f"用户【{self.phone}】 - 执行签到请求异常!{e}")
fn_print(response.text)
return False
async def get_task_list(self):
try:
response = await self.client.post(
url="/task/taskList?version=11.0.7",
headers=self.headers,
json={}
)
data = response.json()
if data['code'] != 2200:
fn_print(f"用户【{self.phone}】 - 获取任务列表失败了")
return None
else:
tasks = []
for task in data['data']:
if task['state'] == 1 and task['browserTime'] != 0:
tasks.append(
{
'taskCode': task['taskCode'],
'title': task['title'],
'browserTime': task['browserTime']
}
)
return tasks
except Exception as e:
fn_print(f"用户【{self.phone}】 - 获取任务列表请求异常!{e}")
fn_print(response.text)
return None
async def perform_tasks(self, task_code):
try:
response = await self.client.post(
url="/task/start",
headers=self.headers,
json={"taskCode": task_code}
)
data = response.json()
if data['code'] != 2200:
fn_print(f"用户【{self.phone}】 - 执行任务【{task_code}】失败了,跳过当前任务")
return None
else:
task_id = data['data']
return task_id
except Exception as e:
fn_print(f"用户【{self.phone}】 - 执行任务【{task_code}】请求异常!{e}")
fn_print(response.text)
return None
async def finsh_task(self, task_id):
max_retry = 3 # 最大重试次数
retry_delay = 2 # 重试间隔时间(秒)
for attempt in range(max_retry):
try:
response = await self.client.post(
url="/task/finish",
headers=self.headers,
json={"id": task_id}
)
data = response.json()
if data['code'] == 2200:
fn_print(f"用户【{self.phone}】 - 完成任务【{task_id}】成功!开始领取奖励")
return True
if attempt < max_retry - 1:
fn_print(f"用户【{self.phone}】 - 完成任务【{task_id}】失败了,尝试重新提交(第{attempt + 1}次重试。。)")
await asyncio.sleep(retry_delay * (attempt + 1))
continue
fn_print(f"用户【{self.phone}】 - 完成任务【{task_id}】最终失败,跳过当前任务")
return False
except Exception as e:
error_msg = f"用户【{self.phone}】 - 完成任务【{task_id}】请求异常!{e}"
if 'response' in locals():
error_msg += f"\n{response.text}"
fn_print(error_msg)
if attempt == max_retry - 1:
return False
await asyncio.sleep(retry_delay * (attempt + 1))
async def receive_reward(self, task_id):
try:
response = await self.client.post(
url="/task/receive",
headers=self.headers,
json={"id": task_id}
)
data = response.json()
if data['code'] != 2200:
fn_print(f"用户【{self.phone}】 - 领取签到奖励失败了, 请尝试手动领取")
else:
fn_print(f"用户【{self.phone}】 - 领取签到奖励成功!开始下一个任务")
except Exception as e:
fn_print(f"用户【{self.phone}】 - 领取签到奖励请求异常!{e}")
fn_print(response.text)
async def get_mileage_info(self):
try:
response = await self.client.post(
url="/index/signIndex",
headers=self.headers,
json={}
)
data = response.json()
if data['code'] != 2200:
fn_print(f"用户【{self.phone}】 - 获取积分信息失败了")
return None
else:
cycle_sign_num = data['data']['cycleSighNum']
continuous_history = data['data']['continuousHistory']
mileage = data['data']['mileageBalance']['mileage']
today_mileage = data['data']['mileageBalance']['todayMileage']
fn_print(
f"用户【{self.phone}】 - 本月签到{cycle_sign_num}天,连续签到{continuous_history}天,今日共获取{today_mileage}里程,当前剩余里程{mileage}")
except Exception as e:
fn_print(f"用户【{self.phone}】 - 获取积分信息请求异常!{e}")
fn_print(response.text)
return None
async def run(self):
today_sign = await self.sign_in()
if today_sign is None:
return
if today_sign:
fn_print(f"用户【{self.phone}】 - 今日已签到,开始获取任务列表")
else:
if await self.do_sign_in():
fn_print(f"用户【{self.phone}】 - 签到成功,开始获取任务列表")
tasks = await self.get_task_list()
if tasks:
for task in tasks:
task_code = task['taskCode']
title = task['title']
browser_time = task['browserTime']
fn_print(f"用户【{self.phone}】 - 开始做任务【{title}】,需要浏览{browser_time}")
task_id = await self.perform_tasks(task_code)
if task_id:
await asyncio.sleep(browser_time)
if await self.finsh_task(task_id):
await self.receive_reward(task_id)
await self.get_mileage_info()
async def main():
tasks = []
for cookie in tc_cookies:
tclx = Tclx(cookie)
tasks.append(tclx.run())
await asyncio.gather(*tasks)
if __name__ == '__main__':
asyncio.run(main())
send_notification_message_collection(f"同程旅行签到通知 - {datetime.now().strftime('%Y/%m/%d')}")