mirror of
https://github.com/KingJin-web/zy.git
synced 2025-12-16 23:19:32 +08:00
321 lines
12 KiB
Python
321 lines
12 KiB
Python
# 配置说明:
|
||
# 1. 环境变量 QQ_TOKEN: 配置token账号信息支持多账号分隔符:#
|
||
# 2. 环境变量 qqyd_ua: 配置UA信息
|
||
# 3. 可配置过检测接口
|
||
# 4. 环境变量 qqyd_proxy: 配置代理连接,注意代理时长选择!注意代理时长选择!注意代理时长选择!同一账号运行时不要换ip(4.0更新内容)
|
||
# 活动入口 https://img.hnking.cn/blog/202509041844746.png
|
||
|
||
import time, json, random, requests, os
|
||
from urllib.parse import urlparse, parse_qs, unquote
|
||
|
||
PROXY_URL = os.getenv("qqyd_proxy")
|
||
UA_USER_AGENT = os.getenv("qqyd_ua")
|
||
# 配置
|
||
API_URL = '' # 检测文章提交接口URL
|
||
|
||
def get_random_r():
|
||
return str(random.uniform(0, 1))
|
||
|
||
|
||
def gettime():
|
||
return str(int(time.time() * 1000))
|
||
|
||
|
||
def extract_biz(url):
|
||
"""从微信公众号文章链接中提取__biz参数值"""
|
||
# 解析URL
|
||
parsed_url = urlparse(url)
|
||
|
||
# 解析查询参数
|
||
query_params = parse_qs(parsed_url.query)
|
||
|
||
# 提取__biz参数
|
||
if '__biz' in query_params:
|
||
return query_params['__biz'][0]
|
||
else:
|
||
return None
|
||
|
||
|
||
def getHomeInfo():
|
||
"""获取首页信息"""
|
||
url = 'https://read.tslu.cn/abaaba/getHomeInfo/'
|
||
params = {'token': TOKEN}
|
||
headers = {
|
||
'Host': 'read.tslu.cn',
|
||
'Connection': 'keep-alive',
|
||
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
||
'User-Agent': UA_USER_AGENT,
|
||
'Origin': 'http://we.e9l.cn',
|
||
'Sec-Fetch-Site': 'cross-site',
|
||
'Sec-Fetch-Mode': 'cors',
|
||
'Sec-Fetch-Dest': 'empty',
|
||
'Referer': 'http://we.e9l.cn/',
|
||
'Accept-Encoding': 'gzip, deflate, br',
|
||
'Accept-Language': 'zh-CN,zh;q=0.9',
|
||
}
|
||
try:
|
||
response = requests.get(url, headers=headers, params=params,proxies=proxies).json()
|
||
if response.get('code') == 0:
|
||
home_data = response.get('data', {})
|
||
print(
|
||
f"首页信息 - 用户ID: {home_data.get('id', '未知')} | 累计阅读: {home_data.get('dayreads', 0)}天 | 金币: {home_data.get('gold', 0)}")
|
||
return home_data
|
||
else:
|
||
print(f"首页信息获取失败: {response.get('msg', '未知错误')}")
|
||
except Exception as e:
|
||
print(f"首页信息请求异常: {str(e)}")
|
||
return None
|
||
|
||
|
||
def getReadUrl():
|
||
url = 'https://read.tslu.cn/abaaba/getReadUrl/'
|
||
headers = {
|
||
'Host': 'read.tslu.cn',
|
||
'Connection': 'keep-alive',
|
||
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
||
'User-Agent': UA_USER_AGENT,
|
||
'Origin': 'http://we.e9l.cn',
|
||
'Sec-Fetch-Site': 'cross-site',
|
||
'Sec-Fetch-Mode': 'cors',
|
||
'Sec-Fetch-Dest': 'empty',
|
||
'Referer': 'http://we.e9l.cn/',
|
||
'Accept-Encoding': 'gzip, deflate, br',
|
||
'Accept-Language': 'zh-CN,zh;q=0.9',
|
||
}
|
||
params = {'type': 2,'b': str(int(time.time()*1000)), 'token': TOKEN}
|
||
|
||
try:
|
||
response = requests.get(url, headers=headers, params=params, proxies=proxies).json()
|
||
parsed_url = urlparse(response['data']['url'])
|
||
outer_params = parse_qs(parsed_url.query)
|
||
inner_url_encoded = outer_params.get('query', [''])[0]
|
||
inner_url = unquote(inner_url_encoded)
|
||
parsed_inner = urlparse(inner_url)
|
||
inner_params = parse_qs(parsed_inner.query)
|
||
t = inner_params.get('t', ['未获取t'])[0]
|
||
u = inner_params.get('u', ['未获取u'])[0]
|
||
ch = inner_params.get('ch', ['未获取ch'])[0]
|
||
return t, u, ch
|
||
except Exception as e:
|
||
print(f"参数获取异常: {str(e)}")
|
||
return '未获取t', '未获取u', '未获取ch'
|
||
|
||
|
||
def check_article(aid, article_url):
|
||
"""文章检测逻辑"""
|
||
print(f"检测文章 [ID:{aid}]")
|
||
if not API_URL:
|
||
print(f"未配置自动过检进入通知推送手动,请在面板配置文件设置对应推送..")
|
||
title = "⚠️ QQ检测文章!请在60s内完成阅读!⚠️ 每次阅读不得少于8秒!"
|
||
content = f"文章链接:{article_url} 当前时间 {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 当前时间 {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}"
|
||
print(QLAPI.notify(title, content))
|
||
time.sleep(60)
|
||
return True
|
||
else:
|
||
try:
|
||
resp = requests.post(API_URL, json={"url": article_url,'token': TOKEN,'ua':UA_USER_AGENT,'proxies':proxies}, timeout=60).json()
|
||
if resp['status'] == 'success':
|
||
time.sleep(8)
|
||
print("✅ 自动过检成功")
|
||
return True
|
||
else:
|
||
print(f"❌ 自动过检失败: {resp['message']}")
|
||
return False
|
||
except Exception as e:
|
||
print(f"过检请求异常: {e}")
|
||
return False
|
||
|
||
|
||
def sign_in():
|
||
"""执行签到"""
|
||
print("\n--- 执行签到 ---")
|
||
sign_url = "https://read.tslu.cn/abaaba/getxshd/"
|
||
headers = {
|
||
'Host': 'read.tslu.cn',
|
||
'Connection': 'keep-alive',
|
||
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
||
'User-Agent': UA_USER_AGENT,
|
||
'Origin': 'http://we.e9l.cn',
|
||
'Sec-Fetch-Site': 'cross-site',
|
||
'Sec-Fetch-Mode': 'cors',
|
||
'Sec-Fetch-Dest': 'empty',
|
||
'Referer': 'http://we.e9l.cn/',
|
||
'Accept-Encoding': 'gzip, deflate, br',
|
||
'Accept-Language': 'zh-CN,zh;q=0.9',
|
||
}
|
||
params = {'token': TOKEN}
|
||
|
||
try:
|
||
response = requests.get(sign_url, params=params, headers=headers, proxies=proxies).json()
|
||
if response.get("code") == 0:
|
||
print(f"签到成功! 获得金币: {response.get('golds', 0)}")
|
||
getHomeInfo() # 刷新金币显示
|
||
else:
|
||
print(f"签到失败: {response.get('msg', '未知错误')}")
|
||
except Exception as e:
|
||
print(f"签到请求异常: {str(e)}")
|
||
print("--- 签到结束 ---\n")
|
||
|
||
|
||
def make_request(loop_count, initial_params, headers):
|
||
"""主循环请求逻辑"""
|
||
url = "https://rdapi.hzjianyue.cn/api/articleTask0428"
|
||
current_jkey = None
|
||
current_params = initial_params.copy()
|
||
current_c = 1
|
||
user_id = initial_params.get("u", "")
|
||
channel_id = initial_params.get("ch", "")
|
||
|
||
for i in range(loop_count):
|
||
print(f"\n[第{i + 1}次循环] c值: {current_c}")
|
||
|
||
# 准备请求参数
|
||
params = current_params.copy()
|
||
params["c"] = current_c
|
||
params["r"] = get_random_r()
|
||
if i > 0 and current_jkey:
|
||
params["jkey"] = current_jkey
|
||
|
||
try:
|
||
response = requests.get(url, params=params, headers=headers,proxies=proxies)
|
||
response.raise_for_status()
|
||
result = response.json()
|
||
|
||
# 检测第5轮完成
|
||
if result.get("code") == 1 and not result.get("data") and "第5轮已经完成" in result.get("msg", ""):
|
||
print(f"检测到第5轮完成,任务结束!")
|
||
sign_in()
|
||
return
|
||
|
||
# 检测其他轮次完成
|
||
if result.get("code") == 1 and not result.get("data") and "轮已经完成" in result.get("msg", ""):
|
||
print(f"轮次完成: {result.get('msg')},终止循环")
|
||
getHomeInfo()
|
||
return
|
||
|
||
# 检测其他轮次完成
|
||
if result.get("code") == 1 and not result.get("data") and "暂时没有文章可供阅读" in result.get("msg", ""):
|
||
print(f"轮次完成: {result.get('msg')},终止循环")
|
||
getHomeInfo()
|
||
return
|
||
|
||
# 检测其他轮次完成
|
||
if result.get("code") == 1 and not result.get("data") and "您阅读数量已达今日上限" in result.get("msg", ""):
|
||
print(f"轮次完成: {result.get('msg')},终止循环")
|
||
getHomeInfo()
|
||
return
|
||
|
||
# 检测其他轮次完成
|
||
if result.get("code") == 1 and not result.get("data") and "前被微信判断为无效用户" in result.get("msg", ""):
|
||
print(f"轮次完成: {result.get('msg')},终止循环")
|
||
getHomeInfo()
|
||
return
|
||
|
||
# 检测链接失效
|
||
if result.get("code") == 1 and result.get("msg") == "当前链接已失效, 请获取最新链接哦" and not result.get(
|
||
"data"):
|
||
print("链接失效,重新获取参数...")
|
||
new_t, new_u, new_ch = getReadUrl()
|
||
current_params.update({"t": new_t, "u": new_u, "ch": new_ch})
|
||
user_id, channel_id = new_u, new_ch
|
||
current_jkey = None
|
||
current_c = 1
|
||
continue
|
||
|
||
# 处理正常响应
|
||
if result.get("code") == 0:
|
||
data = result.get("data", {})
|
||
current_jkey = data.get("jkey")
|
||
aid = data.get("aid", 0)
|
||
article_url = data.get("url", "")
|
||
|
||
_biz = extract_biz(article_url)
|
||
print(f"📖 开始阅读: {article_url}", flush=True)
|
||
print(f"文章信息 - : {_biz} | 已读/总数: {data.get('readNum', 0)}/{data.get('totalNum', 0)}")
|
||
if _biz in ['MzkyNzYxMDA0Mw==','MzkzNzk3Mjk2MQ==','MzkyMjYxMDAwMA==','Mzk3NTc4MzI1NQ==',
|
||
'MzI5MjYyNDIxOA==','Mzk0OTYxMDEwNQ==','MzkzNjk3MjIxNg==','MzkzMTk0ODYxOQ==',
|
||
'MzkzODk3Mjk2NQ==','MzIwOTc0MzYxMg==','MzkyOTk0NzcyNw==','MzkxOTg4MjUzOA==','Mzk4ODQ2OTYyMg==',
|
||
'MzkzMjk3MDgxNQ==','MzkzOTYxMDQ2Mw==','MzkzODk0NzkwMg==','MzkwODYwOTUxOQ=='] or len(current_jkey) > 35:
|
||
if not check_article(_biz, article_url):
|
||
return
|
||
|
||
current_c += 1
|
||
else:
|
||
print(f"请求异常: {result.get('msg', '未知错误')}")
|
||
current_c += 1
|
||
|
||
except requests.exceptions.RequestException as e:
|
||
print(f"网络请求错误: {e}")
|
||
current_c += 1
|
||
except json.JSONDecodeError:
|
||
print("响应格式错误")
|
||
current_c += 1
|
||
|
||
# 延迟处理
|
||
if i < loop_count - 1:
|
||
delay = random.randint(8, 20)
|
||
print(f"等待{delay}秒...")
|
||
time.sleep(delay)
|
||
|
||
print(f"\n所有{loop_count}次循环完成")
|
||
getHomeInfo()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
print("活动入口:https://img.hnking.cn/blog/202509041844746.png")
|
||
QQ_TOKEN = os.getenv('QQ_TOKEN')
|
||
if not QQ_TOKEN:
|
||
print("请先配置账号信息(QQ_TOKEN)")
|
||
exit()
|
||
|
||
if UA_USER_AGENT:
|
||
print(f"✅ 已配置代理: {UA_USER_AGENT}")
|
||
else:
|
||
print("ℹ️ 未配置ua,停止运行")
|
||
exit()
|
||
|
||
if PROXY_URL:
|
||
print(f"✅ 已配置代理: {PROXY_URL}")
|
||
else:
|
||
print("ℹ️ 未配置代理,采用本地请求")
|
||
|
||
TOKENS = QQ_TOKEN.split('#')
|
||
print(f"共{len(TOKENS)}个账号")
|
||
for TOKEN in TOKENS:
|
||
proxies = {}
|
||
if PROXY_URL:
|
||
try:
|
||
get_ip = requests.get(PROXY_URL).text.strip()
|
||
print('获取代理:{0}'.format(get_ip))
|
||
proxies = {
|
||
"http": f"http://{get_ip}",
|
||
"https": f"http://{get_ip}",
|
||
}
|
||
except Exception as e:
|
||
print('获取代理失败,使用本地网络执行')
|
||
getHomeInfo() # 初始首页信息
|
||
t, u, ch = getReadUrl()
|
||
|
||
initial_params = {
|
||
"t": t,
|
||
"u": u,
|
||
"ch": ch,
|
||
"pageshow": "",
|
||
}
|
||
|
||
headers = {
|
||
"Host": "rdapi.hzjianyue.cn",
|
||
"Connection": "keep-alive",
|
||
"User-Agent": UA_USER_AGENT,
|
||
"X-Requested-With": "XMLHttpRequest",
|
||
"Accept": "*/*",
|
||
"Sec-Fetch-Site": "cross-site",
|
||
"Sec-Fetch-Mode": "cors",
|
||
"Sec-Fetch-Dest": "empty",
|
||
"Accept-Encoding": "gzip, deflate, br",
|
||
"Accept-Language": "zh-CN,zh;q=0.9"
|
||
}
|
||
|
||
loop_times = 39
|
||
print(f"\n开始执行{loop_times}次循环...")
|
||
make_request(loop_times, initial_params, headers) |