Initial Qinglong script classification corpus

This commit is contained in:
Hermes Agent
2026-05-23 18:48:48 +00:00
commit 5b4854515c
32 changed files with 15496 additions and 0 deletions

View File

@@ -0,0 +1,563 @@
// # Source: https://github.com/huwangkeji/juejin_checkin/blob/main/juejin_checkin.js
// # Raw: https://raw.githubusercontent.com/huwangkeji/juejin_checkin/main/juejin_checkin.js
// # Repo: huwangkeji/juejin_checkin
// # Path: juejin_checkin.js
// # UploadedAt: 2026-05-19T14:34:11Z
// # SHA256: 6f8a138b51c397220444c9312040dbe3407af5aeed4fa4467a36672aeb8bcfd1
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
* @name 掘金自动签到脚本
* @description 掘金社区每日签到 + 免费抽奖 + 沾喜气 + Bug消除支持Cookie自动签到
* @namespace https://juejin.cn
* @version 1.0.0
* @author CodeBuddy
*
* 【青龙面板使用说明】
* 1. 依赖管理 -> NodeJS -> 添加依赖: axios
* 2. 环境变量 (必填):
* - JUEJIN_COOKIE: 掘金Cookie (从浏览器开发者工具复制)
* - JUEJIN_AID: API参数aid (通常为2608)
* - JUEJIN_UUID: API参数uuid
* - JUEJIN_MSTOKEN: API参数msToken
* - JUEJIN_A_BOGUS: API参数a_bogus
* 3. 环境变量 (可选):
* - JUEJIN_COOKIE_2 ~ JUEJIN_COOKIE_5: 多账号Cookie
* - JUEJIN_NOTIFY: 是否推送通知 (默认true)
* 4. 定时规则: 30 6 * * * (每天早上6:30执行)
*
* 【参数获取方式】
* 1. 浏览器打开 https://juejin.cn 并登录
* 2. 按F12打开开发者工具 -> Network(网络)标签
* 3. 刷新页面,找到任意一个 api.juejin.cn 的请求
* 4. 在 Request Headers 中复制完整的 Cookie 值
* 5. 在 Query String Parameters 中复制 aid, uuid, msToken, a_bogus
* 6. 粘贴到青龙面板对应的环境变量中
* 7. Cookie和参数有效期约30天过期后需重新获取
*
* 【功能列表】
* - Cookie自动签到支持多账号
* - 每日签到
* - 免费抽奖
* - 沾喜气
* - Bug消除
* - 查询矿石余额/签到天数/幸运值
* - 青龙面板通知推送
*/
const axios = require('axios');
// ==================== 配置区域 ====================
const API_BASE = 'https://api.juejin.cn';
// 请求头
const DEFAULT_HEADERS = {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
'Referer': 'https://juejin.cn/',
'Origin': 'https://juejin.cn',
'Content-Type': 'application/json',
'sec-ch-ua': '"Not/A)Brand";v="99", "Chromium";v="148"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
};
// ==================== 工具函数 ====================
function log(msg) {
const now = new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
console.log(`[${now}] ${msg}`);
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* 创建带Cookie和参数的axios实例
*/
function createApiClient(cookie, params) {
const instance = axios.create({
baseURL: API_BASE,
headers: {
...DEFAULT_HEADERS,
Cookie: cookie,
},
timeout: 30000,
});
// 请求拦截 - 自动添加查询参数
instance.interceptors.request.use((config) => {
if (params && Object.keys(params).length > 0) {
config.params = { ...config.params, ...params };
}
// POST请求body为空对象
if (config.method === 'post' && !config.data) {
config.data = {};
}
return config;
});
// 响应拦截
instance.interceptors.response.use(
(response) => {
const data = response.data;
// 处理空响应
if (data === '' || data === null || data === undefined) {
throw new Error('API返回空响应可能需要更新参数');
}
if (typeof data === 'object' && data.err_no !== 0) {
throw new Error(`API错误: [${data.err_no}] ${data.err_msg || '未知错误'}`);
}
return data.data;
},
(error) => {
if (error.response) {
const data = error.response.data;
if (data && typeof data === 'object' && data.err_no !== undefined) {
throw new Error(`API错误: [${data.err_no}] ${data.err_msg || '未知错误'}`);
}
throw new Error(`HTTP错误: ${error.response.status} ${error.response.statusText}`);
}
throw error;
}
);
return instance;
}
// ==================== API 调用 ====================
/**
* 检查今日签到状态
*/
async function getTodayStatus(api) {
try {
const data = await api.get('/growth_api/v1/get_today_status');
return data === true;
} catch (e) {
log('⚠️ 查询签到状态失败: ' + e.message);
return null;
}
}
/**
* 执行签到
*/
async function checkIn(api) {
try {
const data = await api.post('/growth_api/v1/check_in');
log('✅ 签到成功!');
return { success: true, data };
} catch (e) {
if (e.message.includes('15001') || e.message.includes('已签到') || e.message.includes('duplicate')) {
log('📌 今日已签到,无需重复签到');
return { success: true, already: true };
}
if (e.message.includes('3013')) {
log('📌 今日已签到 (3013)');
return { success: true, already: true };
}
if (e.message.includes('空响应')) {
log('⚠️ API返回空响应参数可能已过期建议重新获取');
return { success: false, error: e.message };
}
log('❌ 签到失败: ' + e.message);
return { success: false, error: e.message };
}
}
/**
* 获取签到天数统计
*/
async function getCounts(api) {
try {
const data = await api.get('/growth_api/v1/get_counts');
return data;
} catch (e) {
log('⚠️ 获取签到统计失败: ' + e.message);
return null;
}
}
/**
* 获取当前矿石数
*/
async function getCurrentPoint(api) {
try {
const data = await api.get('/growth_api/v1/get_cur_point');
return data;
} catch (e) {
log('⚠️ 获取矿石余额失败: ' + e.message);
return null;
}
}
/**
* 获取抽奖配置
*/
async function getLotteryConfig(api) {
try {
const data = await api.get('/growth_api/v1/lottery_config/get');
return data;
} catch (e) {
log('⚠️ 获取抽奖配置失败: ' + e.message);
return null;
}
}
/**
* 免费抽奖
*/
async function drawLottery(api) {
try {
const data = await api.post('/growth_api/v1/lottery/draw');
log('🎉 抽奖成功!奖品: ' + (data.lottery_name || '未知'));
return { success: true, data };
} catch (e) {
log('❌ 抽奖失败: ' + e.message);
return { success: false, error: e.message };
}
}
/**
* 沾喜气
*/
async function dipLucky(api) {
try {
// 先获取幸运用户列表
const luckyUsers = await api.post('/growth_api/v1/lottery_history/global_big', {
page_no: 1,
page_size: 5,
});
if (luckyUsers && luckyUsers.lotteries && luckyUsers.lotteries.length > 0) {
const historyId = luckyUsers.lotteries[0].history_id;
const data = await api.post('/growth_api/v1/lottery_lucky/dip_lucky', {
lottery_history_id: historyId,
});
log('🍀 沾喜气成功!幸运值: ' + (data.dip_value || 0));
return { success: true, data };
}
log('⚠️ 暂无可沾喜气的用户');
return { success: false };
} catch (e) {
log('❌ 沾喜气失败: ' + e.message);
return { success: false, error: e.message };
}
}
/**
* 获取我的幸运值
*/
async function getMyLucky(api) {
try {
const data = await api.post('/growth_api/v1/lottery_lucky/my_lucky');
return data;
} catch (e) {
log('⚠️ 获取幸运值失败: ' + e.message);
return null;
}
}
/**
* 查询用户信息 (验证Cookie有效性)
*/
async function getUserInfo(api) {
try {
const data = await api.get('/user_api/v1/user/get');
return data;
} catch (e) {
log('⚠️ Cookie无效或已过期: ' + e.message);
return null;
}
}
/**
* 获取Bug消除配置
*/
async function getBugFixConfig(api) {
try {
const data = await api.get('/growth_api/v1/bugfix/not_collect');
return data;
} catch (e) {
log('⚠️ 获取Bug配置失败: ' + e.message);
return null;
}
}
/**
* 消除Bug
*/
async function fixBug(api, bugId) {
try {
const data = await api.post('/growth_api/v1/bugfix/collect', {
bug_type: bugId,
});
log('🐛 Bug消除成功');
return { success: true, data };
} catch (e) {
log('❌ Bug消除失败: ' + e.message);
return { success: false, error: e.message };
}
}
// ==================== 青龙面板通知 ====================
/**
* 青龙面板通知推送
*/
async function sendNotify(title, content) {
if (process.env.JUEJIN_NOTIFY === 'false') {
log('📢 通知已禁用');
return;
}
try {
// 尝试加载青龙面板的通知模块
const notifyPath = require('path').join(process.cwd(), 'notify.js');
if (require('fs').existsSync(notifyPath)) {
const sendNotifyFn = require(notifyPath);
if (typeof sendNotifyFn === 'function') {
await sendNotifyFn(title, content);
log('📢 青龙通知已发送');
return;
}
}
// 尝试从全局加载
try {
const { sendNotify: qinglongNotify } = require('qlnotify');
await qinglongNotify(title, content);
log('📢 青龙通知已发送');
return;
} catch (e) {
// 忽略
}
log('📢 青龙通知模块未找到,仅控制台输出');
} catch (e) {
log('⚠️ 发送通知失败: ' + e.message);
}
}
// ==================== 单个账号签到流程 ====================
async function runAccount(cookie, params, index) {
const prefix = index > 1 ? `[账号${index}] ` : '';
log('');
log(`${prefix}═══════════════════════════════════════`);
log(`${prefix} 开始处理账号 ${index}`);
log(`${prefix}═══════════════════════════════════════`);
if (!cookie || cookie.trim().length === 0) {
log(`${prefix}❌ Cookie为空跳过`);
return null;
}
// 创建API客户端
const api = createApiClient(cookie, params);
// 验证Cookie有效性
log(`${prefix}🔍 验证Cookie...`);
const userInfo = await getUserInfo(api);
if (!userInfo) {
log(`${prefix}❌ Cookie已失效请重新获取`);
return {
success: false,
error: 'Cookie已失效',
userName: '未知用户',
};
}
const userName = userInfo.user_name || userInfo.nick_name || '未知用户';
log(`${prefix}✅ Cookie有效用户: ${userName}`);
// 签到
log(`${prefix}📅 执行签到...`);
const todayStatus = await getTodayStatus(api);
let signInResult = { success: true, already: todayStatus === true };
if (todayStatus === true) {
log(`${prefix}📌 今日已签到,跳过`);
} else if (todayStatus === false) {
signInResult = await checkIn(api);
if (!signInResult.success) {
log(`${prefix}🔄 签到失败1秒后重试...`);
await sleep(1000);
signInResult = await checkIn(api);
}
} else {
log(`${prefix}⚠️ 无法查询签到状态,直接尝试签到...`);
signInResult = await checkIn(api);
}
// 抽奖
log(`${prefix}🎰 执行抽奖...`);
const lotteryConfig = await getLotteryConfig(api);
let lotteryResult = { success: false };
if (lotteryConfig && lotteryConfig.free_count > 0) {
log(`${prefix}🎁 有 ${lotteryConfig.free_count} 次免费抽奖机会`);
lotteryResult = await drawLottery(api);
} else if (lotteryConfig) {
log(`${prefix}📌 今日免费抽奖次数已用完`);
}
// 沾喜气
log(`${prefix}🍀 沾喜气...`);
const dipResult = await dipLucky(api);
// Bug消除
log(`${prefix}🐛 消除Bug...`);
const bugConfig = await getBugFixConfig(api);
let bugFixResult = { success: false };
if (bugConfig && Array.isArray(bugConfig) && bugConfig.length > 0) {
const bug = bugConfig[0];
log(`${prefix}🔧 发现未消除的Bug: ${bug.bug_type}`);
bugFixResult = await fixBug(api, bug.bug_type);
} else {
log(`${prefix}📌 暂无Bug可消除`);
}
// 查询统计信息
log(`${prefix}📊 查询统计...`);
const counts = await getCounts(api);
const point = await getCurrentPoint(api);
const lucky = await getMyLucky(api);
if (counts) {
log(`${prefix}📅 连续签到: ${counts.cont_count || 0}`);
log(`${prefix}📅 累计签到: ${counts.sum_count || 0}`);
}
if (point !== null) {
log(`${prefix}💰 当前矿石: ${point}`);
}
if (lucky) {
log(`${prefix}🍀 幸运值: ${lucky.total_value || 0}`);
}
log(`${prefix}✅ 账号处理完成`);
return {
success: true,
userName,
signIn: signInResult,
lottery: lotteryResult,
dip: dipResult,
bugFix: bugFixResult,
counts,
point,
lucky,
};
}
// ==================== 主流程 ====================
async function main() {
log('═══════════════════════════════════════');
log(' 掘金自动签到脚本 v1.0.0');
log('═══════════════════════════════════════');
// 收集所有账号的配置
const accounts = [];
// 主账号
const mainCookie = process.env.JUEJIN_COOKIE || '';
const mainParams = {
aid: process.env.JUEJIN_AID || '2608',
uuid: process.env.JUEJIN_UUID || '',
msToken: process.env.JUEJIN_MSTOKEN || '',
a_bogus: process.env.JUEJIN_A_BOGUS || '',
spider: '0',
};
if (mainCookie) {
accounts.push({ cookie: mainCookie, params: mainParams });
}
// 多账号支持
for (let i = 2; i <= 5; i++) {
const cookie = process.env[`JUEJIN_COOKIE_${i}`] || '';
if (cookie) {
accounts.push({
cookie,
params: {
aid: process.env[`JUEJIN_AID_${i}`] || mainParams.aid,
uuid: process.env[`JUEJIN_UUID_${i}`] || '',
msToken: process.env[`JUEJIN_MSTOKEN_${i}`] || '',
a_bogus: process.env[`JUEJIN_A_BOGUS_${i}`] || '',
spider: '0',
},
});
}
}
if (accounts.length === 0) {
log('');
log('❌ 未配置Cookie请设置环境变量 JUEJIN_COOKIE');
log('');
log('【参数获取方式】');
log('1. 浏览器打开 https://juejin.cn 并登录');
log('2. 按F12打开开发者工具 -> Network(网络)标签');
log('3. 刷新页面,找到任意一个 api.juejin.cn 的请求');
log('4. 在 Request Headers 中复制完整的 Cookie 值');
log('5. 在 Query String Parameters 中复制 aid, uuid, msToken, a_bogus');
log('6. 粘贴到青龙面板对应的环境变量中');
log('');
process.exit(1);
}
log(`📱 共配置 ${accounts.length} 个账号`);
// 执行每个账号的签到
const results = [];
for (let i = 0; i < accounts.length; i++) {
const result = await runAccount(accounts[i].cookie, accounts[i].params, i + 1);
if (result) results.push(result);
}
// 生成通知内容
log('');
log('📢 发送通知...');
let notifyTitle = '掘金每日签到报告';
let notifyContent = '';
for (let i = 0; i < results.length; i++) {
const r = results[i];
const prefix = results.length > 1 ? `【账号${i + 1}` : '';
if (!r.success) {
notifyContent += `${prefix}${r.userName}: ${r.error}\n`;
continue;
}
notifyContent += `${prefix}👤 ${r.userName}\n`;
notifyContent += ` 📅 连续签到: ${r.counts?.cont_count || 0}\n`;
notifyContent += ` 📅 累计签到: ${r.counts?.sum_count || 0}\n`;
notifyContent += ` 💰 当前矿石: ${r.point ?? '未知'}\n`;
notifyContent += ` 🍀 幸运值: ${r.lucky?.total_value || 0}\n`;
notifyContent += ` ✅ 签到: ${r.signIn.already ? '今日已签到' : r.signIn.success ? '成功' : '失败'}\n`;
notifyContent += ` 🎰 抽奖: ${r.lottery.success ? '成功 - ' + (r.lottery.data?.lottery_name || '') : '未抽奖/失败'}\n`;
notifyContent += ` 🍀 沾喜气: ${r.dip.success ? '成功' : '失败'}\n`;
notifyContent += ` 🐛 Bug消除: ${r.bugFix.success ? '成功' : '无/失败'}\n`;
notifyContent += '\n';
}
await sendNotify(notifyTitle, notifyContent);
log('');
log('═══════════════════════════════════════');
log(' 脚本执行完成!');
log('═══════════════════════════════════════');
}
// 执行主函数
main().catch((error) => {
log('💥 脚本异常退出: ' + error.message);
console.error(error);
process.exit(1);
});

View File

@@ -0,0 +1,352 @@
# Source: https://github.com/lksky8/sign-ql/blob/main/3dmgame.py
# Raw: https://raw.githubusercontent.com/lksky8/sign-ql/main/3dmgame.py
# Repo: lksky8/sign-ql
# Path: 3dmgame.py
# UploadedAt: 2026-03-27T20:17:30Z
# SHA256: 2262c9f7c2d40c8ef9822325fadd2e8ed3c43ba0f609c072a27c49b02edc2eaa
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
作者https://github.com/lksky8/sign-ql/
日期2026-3-28
网站3dmgame论坛签到
功能:签到、抽奖,金币可换现金买游戏
食用方法登录论坛后浏览器F12打开抓包https://bbs.3dmgame.com/home.php?mod=spacecp&ac=credit&showcredit=1抓这个url请求头的cookie包
变量bbs3dmck='cookie' 多个账号用换行分割
定时一天三次
青龙需要安装lxml模块
cron: 0 9 */8 * * *
"""
import time
import requests
from lxml import etree
import re
import random
import os
send_msg = ''
one_msg = ''
def Log(cont=''):
global send_msg, one_msg
if cont:
one_msg += f'{cont}\n'
send_msg += f'{cont}\n'
# 发送通知消息
def send_notification_message(title):
try:
from notify import send
print("加载通知服务成功!")
send(title, send_msg)
except Exception as e:
print('发送通知消息失败!' + str(e))
class ThreeDMGame:
def __init__(self, cookies):
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': 'https://bbs.3dmgame.com',
'Pragma': 'no-cache',
'Sec-Fetch-Dest': 'iframe',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-User': '?1',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36',
'sec-ch-ua': '"Chromium";v="146", "Not-A.Brand";v="24", "Google Chrome";v="146"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'Cookie': cookies,
}
self.session = requests.Session()
self.session.headers.update(headers)
def user_info(self):
try:
response = self.session.get('https://bbs.3dmgame.com/home.php?mod=spacecp&ac=credit&showcredit=1')
html = etree.HTML(response.text)
user_id = html.xpath('//*[@id="hd"]/div/div[1]/p/strong/a/text()')[0]
points = html.xpath('//*[@id="extcreditmenu"]/text()')[0]
gold = html.xpath('//*[@id="ct"]/div[1]/div/ul[2]/li[1]/text()')[0]
print(f'用户ID[{user_id}] {points} 金元:{gold}')
Log(f'\n用户ID[{user_id}] {points} 金元:{gold}')
except Exception as e:
print('3dmgame论坛用户信息获取失败', e)
Log(f'\n3dmgame论坛用户信息获取失败')
def task_view(self, t_id):
try:
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=view&id={t_id}')
html = etree.HTML(response.text)
task_name = html.xpath('//h1[contains(@class, "xs2") and contains(@class, "ptm") and contains(@class, "pbm")]/text()')[0].strip()
if 'do=apply' in response.text:
print(f'任务:《{task_name}》 可申请')
elif '后可以再次申请' in response.text:
print(f'任务:《{task_name}》 未到申请时间')
elif '您所在的用户组无法申请此任务' in response.text:
print(f'任务:《{task_name}》 您所在的用户组无法申请此任务')
elif 'static/image/task/reward.gif' in response.text:
print(f'任务:《{task_name}》 任务已完成,待领取奖励')
else:
print(f'任务:《{task_name}》 未知状态')
except Exception as e:
print(f'查看任务信息失败:{t_id} {e}')
def check_task(self):
try:
response = self.session.get('https://bbs.3dmgame.com/home.php?mod=task')
# print(response.text)
html = etree.HTML(response.text)
task_rows = html.xpath('//div[@class="ptm"]//table//tr')
# for row in task_rows:
# # 提取任务名称
# task_name = row.xpath('.//td[2]//h3/a/text()')[0] if row.xpath('.//td[2]//h3/a/text()') else ""
#
# # 提取任务描述
# description = row.xpath('.//td[2]/p/text()')[0] if row.xpath('.//td[2]/p/text()') else ""
#
# # 提取任务奖励
# reward = row.xpath('.//td[3]/text()')[0].strip() if row.xpath('.//td[3]/text()') else ""
#
# # 提取任务状态(可申请/不可申请)
# is_available = len(row.xpath('.//td[4]//img[@alt="apply"]')) > 0
#
# apply_link = row.xpath('.//td[4]/a[contains(@href, "do=apply")]/@href')[0] if row.xpath('.//td[4]/a[contains(@href, "do=apply")]/@href') else "无可用申请链接"
#
# print(f"任务名称: {task_name}")
# print(f"申请链接: {apply_link}")
# print(f"描述: {description}")
# print(f"奖励: {reward}")
# print(f"是否可申请: {'是' if is_available else '否'}")
# print("---")
task_list = {}
for row in task_rows:
task_name = row.xpath('.//td[2]//h3/a/text()')[0] if row.xpath('.//td[2]//h3/a/text()') else ""
description = row.xpath('.//td[2]/p/text()')[0] if row.xpath('.//td[2]/p/text()') else ""
reward = row.xpath('.//td[3]/text()')[0].strip() if row.xpath('.//td[3]/text()') else ""
apply_links = row.xpath('.//td[4]/a[contains(@href, "do=apply")]/@href')
# 只处理有可用申请链接的任务
if apply_links:
apply_link = apply_links[0]
print(f"任务名称: {task_name}")
print(f"描述: {description}")
print(f"奖励: {reward}")
# print(f"任务id: {apply_link.split('id=')[-1]}")
print("-" * 50)
task_list.update({task_name: apply_link.split('id=')[-1]})
if len(task_list) > 0:
print(f'获取到{len(task_list)}个可接任务')
for name, link_id in task_list.items():
print('*' * 30)
print(f'尝试领取任务:{name}')
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=apply&id={link_id}')
if 'do=draw' in response.text:
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=draw&id={link_id}')
if '恭喜您,任务已成功完成,您将收到奖励通知,请注意查收' in response.text:
print(f'任务:{name} 直接完成')
else:
print(f'任务:{name} 失败' + response.text)
elif '申请此任务需要先完成另一个任务' in response.text:
html_message = etree.HTML(response.text)
qianzhi_task = html_message.xpath('//div[@id="messagetext"]//p[@class="alert_btnleft"]/a/@href')[0].split("id=")[-1]
print(f'任务:{name} 领取失败 | 原因是前置任务未完成跳转前置任务id{qianzhi_task}')
self.task_view(qianzhi_task)
elif '任务申请成功' in response.text:
print(f'任务:{name} 领取成功')
elif '不是进行中的任务' in response.text:
print(f'任务:{name} 无法直接完成')
else:
print(f'任务:{name} 领取失败')
print(response.text)
time.sleep(1)
print('-' * 50)
else:
print('没有可接任务')
# Log(f'\n没有可接任务')
print('-' * 50)
except Exception as e:
print(f'检查任务信息失败:{e}')
def check_task_doing(self):
try:
response = self.session.get('https://bbs.3dmgame.com/home.php?mod=task&item=doing')
# print(response.text)
html = etree.HTML(response.text)
task_rows = html.xpath('//div[@class="ptm"]//table//tr')
task_list = []
for row in task_rows:
# 提取任务名称
task_name = row.xpath('.//td[2]//h3/a/text()')[0] if row.xpath('.//td[2]//h3/a/text()') else ""
# 提取任务ID
task_id = row.xpath('.//td[2]//h3/a/@href')[0].split('id=')[-1] if row.xpath('.//td[2]//h3/a/@href') else ""
# 提取do=view链接任务详情链接
# view_link = row.xpath('.//td[2]//h3/a[contains(@href, "do=view")]/@href')[0] if row.xpath('.//td[2]//h3/a[contains(@href, "do=view")]/@href') else ""
# 提取领取链接(do=draw类型)
# draw_links = row.xpath('.//td[4]/p/a[contains(@href, "do=draw")]/@href')[0] if row.xpath('.//td[4]/p/a/@href') else ""
print(f"进行中的任务: 《{task_name}")
task_list.append({task_name: task_id})
print('-' * 30)
if len(task_list) > 0:
return task_list
else:
print('没有进行中的任务')
# Log(f'\n没有进行中的任务')
return []
except Exception as e:
print(f'检查任务进行中失败:{e}')
def do_task(self, tk_list):
print(f'获取到{len(tk_list)}个待完成任务')
for task_name, task_id in tk_list.items():
print(f'尝试完成任务:《{task_name}')
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=view&id={task_id}')
if 'static/image/task/reward.gif' in response.text:
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=draw&id={task_id}')
if '恭喜您,任务已成功完成,您将收到奖励通知,请注意查收' in response.text:
print(f'任务:《{task_name}》 完成')
else:
print(f'任务:《{task_name}》 失败')
print(response.text)
elif '完成此任务所需条件' in response.text:
print(f'任务:《{task_name}》 无完成条件')
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=draw&id={task_id}')
if '恭喜您,任务已成功完成,您将收到奖励通知,请注意查收' in response.text:
print(f'任务:《{task_name}》 完成')
else:
print(f'任务:《{task_name}》 失败')
print(response.text)
else:
print(f'任务:《{task_name}》 有完成条件')
tree = etree.HTML(response.text)
tables = tree.xpath("//table[@class='tfm']//td[@class='bbda']/a/@href")[0]
# print(tables)
reply_td = tree.xpath("//table[@class='tfm']//td[@class='bbda'][contains(., '')]/text()[normalize-space()]")[1]
reply_td = reply_td.replace(' ', '')
# print(reply_td)
reply_count = re.search(r'(\d+)次', reply_td).group(1) if re.search(r'(\d+)次', reply_td) else "未知"
if 'thread' in tables:
response = self.session.get(f'https://bbs.3dmgame.com/{tables}')
formhash = re.search(r'name="formhash" value="(\w+)"', response.text).group(1)
fid_match = re.search(r"fid\s*=\s*parseInt\('(\d+)'\)", response.text).group(1)
tid_match = re.search(r"tid\s*=\s*parseInt\('(\d+)'\)", response.text).group(1)
print('回复次数:' + reply_count)
if int(reply_count) > 5:
print('回复次数大于5次任务跳过')
else:
for _ in range(int(reply_count)):
for i in range(3):
result = self.reply(tid_match, fid_match, formhash)
if result:
break
time.sleep(10)
time.sleep(35)
print(f'已完成任务 《{task_name}》 回复指定文章要求')
else:
response = self.session.get(f'https://bbs.3dmgame.com/{tables}')
result = re.findall(r'mod=redirect&tid=(\d+)&goto', response.text)
if len(result) > 0:
response = self.session.get(f'https://bbs.3dmgame.com/thread-{random.choice(result)}-1-1.html')
formhash = re.search(r'name="formhash" value="(\w+)"', response.text).group(1)
fid_match = re.search(r"fid\s*=\s*parseInt\('(\d+)'\)", response.text).group(1)
tid_match = re.search(r"tid\s*=\s*parseInt\('(\d+)'\)", response.text).group(1)
for _ in range(int(reply_count)):
for i in range(3):
result = self.reply(tid_match, fid_match, formhash)
if result:
break
time.sleep(10)
time.sleep(35)
print(f'已完成任务 《{task_name}》 回复指定主题要求')
response = self.session.get(f'https://bbs.3dmgame.com/home.php?mod=task&do=draw&id={task_id}')
if '恭喜您,任务已成功完成,您将收到奖励通知,请注意查收' in response.text:
print(f'任务:《{task_name}》 完成')
elif '您已完成该任务的' in response.text:
html = etree.HTML(response.text)
b = html.xpath('//div[@id="messagetext"]/p/text()')[0]
print(f'任务:《{task_name}》 失败:' + b.strip())
elif '您还没有开始执行任务,赶快哦' in response.text:
print(f'任务:《{task_name}》 失败:因任务特殊跳过该任务')
elif '您还没有开始执行任务' in response.text:
print(f'任务:《{task_name}》 失败:因任务特殊跳过该任务')
else:
print(f'任务:《{task_name}》 失败')
print(response.text)
time.sleep(3)
def reply(self, tid, fid, formhash):
response = requests.get("https://www.mxnzp.com/api/jokes/list?page=1&app_id=vqohyieoq7qklmgp&app_secret=FCc9Uf0h1c0LNkqeLRolebStTGfds3Fx")
response_json = response.json()
if response_json['code'] == 1 :
message = response_json['data']['list'][0]['content']
else:
message = '我是新玩家,搞不懂' + random.choice(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'])
data = {
'file': '',
'message': message,
'posttime': str(int(time.time())),
'formhash': formhash,
'usesig': '1',
'subject': ' ',
}
response = self.session.post(f'https://bbs.3dmgame.com/forum.php?mod=post&action=reply&fid={fid}&tid={tid}&extra=page%3D1&replysubmit=yes&infloat=yes&handlekey=fastpost&inajax=1', data=data)
if '回复发布成功' in response.text:
print('回帖成功,等待35秒后回复下个帖子')
return True
else:
print('回复失败,未知原因')
return False
def main(self):
self.user_info()
print('-' * 50)
print('开始做论坛任务-->>>>>>>>')
self.check_task()
task_list = self.check_task_doing()
if task_list:
for task in task_list:
self.do_task(task)
print('等待30秒进行下一个账号')
self.session.close()
print('*' * 50)
time.sleep(30)
Log('-' * 30)
if __name__ == '__main__':
try:
if 'bbs3dmck' in os.environ:
bbs3dmck = re.split("@|&", os.environ.get("bbs3dmck"))
print(f'查找到{len(bbs3dmck)}个账号\n')
else:
bbs3dmck = None
print('无bbs3dmck变量')
Log(f'\n未填入bbs3dmck变量')
if bbs3dmck:
z = 1
for ck in bbs3dmck:
print(f'登录第{z}个账号')
threeDM = ThreeDMGame(ck)
threeDM.main()
z+= 1
except Exception as e:
print(e)
try:
send_notification_message(title='3dmgame论坛签到') # 发送通知
except Exception as e:
print(e)

View File

@@ -0,0 +1,388 @@
# Source: https://github.com/lksky8/sign-ql/blob/main/PPark.py
# Raw: https://raw.githubusercontent.com/lksky8/sign-ql/main/PPark.py
# Repo: lksky8/sign-ql
# Path: PPark.py
# UploadedAt: 2025-09-22T11:01:17Z
# SHA256: 120e73308bc1ccfb9db8ebd87357364850257a25ba1bc039d67c2967fe6c8e19
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
PP停车签到
作者https://github.com/lksky8/sign-ql
最后更新日期2025-9-22
食用方法变量输入export pp_token=账号1#token1&账号2#token2
支持多用户运行
多用户用&或者@隔开
例如账号113800000000#eyJhbGciOiJIUzI1NiJ9.eyj 账号2 139000000000#eyJhbGciOiJIUzI1NiJ9.eyj
则变量为
export pp_token="13800000000#eyJhbGciOiJIUzI1NiJ9.eyj&13900000000#eyJhbGciOiJIUzI1NiJ9.eyj"
每天运行两次否则token会过期
cron: 0 40 0,12 * * *
"""
import requests
import base64
from urllib.parse import quote
import json
import hashlib
import time
import os
import re
KEY_ENCRYPT = "2363ECDFC54A5AF12477D3D45333A19F" # key1 用于加密
KEY_DECRYPT = "466d67cf8f9810707404fae5ed172b8e" # key2 用于解密
WX_ENCRYPT = "riegh^ee:w0fok5je5eeS{eecaes1nep"
send_msg = ''
one_msg = ''
def Log(cont=''):
global send_msg, one_msg
if cont:
one_msg += f'\n{cont}'
send_msg += f'\n{cont}'
def send_notification_message(title):
try:
from notify import send
print("加载通知服务成功!")
send(title, send_msg)
except Exception as e:
if e:
print('发送通知消息失败!')
api_headers = {
'Host': 'api.660pp.com',
'accept': '*/*',
'content-type': 'application/x-www-form-urlencoded',
'rest_api_type': '1',
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Parking/4.3.2 (iOS 16.6.1; iPhone15,2; Build/1312) NetType/WIFI',
'accept-language': 'zh_CN',
}
wx_headers = {
'Host': 'user-api.4pyun.com',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467',
'xweb_xhr': '1',
'content-type': 'application/x-www-form-urlencoded',
'accept': '*/*',
'sec-fetch-site': 'cross-site',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
'referer': 'https://servicewechat.com/wxa204074068ad40ef/879/page-frame.html',
'accept-language': 'zh-CN,zh;q=0.9',
'priority': 'u=1, i',
}
def transform(bytes_data: bytearray, key: str) -> bytearray:
len_key = len(key)
len_b = len(bytes_data)
for i in range(len_b):
index = (len_b - i) % len_key
key_byte = ord(key[index])
in_byte = bytes_data[i]
flipped = in_byte ^ 0xFF
bytes_data[i] = key_byte ^ flipped
return bytes_data
def encrypt(arg: str, key: str) -> str:
"""加密,对应提供的 encrypt 方法"""
bytes_data = bytearray(arg.encode('utf-8'))
transformed = transform(bytes_data, key)
return base64.b64encode(transformed).decode('utf-8')
def decrypt(arg: str) -> str:
"""解密,对应提供的 decrypt 方法"""
bytes_data = bytearray(base64.b64decode(arg))
transformed = transform(bytes_data, KEY_DECRYPT)
return transformed.decode('utf-8')
def save_or_update_phone_data(phone_key, new_data, file_path='PPark_data.json'):
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
existing_data = json.load(f)
else:
existing_data = {}
if phone_key in existing_data:
existing_data[phone_key].update(new_data) # 合并新旧数据
print(f"[{phone_key}] 数据已更新!")
else:
existing_data[phone_key] = new_data # 新增数据
print(f"[{phone_key}] 新增数据!")
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(existing_data, f, ensure_ascii=False, indent=4)
def get_user_ids_and_tokens(file_path='PPark_data.json'):
try:
with open(file_path, 'r', encoding='utf-8') as f:
phone_data = json.load(f)
results = []
for phone_key, data in phone_data.items():
token = data.get('refresh_token')
if token:
results.append({
'phone_key': phone_key,
'refresh_token': token,
'user_name': data.get('user_name'),
'user_id': data.get('user_id')
})
return results
except FileNotFoundError:
print(f"文件 {file_path} 不存在!")
return []
except json.JSONDecodeError:
print(f"文件 {file_path} 格式错误!")
return []
def get_userdata(u):
user_phone = u.split('#')[0]
user_token = u.split('#')[1]
try:
with open('PPark_data.json', 'r', encoding='utf-8') as f:
cache_data = json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
cache_data = {}
if user_phone not in cache_data:
print(f'[{user_phone}] 不存在于缓存中,尝试初始化数据')
init_refresh_token(user_phone,user_token)
else:
print(f'[{user_phone}] 已存在于缓存中,直接读取数据')
refresh_token(user_phone,user_token,cache_data[user_phone]['refresh_token'])
old_user_token = cache_data[user_phone]['init_token']
if old_user_token != user_token:
print(f'[{user_phone}] token已更新尝试刷新')
init_refresh_token(user_phone,user_token)
def md5_encrypt(s: str):
return hashlib.md5(s.encode('utf-8')).hexdigest()
def get_user_info(phone: str, token: str):
headers = wx_headers.copy()
headers['authorization'] = f'Bearer {token}'
try:
response = requests.get('https://user-api.4pyun.com/rest/2.0/user/whoami',headers=headers)
response.raise_for_status()
response_json = response.json()
if response_json['code'] == '1001':
print(f"[{response_json['payload']['nickname']}] 获取用户信息:成功")
return response_json['payload']['nickname'], response_json['payload']['identity']
else:
print(f"[{phone}] 获取用户信息:失败:{response_json}")
return None
except requests.RequestException as e:
print(f"[{phone}] 获取用户信息_请求异常{e}")
except json.JSONDecodeError:
print(f"[{phone}] 获取用户信息_响应不是有效的JSON格式")
except Exception as e:
print(f"[{phone}] 获取用户信息_其他异常{e}")
def refresh_token(mobile: str, i_token: str, r_token: str):
headers = api_headers.copy()
headers['rest_api_token'] = r_token
try:
response = requests.put('https://api.660pp.com/rest/1.6/user/token', headers=headers)
response_json = response.json()
# print(response_json)
if response_json['code'] == '1001':
result = json.loads(decrypt(response_json['result']))
print(f"[{mobile}] 刷新token成功")
save_or_update_phone_data(mobile,{'init_token': i_token,'refresh_token': result['token']})
elif response_json['code'] == '401':
print(f"[{mobile}] 刷新token失败token已失效")
Log(f"[{mobile}] 刷新token失败token已失效")
else:
print(f"[{mobile}] 刷新token失败{response_json}")
except requests.RequestException as e:
print(f"[{mobile}] 刷新token_请求异常{e}")
except json.JSONDecodeError:
print(f"[{mobile}] 刷新token_响应不是有效的JSON格式")
except Exception as e:
print(f"[{mobile}] 刷新token_其他异常{e}")
def init_refresh_token(mobile: str, token: str):
headers = api_headers.copy()
headers['rest_api_token'] = token
try:
response = requests.put('https://api.660pp.com/rest/1.6/user/token', headers=headers)
response_json = response.json()
# print(response_json)
if response_json['code'] == '1001':
result = json.loads(decrypt(response_json['result']))
user_name, user_id = get_user_info(mobile, token)
save_or_update_phone_data(mobile,{'user_name': user_name, 'user_id': user_id, 'init_token': token, 'refresh_token': result['token']})
print(f"[{mobile}] 刷新token成功")
elif response_json['code'] == '401':
print(f"[{mobile}] 刷新token失败token已失效")
Log(f"[{mobile}] 刷新token失败token已失效")
else:
print(f"[{mobile}] 刷新token失败{response_json}")
except requests.RequestException as e:
print(f"[{mobile}] 刷新token_请求异常{e}")
except json.JSONDecodeError:
print(f"[{mobile}] 刷新token_响应不是有效的JSON格式")
except Exception as e:
print(f"[{mobile}] 刷新token_其他异常{e}")
def day_sign(nickname: str, token: str):
headers = api_headers.copy()
headers['rest_api_token'] = token
try:
response = requests.get('https://api.660pp.com/rest/1.6/reward/bonus?yc7OyqO6qQ%3D%3D=rL7JhL/NrriG2tPZ2aegog%3D%3D', headers=headers)
response.raise_for_status()
response_json = response.json()
if response_json['code'] == '1001':
result = json.loads(decrypt(response_json['result']))
message = result['message'].replace('\r\n', '')
if '签到获得' in result['message'] or '已连续签到'in result['message']:
print(f"[{nickname}] 签到成功:{message} 已累计获得:{result['combo']} 积分")
Log(f"[{nickname}] 签到成功:{message} 已累计获得:{result['combo']} 积分")
elif message == '您已签到成功' :
print(f"[{nickname}] 签到失败:已签到")
Log(f"[{nickname}] 已签到")
else:
print(f"[{nickname}] 签到失败:{message}")
Log(f"[{nickname}] 签到失败:{message}")
else:
print(f"[{nickname}] 获取签到数据失败:{response_json}")
except requests.RequestException as e:
print(f"[{nickname}] 签到_请求异常{e}")
except json.JSONDecodeError:
print(f"[{nickname}] 签到_响应不是有效的JSON格式")
except Exception as e:
print(f"[{nickname}] 签到_其他异常{e}")
def get_task(nickname: str, token: str):
headers = wx_headers.copy()
headers['authorization'] = f'Bearer {token}'
try:
response = requests.get('https://user-api.4pyun.com/rest/2.0/bonus/reward/task/list?%2B9Hnx%2FPy=7bL7p%2FqgoK77uPOi%2B8WjqP%2Fw', headers=headers)
response.raise_for_status()
response_json = response.json()
if response_json['code'] == '1001':
video_task = [task for task in response_json['payload']['row'] if task['name'] == '看视频得积分'][0]
referer_url = video_task['referer_url']
print(f'[{nickname}] 获取视频任务数据成功')
return referer_url.split('&voucher=')[1]
else:
print(f"[{nickname}] 获取任务_失败{response_json}")
Log(f"[{nickname}] 获取视频任务数据失败:{response_json}")
return None
except requests.RequestException as e:
print(f"[{nickname}] 获取任务_请求异常{e}")
except json.JSONDecodeError:
print(f"[{nickname}] 获取任务_响应不是有效的JSON格式")
except Exception as e:
print(f"[{nickname}] 获取任务_其他异常{e}")
def complete_task(nickname: str, token: str, task_id: str):
headers = wx_headers.copy()
headers['authorization'] = f'Bearer {token}'
headers['content-type'] = 'application/json;charset=utf-8'
try:
data = '{"app_id":"wxa204074068ad40ef","purpose":"reward:motivate:advertising","voucher":"voucher_data"}'.replace('voucher_data', task_id)
encrypt_data = encrypt(data,WX_ENCRYPT)
response = requests.post('https://user-api.4pyun.com/rest/2.0/bonus/reward/task/complete', headers=headers, data=encrypt_data)
response.raise_for_status()
response_json = response.json()
if response_json['code'] == '1001':
print(f"[{nickname}] 看视频:任务完成")
headers['content-type'] = 'application/x-www-form-urlencoded'
response = requests.get('https://user-api.4pyun.com/rest/2.0/bonus/reward/acquire?%2B9Hnx%2FPy=7bL7p%2FqgoK77uPOi%2B8WjqP%2Fw&6u%2FT5%2Ffp8w%3D%3D=%2Fv%2Fp%2Fej%2BvsH17qPs9L7xqvir%2FqDo7sjk8fTx', headers=headers)
response.raise_for_status()
response_json = response.json()
if response_json['code'] == '1001':
print(f"[{nickname}] 看视频:任务奖励已领取,{response_json['payload']['message']}")
Log(f"[{nickname}] 看视频:任务奖励已领取,{response_json['payload']['message']}")
elif response_json['message'] == '已达积分领取次数上限':
print(f"[{nickname}] 看视频:积分已领取")
else:
print(f"[{nickname}] 看视频:{response_json['message']}")
Log(f"[{nickname}] 看视频:{response_json['message']}")
else:
print(f"[{nickname}] 看视频任务失败:{response_json}")
Log(f"[{nickname}] 看视频任务失败:{response_json}")
except requests.RequestException as e:
print(f"[{nickname}] 看视频任务_请求异常{e}")
except json.JSONDecodeError:
print(f"[{nickname}] 看视频任务_响应不是有效的JSON格式")
except Exception as e:
print(f"[{nickname}] 看视频任务_其他异常{e}")
def reward_balance(nickname: str, token: str, user_id: str):
headers = wx_headers.copy()
headers['authorization'] = f'Bearer {token}'
try:
response = requests.get(f'https://user-api.4pyun.com/rest/2.0/reward/balance?rP7%2Fz%2BPx7u8%3D={quote(encrypt(user_id,WX_ENCRYPT))}&7%2BnE5cfz8g%3D%3D={quote(encrypt(user_id,WX_ENCRYPT))}&%2Fbb%2F6P7j4erz=pw%3D%3D', headers=headers)
response.raise_for_status()
response_json = response.json()
if response_json['code'] == '1001':
print(f"[{nickname}] 积分余额:{response_json['payload']['balance']}")
Log(f"[{nickname}] 积分余额:{response_json['payload']['balance']}")
else:
print(f"[{nickname}] 获取积分余额_失败{response_json}")
Log(f"[{nickname}] 获取积分余额_失败{response_json}")
except requests.RequestException as e:
print(f"[{nickname}] 获取积分余额_请求异常{e}")
except json.JSONDecodeError:
print(f"[{nickname}] 获取积分余额_响应不是有效的JSON格式")
except Exception as e:
print(f"[{nickname}] 获取积分余额_其他异常{e}")
if __name__ == '__main__':
if 'pp_token' in os.environ:
pp_token = re.split("@|&", os.environ.get("pp_token"))
print(f'查找到{len(pp_token)}个账号')
else:
pp_token = []
print('请填入pp_token变量')
Log('请填入pp_token变量')
try:
if pp_token:
for pp_token_item in pp_token:
get_userdata(pp_token_item)
user_data = get_user_ids_and_tokens()
if user_data:
print(f"配置缓存中读取到{len(user_data)}个账号")
print('*' * 50)
z = 1
for item in user_data:
print('-' * 50)
print(f'登录第{z}个账号>>>>>>')
phone_key = item.get('phone_key')
new_token = item.get('refresh_token')
user_name = item.get('user_name')
user_id = item.get('user_id')
if new_token:
day_sign(user_name,new_token)
for _ in range(2):
voucher = get_task(user_name, new_token)
if voucher:
complete_task(user_name, new_token, voucher)
time.sleep(5)
reward_balance(user_name,new_token,user_id)
time.sleep(3)
Log('-'*30)
z += 1
else:
print("未读取到用户数据,程序退出")
exit(0)
except Exception as e:
print(f'程序异常:{e}')
try:
send_notification_message(title='PP停车') # 发送通知
except Exception as e:
print('推送失败:' + str(e))

View File

@@ -0,0 +1,341 @@
# Source: https://github.com/lksky8/sign-ql/blob/main/invalid/tyqh.py
# Raw: https://raw.githubusercontent.com/lksky8/sign-ql/main/invalid/tyqh.py
# Repo: lksky8/sign-ql
# Path: invalid/tyqh.py
# UploadedAt: 2026-05-23T06:33:20Z
# SHA256: 4c779933563a21d73534721d588cf8fd5aa9e6d6ced3e3b3bb414c91fb576708
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
统一茄皇
作者https://github.com/lksky8/sign-ql
最后更新日期2025-12-11
食用方法抓包url https://api.zhumanito.cn/api/login 请求体json {"wid":"12345678910"}
支持多用户运行
多用户用&或者@隔开
例如账号112345678910 账号2 12345678911
则变量为
export tyqh="12345678910@12345678911"
cron: 11 11 * * *
"""
import requests
import os
import re
import time
# 推送开关True为开启False为关闭
sendnotify = True
send_msg = ''
one_msg = ''
def Log(cont=''):
global send_msg, one_msg
if cont:
one_msg += f'\n{cont}'
send_msg += f'\n{cont}'
def send_notification_message(title):
try:
from notify import send
print("加载通知服务成功!")
send(title, send_msg)
except Exception as e:
if e:
print('发送通知消息失败!')
api_headers = {
'Host': 'api.zhumanito.cn',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16571',
'authorization': '',
'accept': '*/*',
'origin': 'https://h5.zhumanito.cn',
'sec-fetch-site': 'same-site',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
'referer': 'https://h5.zhumanito.cn/',
'accept-language': 'zh-CN,zh;q=0.9',
'priority': 'u=1, i',
}
def login(wid):
headers = {
'Host': 'api.zhumanito.cn',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16571',
'content-type': 'application/json;charset=UTF-8',
'accept': '*/*',
'origin': 'https://h5.zhumanito.cn',
'sec-fetch-site': 'same-site',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
'referer': 'https://h5.zhumanito.cn/',
'accept-language': 'zh-CN,zh;q=0.9',
'priority': 'u=1, i',
}
try:
response = requests.post('https://api.zhumanito.cn/api/login', headers=headers, json={'wid': wid})
response.raise_for_status()
response_json = response.json()
if response_json['code'] == 200 and response_json['msg'] == '成功':
print(f"登录成功用户ID: {wid},拥有番茄:{response_json['data']['user']['fruit_num']}")
Log(f"登录成功用户ID: {wid},拥有番茄:{response_json['data']['user']['fruit_num']}")
if '"seed_stage":0' in response.text:
print(f"未种植番茄")
Log(f"未种植番茄")
time.sleep(1)
seed_tomato(response_json['data']['token'])
return response_json['data']['token']
else:
print(f"用户ID: {wid} 登录失败: {response_json['msg']}")
Log(f"用户ID: {wid} 登录失败: {response_json['msg']}")
return None
except requests.RequestException as e:
print(f"获取用户数据网络请求失败: {e}")
except ValueError as e:
print(f"获取用户数据解析JSON响应失败: {e}")
except KeyError as e:
print(f"获取用户数据JSON响应中缺少键: {e}")
except Exception as e:
print(f"获取用户数据时发生未知错误: {e}")
def get_tomato(user_token):
headers = api_headers.copy()
headers['authorization'] = user_token
try:
response = requests.post('https://api.zhumanito.cn/api/harvest', headers=headers)
response.raise_for_status()
response_json = response.json()
if response_json['code'] == 200 and response_json['msg'] == '成功':
print(f"番茄收获成功,获得番茄:{response_json['data']['fruit_up']}")
Log(f"番茄收获成功,获得番茄:{response_json['data']['fruit_up']}")
seed_tomato(user_token)
else:
print(f"收获番茄失败: {response_json['msg']}")
Log(f"收获番茄失败: {response_json['msg']}")
except requests.RequestException as e:
print(f"收获番茄网络请求失败: {e}")
except ValueError as e:
print(f"收获番茄解析JSON响应失败: {e}")
except KeyError as e:
print(f"收获番茄JSON响应中缺少键: {e}")
except Exception as e:
print(f"收获番茄时发生未知错误: {e}")
def seed_tomato(user_token):
headers = api_headers.copy()
headers['authorization'] = user_token
try:
response = requests.post('https://api.zhumanito.cn/api/seed', headers=headers)
response.raise_for_status()
response_json = response.json()
if response_json['code'] == 200 and response_json['msg'] == '成功':
print(f"番茄种植成功")
Log(f"番茄种植成功")
else:
print(f"番茄种植失败: {response_json['msg']}")
Log(f"番茄种植失败: {response_json['msg']}")
except requests.RequestException as e:
print(f"番茄种植网络请求失败: {e}")
except ValueError as e:
print(f"番茄种植解析JSON响应失败: {e}")
except KeyError as e:
print(f"番茄种植JSON响应中缺少键: {e}")
except Exception as e:
print(f"番茄种植时发生未知错误: {e}")
def get_task(user_token):
headers = api_headers.copy()
headers['authorization'] = user_token
try:
response = requests.get('https://api.zhumanito.cn/api/task?', headers=headers)
response.raise_for_status()
response_json = response.json()
if response_json['code'] == 200 and response_json['msg'] == '成功':
print(f"获取任务成功")
task_lists = []
for task_list in response_json['data']['task']:
task_name = task_list['content']
reward_water = task_list['water_num']
reward_sun = task_list['sun_num']
if task_list['status'] == 1:
print(f"任务: {task_name}, 奖励水: {reward_water}, 奖励阳光: {reward_sun} 已完成")
else:
print(f"任务: {task_name}, 奖励水: {reward_water}, 奖励阳光: {reward_sun} 未完成")
task_lists.append({
'task_id': task_list['id'],
'task_name': task_name,
})
return task_lists
else:
print(f"获取任务失败: {response_json['msg']}")
return None
except requests.RequestException as e:
print(f"获取任务数据网络请求失败: {e}")
except ValueError as e:
print(f"获取任务数据解析JSON响应失败: {e}")
except KeyError as e:
print(f"获取任务数据JSON响应中缺少键: {e}")
except Exception as e:
print(f"获取任务数据时发生未知错误: {e}")
def get_task_again(user_token):
headers = api_headers.copy()
headers['authorization'] = user_token
try:
response = requests.get('https://api.zhumanito.cn/api/task?', headers=headers)
response.raise_for_status()
response_json = response.json()
if response_json['code'] == 200 and response_json['msg'] == '成功':
print(f"获取任务成功")
for task_list in response_json['data']['task']:
task_name = task_list['content']
reward_water = task_list['water_num']
reward_sun = task_list['sun_num']
if task_list['status'] == 1:
print(f"任务: {task_name}, 奖励水: {reward_water}, 奖励阳光: {reward_sun} 已完成")
Log(f"任务: {task_name}, 奖励水: {reward_water}, 奖励阳光: {reward_sun} 已完成")
else:
print(f"任务: {task_name}, 奖励水: {reward_water}, 奖励阳光: {reward_sun} 未完成")
Log(f"任务: {task_name}, 奖励水: {reward_water}, 奖励阳光: {reward_sun} 未完成")
else:
print(f"获取任务失败: {response_json['msg']}")
Log(f"获取任务失败: {response_json['msg']}")
return None
except requests.RequestException as e:
print(f"获取任务数据网络请求失败: {e}")
except ValueError as e:
print(f"获取任务数据解析JSON响应失败: {e}")
except KeyError as e:
print(f"获取任务数据JSON响应中缺少键: {e}")
except Exception as e:
print(f"获取任务数据时发生未知错误: {e}")
def task_complete(user_token, task_id,task_name):
headers = api_headers.copy()
headers['authorization'] = user_token
headers['content-type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
try:
response = requests.post('https://api.zhumanito.cn/api/task/complete', headers=headers, data=f'task_id={task_id}&')
response.raise_for_status()
response_json = response.json()
if response_json['code'] == 200 and response_json['msg'] == '成功':
for task_status in response_json['data']['task']:
if task_status['task_id'] == task_id and task_status['status']:
print(f"任务: {task_name} 成功,剩余水: {response_json['data']['user']['water_num']}, 剩余阳光: {response_json['data']['user']['sun_num']}")
else:
print(f"任务: {task_name} 失败: {response_json['msg']}")
except requests.RequestException as e:
print(f"完成任务: {task_name} 时网络请求失败: {e}")
except ValueError as e:
print(f"完成任务: {task_name} 时解析JSON响应失败: {e}")
except KeyError as e:
print(f"完成任务: {task_name} 时JSON响应中缺少键: {e}")
except Exception as e:
print(f"完成任务: {task_name} 时发生未知错误: {e}")
def water(user_token):
headers = api_headers.copy()
headers['authorization'] = user_token
headers['content-type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
try:
response = requests.post('https://api.zhumanito.cn/api/water', headers=headers)
response.raise_for_status()
response_json = response.json()
if response_json['code'] == 200 and response_json['msg'] == '成功':
print(f"浇水成功,剩余水: {response_json['data']['user']['water_num']}, 剩余阳光: {response_json['data']['user']['sun_num']}")
Log(f"浇水成功,剩余水: {response_json['data']['user']['water_num']}, 剩余阳光: {response_json['data']['user']['sun_num']}")
return True
elif response_json['code'] == 10006 and response_json['msg'] == '能量值不足了,可以坚持做任务获取哦~':
print("不够水了")
Log("不够水了")
return False
elif response_json['code'] == 10007 and response_json['msg'] == '今日浇水已达到上限,请明天再来哦~':
print("今日浇水次数已达到上限")
Log("今日浇水次数已达到上限")
return False
elif response_json['code'] == 10008 and response_json['msg'] == '已成熟,不必浇灌':
print("番茄已成熟,自动收获")
Log("番茄已成熟,自动收获")
get_tomato(user_token)
return True
else:
print(f"浇水失败: {response_json['msg']}")
return False
except requests.RequestException as e:
print(f"浇水时网络请求失败: {e}")
except ValueError as e:
print(f"浇水时解析JSON响应失败: {e}")
except KeyError as e:
print(f"浇水时JSON响应中缺少键: {e}")
except Exception as e:
print(f"浇水时发生未知错误: {e}")
finally:
time.sleep(3)
def view_page(wid):
headers = {
'Host': 'api.zhumanito.cn',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'sec-fetch-site': 'same-site',
'sec-fetch-dest': 'document',
'accept-language': 'zh-CN,zh-Hans;q=0.9',
'sec-fetch-mode': 'navigate',
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.64(0x1800402b) NetType/WIFI Language/zh_CN miniProgram/wx532ecb3bdaaf92f9',
'referer': 'https://h5.zhumanito.cn/',
}
requests.get(f'https://api.zhumanito.cn/?wid={wid}', headers=headers)
if __name__ == '__main__':
if 'tyqh' in os.environ:
tyqh_session = re.split("@|&", os.environ.get("tyqh"))
print(f'查找到{len(tyqh_session)}个账号')
else:
tyqh_session = []
if tyqh_session:
z = 1
for wid in tyqh_session:
print('*'*50)
print(f'开始处理第{z}个账号')
Log(f'处理第{z}个账号:')
print('-' * 30)
token = login(wid)
print('-' * 30)
all_task = get_task(token)
print('-'*30)
print('开始做任务')
for task in all_task:
if task['task_name'] == '浏览指定页面':
view_page(wid)
print('任务: 浏览指定页面 成功')
time.sleep(3)
continue
task_complete(token, task['task_id'], task['task_name'])
time.sleep(3)
print('-' * 30)
while water(token):
pass
get_task_again(token)
Log('\n')
z += 1
time.sleep(10)
else:
print('请填入tyqh变量')
Log('请填入tyqh变量')
if sendnotify:
try:
send_notification_message(title='统一茄皇') # 发送通知
except Exception as e:
print('推送失败:' + str(e))

View File

@@ -0,0 +1,584 @@
// # Source: https://github.com/DearSong15/ql-scripts/blob/main/zsp_video.js
// # Raw: https://raw.githubusercontent.com/DearSong15/ql-scripts/main/zsp_video.js
// # Repo: DearSong15/ql-scripts
// # Path: zsp_video.js
// # UploadedAt: 2026-05-11T15:03:30Z
// # SHA256: 960b2e28799c40a00eb4bd75dcda1e61b3ab747374716073995c75053c3083ee
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
//走个码吧,谢谢兄弟们了
//后台注册地址https://zsp.99panel.top/#/register?inviteCode=lzwbaleD
//前台https://a.zsp55.app/
//变量格式:备注#SecretId#SecretKey#deviceld
const ENV_NAME = "中视频";
const USER_AGENT = "Mozilla/5.0 (Linux; Android 15; 23013RK75C Build/AQ3A.250226.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.260 Mobile Safari/537.36 (Immersed/39.42857) Html5Plus/1.0";
const BASE_URL = "https://x1.zsptv.online";
// 工具函数
function wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// HTTP请求函数
async function httpRequest(options) {
return new Promise((resolve, reject) => {
const url = new URL(options.url);
const https = url.protocol === 'https:' ? require('https') : require('http');
const req = https.request({
hostname: url.hostname,
port: url.port || (url.protocol === 'https:' ? 443 : 80),
path: url.pathname + url.search,
method: options.method || 'GET',
headers: options.headers || {}
}, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
// 调试:记录响应
if (res.statusCode === 403) {
console.log(`🔍 响应体: ${data.substring(0, 200)}...`);
}
resolve({
statusCode: res.statusCode,
headers: res.headers,
body: data
});
});
});
req.on('error', (err) => {
reject(err);
});
if (options.body) {
req.write(options.body);
}
req.end();
});
}
// Unicode解码函数
function decodeUnicode(str) {
if (!str) return '';
return str.replace(/\\u[\dA-F]{4}/gi,
match => String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16)));
}
// 主函数
async function main() {
console.log(`🔔 脚本开始运行,时间: ${new Date().toLocaleString()}\n`);
// 读取环境变量
const accounts = loadAccounts();
if (accounts.length === 0) {
console.log("❌ 未找到有效的账号配置,请检查环境变量格式!");
return;
}
console.log(`✅ 找到 ${accounts.length} 个账号\n`);
// 遍历所有账号
for (let i = 0; i < accounts.length; i++) {
const account = accounts[i];
console.log(`\n📱 开始处理账号 ${i+1}: ${account.remark}`);
console.log("=".repeat(30));
try {
await processAccount(account);
} catch (error) {
console.log(`❌ 处理账号 ${account.remark} 时出错: ${error.message}`);
}
// 账号间延迟
if (i < accounts.length - 1) {
console.log("\n⏳ 等待5秒后处理下一个账号...");
await wait(5000);
}
}
console.log(`\n🎉 所有账号处理完成!`);
}
// 加载账号信息
function loadAccounts() {
const accounts = [];
// 尝试从不同环境变量名称读取
const envNames = ['ZSP', 'AD_WATCH_ACCOUNTS'];
let envValue = '';
for (const envName of envNames) {
if (process.env[envName]) {
envValue = process.env[envName];
console.log(`📋 从环境变量 ${envName} 读取配置`);
break;
}
}
if (!envValue) {
console.log("⚠️ 请设置环境变量 ZSP 或 AD_WATCH_ACCOUNTS");
return accounts;
}
const accountStrs = envValue.split("\n").filter(str => str.trim());
for (const str of accountStrs) {
const parts = str.split("#");
if (parts.length >= 4) {
accounts.push({
remark: parts[0] || "未命名账号",
secretId: parts[1],
secretKey: parts[2],
deviceId: parts[3]
});
console.log(`✅ 加载账号: ${parts[0] || "未命名账号"}`);
} else {
console.log(`⚠️ 忽略格式错误的环境变量: ${str}`);
}
}
return accounts;
}
// 处理单个账号
async function processAccount(account) {
// 1. 登录获取token
const token = await login(account);
if (!token) {
console.log("❌ 登录失败,跳过此账号");
return;
}
console.log(`✅ 登录成功token获取完成`);
// 2. 检测并执行签到
const signed = await checkAndSign(token, account);
if (!signed) {
console.log("❌ 签到失败,跳过广告任务");
return;
}
console.log(`\n📺 开始执行广告观看任务`);
console.log("-".repeat(30));
let successCount = 0;
let failCount = 0;
let totalReward = 0;
let consecutiveErrors = 0;
const maxAds = 50; // 最多执行50次广告任务
for (let adCount = 0; adCount < maxAds; adCount++) {
console.log(`\n🔄 第 ${adCount + 1}/${maxAds} 次广告任务`);
// 如果连续出现3次错误重新登录获取新token
if (consecutiveErrors >= 3) {
console.log("⚠️ 连续3次错误尝试重新登录...");
const newToken = await login(account);
if (newToken) {
token = newToken;
console.log("✅ 重新登录成功,继续任务");
consecutiveErrors = 0;
} else {
console.log("❌ 重新登录失败,跳过此账号");
break;
}
}
try {
// 获取广告信息
const adInfo = await getNextAd(token, account);
if (!adInfo) {
console.log(` ⚠️ 获取广告失败`);
failCount++;
consecutiveErrors++;
await wait(3000);
continue;
}
console.log(` 📱 广告标题: ${adInfo.title}`);
console.log(` ⏱️ 需要观看: ${adInfo.duration}`);
console.log(` 🪙 预期奖励: ${adInfo.reward || 0}`);
// 开始播放广告
console.log(` ▶️ 开始播放广告...`);
const playResult = await claimReward(token, account, adInfo.id, adInfo.duration);
if (playResult && playResult.success) {
console.log(` ✅ 广告观看成功!`);
console.log(` 💰 获得奖励: ${playResult.reward || 0}`);
successCount++;
totalReward += parseInt(playResult.reward) || 0;
consecutiveErrors = 0; // 重置错误计数
// 任务间延迟 (避免请求过快)
if (adCount < maxAds - 1) {
const randomDelay = Math.floor(Math.random() * 3000) + 3000; // 3-6秒随机延迟
console.log(` ⏳ 等待${Math.round(randomDelay/1000)}秒后处理下一个广告...`);
await wait(randomDelay);
}
} else {
console.log(` ❌ 广告观看失败`);
failCount++;
consecutiveErrors++;
await wait(3000);
}
} catch (error) {
console.log(` ❌ 广告任务出错: ${error.message}`);
failCount++;
consecutiveErrors++;
await wait(3000);
}
}
console.log("\n" + "=".repeat(30));
console.log(`📊 任务完成统计:`);
console.log(` ✅ 成功: ${successCount}`);
console.log(` ❌ 失败: ${failCount}`);
console.log(` 💰 总计奖励: ${totalReward}`);
console.log(` 📈 成功率: ${((successCount/maxAds)*100).toFixed(1)}%`);
}
// 登录接口
async function login(account) {
const url = `${BASE_URL}/api/app/v1/auth/secretKeyLogin`;
const body = {
secretId: account.secretId,
secretKey: account.secretKey
};
const headers = {
"Accept": "*/*",
"User-Agent": USER_AGENT,
"app-device": JSON.stringify({
"id": account.deviceId,
"brand": "xiaomi",
"model": "23013RK75C",
"platform": "android",
"system": "Android 15"
}),
"Content-Type": "application/json",
"Host": "x1.zsptv.online"
};
try {
const response = await httpRequest({
url: url,
method: "POST",
headers: headers,
body: JSON.stringify(body)
});
if (response.statusCode !== 200) {
console.log(`❌ 登录请求失败,状态码: ${response.statusCode}`);
return null;
}
const data = JSON.parse(response.body);
if (data.code === 0 && data.data && data.data.token) {
return data.data.token;
} else {
console.log(`❌ 登录失败: ${data.message || "未知错误"}`);
return null;
}
} catch (error) {
console.log(`❌ 登录请求失败: ${error.message}`);
return null;
}
}
// 检测并执行签到
async function checkAndSign(token, account) {
const url = `${BASE_URL}/api/app/v1/device/userSign`;
const headers = {
"Accept": "*/*",
"User-Agent": USER_AGENT,
"Authorization": `Bearer ${token}`,
"app-device": JSON.stringify({
"id": account.deviceId,
"brand": "xiaomi",
"model": "23013RK75C",
"platform": "android",
"system": "Android 15"
}),
"Content-Type": "application/json",
"Host": "x1.zsptv.online"
};
try {
const response = await httpRequest({
url: url,
method: "POST",
headers: headers,
body: "{}"
});
if (response.statusCode !== 200) {
console.log(`❌ 签到请求失败,状态码: ${response.statusCode}`);
return false;
}
const data = JSON.parse(response.body);
if (data.code === 0) {
const message = decodeUnicode(data.message);
console.log(`✅ 签到结果: ${message}`);
if (data.data) {
console.log(` 🪙 获得签到金币: ${data.data.qiandao_money || 0}`);
console.log(` 📅 连续签到天数: ${data.data.continuousDays || 1}`);
}
return true;
} else {
const errorMsg = decodeUnicode(data.message || "未知错误");
console.log(`❌ 签到失败: ${errorMsg}`);
// 如果已签到也返回true继续执行广告任务
if (errorMsg && errorMsg.includes("已签到")) {
console.log(` 今日已签到,继续执行广告任务`);
return true;
}
return false;
}
} catch (error) {
console.log(`❌ 签到请求失败: ${error.message}`);
return false;
}
}
// 获取下一个广告
async function getNextAd(token, account) {
const url = `${BASE_URL}/api/app/v1/ad/next`;
const headers = {
"Accept": "*/*",
"User-Agent": USER_AGENT,
"Authorization": `Bearer ${token}`,
"app-device": JSON.stringify({
"id": account.deviceId,
"brand": "xiaomi",
"model": "23013RK75C",
"platform": "android",
"system": "Android 15"
}),
"Content-Type": "application/json",
"Host": "x1.zsptv.online"
};
try {
const response = await httpRequest({
url: url,
method: "GET",
headers: headers
});
if (response.statusCode !== 200) {
console.log(` ❌ 获取广告失败,状态码: ${response.statusCode}`);
if (response.body) {
const errorData = JSON.parse(response.body);
console.log(` 🔍 错误信息: ${errorData.message || "未知错误"}`);
}
return null;
}
const data = JSON.parse(response.body);
if (data.code === 0 && data.data && data.data.result) {
const ad = data.data.result;
return {
id: ad.id,
title: decodeUnicode(ad.title),
description: decodeUnicode(ad.description),
duration: parseInt(ad.video?.duration || 30), // 默认30秒
videoUrl: ad.video?.url || "",
playUrl: ad.video?.play_url || "",
reward: ad.reward
};
} else {
const errorMsg = decodeUnicode(data.message || "未知错误");
console.log(` ❌ 获取广告失败: ${errorMsg}`);
return null;
}
} catch (error) {
console.log(` ❌ 获取广告请求失败: ${error.message}`);
return null;
}
}
// 观看广告并获取奖励(整合播放和结束确认)
async function claimReward(token, account, adId, duration) {
const startTime = new Date().toISOString();
// 1. 开始播放广告
console.log(` 📅 播放开始时间: ${startTime}`);
const playResult = await startVideoPlay(token, account, adId, startTime);
if (!playResult || !playResult.playRecordId) {
console.log(` ❌ 广告播放开始失败`);
return { success: false };
}
console.log(` ✅ 播放开始成功! 记录ID: ${playResult.playRecordId}`);
console.log(` 💰 初始奖励: ${playResult.initialReward || 0}`);
// 2. 等待广告播放时间
const waitTime = duration * 1000;
console.log(` ⌛ 广告播放中,等待 ${duration} 秒...`);
await wait(waitTime);
// 3. 广告播放结束确认
console.log(` ⏹️ 广告播放完成,确认结束...`);
const endResult = await endVideoPlay(token, account, playResult.playRecordId);
if (endResult.success) {
console.log(` 🎉 广告观看完整流程完成!`);
return {
success: true,
reward: playResult.reward || 0,
playRecordId: playResult.playRecordId
};
} else {
console.log(` ⚠️ 广告观看完成,但结束确认失败`);
// 即使结束确认失败,也视为成功(因为已经播放完成)
return {
success: true,
reward: playResult.reward || 0,
playRecordId: playResult.playRecordId
};
}
}
// 开始播放广告
async function startVideoPlay(token, account, adId, playTime) {
const url = `${BASE_URL}/api/app/v1/ad/video/play`;
const body = {
clientIp: "",
deviceInfo: {
deviceId: account.deviceId,
platform: "android"
},
id: adId.toString(),
playTime: playTime
};
const headers = {
"Accept": "*/*",
"User-Agent": USER_AGENT,
"Authorization": `Bearer ${token}`,
"app-device": JSON.stringify({
"id": account.deviceId,
"brand": "xiaomi",
"model": "23013RK75C",
"platform": "android",
"system": "Android 15"
}),
"Content-Type": "application/json",
"Host": "x1.zsptv.online"
};
try {
const response = await httpRequest({
url: url,
method: "POST",
headers: headers,
body: JSON.stringify(body)
});
if (response.statusCode !== 200) {
console.log(` ❌ 开始播放广告失败,状态码: ${response.statusCode}`);
return null;
}
const data = JSON.parse(response.body);
if (data.code === 0 && data.data) {
return {
playRecordId: data.data.id,
initialReward: data.data.reward || 0,
reward: data.data.reward || 0
};
} else {
console.log(` ❌ 开始播放广告失败: ${data.message || "未知错误"}`);
return null;
}
} catch (error) {
console.log(` ❌ 开始播放广告请求失败: ${error.message}`);
return null;
}
}
// 结束广告播放
async function endVideoPlay(token, account, playRecordId) {
const url = `${BASE_URL}/api/app/v1/ad/video/ended`;
const endTime = new Date().toISOString();
const body = {
clientIp: "",
deviceInfo: {
deviceId: account.deviceId,
platform: "android"
},
id: playRecordId.toString(),
playTime: endTime
};
const headers = {
"Accept": "*/*",
"User-Agent": USER_AGENT,
"Authorization": `Bearer ${token}`,
"app-device": JSON.stringify({
"id": account.deviceId,
"brand": "xiaomi",
"model": "23013RK75C",
"platform": "android",
"system": "Android 15"
}),
"Content-Type": "application/json",
"Host": "x1.zsptv.online"
};
try {
const response = await httpRequest({
url: url,
method: "POST",
headers: headers,
body: JSON.stringify(body)
});
if (response.statusCode !== 200) {
console.log(` ⚠️ 广告结束确认失败,状态码: ${response.statusCode}`);
// 即使结束确认失败也返回成功避免403错误导致任务中断
return { success: true };
}
const data = JSON.parse(response.body);
if (data.code === 0) {
return { success: true };
} else {
console.log(` ⚠️ 广告结束确认返回异常: ${data.message || "未知错误"}`);
return { success: false };
}
} catch (error) {
console.log(` ⚠️ 广告结束确认请求失败: ${error.message}`);
return { success: false };
}
}
// 执行主函数
if (require.main === module) {
main().catch(console.error);
}

View File

@@ -0,0 +1,586 @@
# Source: https://github.com/lksky8/sign-ql/blob/main/yxw_appsign.py
# Raw: https://raw.githubusercontent.com/lksky8/sign-ql/main/yxw_appsign.py
# Repo: lksky8/sign-ql
# Path: yxw_appsign.py
# UploadedAt: 2025-09-28T06:42:50Z
# SHA256: c6d91db16e3a84bf5dfc1e2c7d6cb38fb3f6d38f5829d7f496ba308fa7a77a10
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
'''
作者https://github.com/lksky8/sign-ql/
日期2025-9-28
网站游侠网APP签到
功能:签到、抽奖,金币可换现金买游戏,配合金币脚本使用可获得更多金币
变量yxwlogin='账号&密码' 多个账号用@或者#分割
定时:一天一次
cron45 8 * * *
'''
from json import JSONDecodeError
import requests
import hashlib
import time
import json
import os
import re
import datetime
if 'yxwlogin' in os.environ:
yxwlogin = re.split("@|#",os.environ.get("yxwlogin"))
print(f'查找到{len(yxwlogin)}个账号')
else:
yxwlogin = []
send_msg = ''
one_msg = ''
def log(cont=''):
global send_msg, one_msg
if cont:
one_msg += f'\n{cont}'
send_msg += f'\n{cont}'
def send_notification_message(title):
try:
from notify import send
print("加载通知服务成功!")
send(title, send_msg)
except Exception as e:
if e:
print('发送通知消息失败!')
api_headers = {
'Host': 'api3.ali213.net',
'accept': '*/*',
'user-agent': 'ali213app',
'accept-language': 'zh-Hans-CN;q=1',
}
def get_user_ids_and_tokens(file_path='youxia_data.json'):
try:
# 1. 读取JSON文件
with open(file_path, 'r', encoding='utf-8') as f:
phone_data = json.load(f)
# 2. 遍历每个手机号
results = []
for phone_key, data in phone_data.items():
user_name = data.get('nickname')
user_token = data.get('token')
if user_name and user_token: # 确保userId和token存在
results.append({
'phone_key': phone_key,
'user_name': user_name,
'token': user_token
})
# print(f"手机号: {phone_key}, userId: {user_id}, token: {token}")
return results
except FileNotFoundError:
print(f"文件 {file_path} 不存在!")
return []
except json.JSONDecodeError:
print(f"文件 {file_path} 格式错误!")
return []
def save_or_update_phone_data(phone_key, new_data, file_path='youxia_data.json'):
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
existing_data = json.load(f)
else:
existing_data = {}
if phone_key in existing_data:
existing_data[phone_key].update(new_data) # 合并新旧数据
print(f"账号 [{phone_key}] 数据已更新!")
else:
existing_data[phone_key] = new_data # 新增数据
print(f"账号 [{phone_key}] 新增数据!")
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(existing_data, f, ensure_ascii=False, indent=4)
def get_userdata(u):
phone_user = u.split('&')[0]
phone_password = u.split('&')[1]
try:
with open('youxia_data.json', 'r', encoding='utf-8') as f:
cache_data = json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
cache_data = {}
if phone_user not in cache_data:
print(f'账号 {phone_user} 不存在于缓存中,尝试初始化数据')
login(phone_user, phone_password)
else:
print(f'账号 {phone_user} 已存在于缓存中,直接读取数据')
def md5_encode(string):
md5 = hashlib.md5()
md5.update(string.encode('utf-8'))
return md5.hexdigest()
def check_token(phone,token): # 检查token是否有效并返回新的token
try:
response = requests.get(f'https://api3.ali213.net/feedearn/checktoken?token={token}', headers=api_headers)
response_json = response.json()
if response_json['status'] == 1:
print(f'账号 [{phone}] token 有效')
save_or_update_phone_data(phone, {'token': response_json['token']})
return response_json['token']
else:
print(f'账号 [{phone}] token 无效')
log(f'账号 [{phone}] token 无效\n')
return None
except JSONDecodeError as e:
print(f'账号 [{phone}] 检查token失败: {e}')
except Exception as e:
print(f'账号 [{phone}] 检查token失败: {e}')
def token_exchanger(token):
headers = {
'Host': 'api3.ali213.net',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'sec-fetch-site': 'none',
'sec-fetch-mode': 'navigate',
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 ali213app',
'accept-language': 'zh-CN,zh-Hans;q=0.9',
'sec-fetch-dest': 'document',
}
response = requests.get('https://api3.ali213.net/feedearn/tokenexchanger?token='+token+'&redirectUrl=https://api3.ali213.net/feedearn/luckybox',headers=headers)
print(response.text)
def userinfo(phone,token):
try:
response = requests.get(f'https://api3.ali213.net/feedearn/userbaseinfo?token={token}', headers=api_headers)
response_json = response.json()
if '"status":0' in response.text:
print(f'账号 [{phone}] 登录过期,需要重新登录')
log(f'账号 [{phone}] 登录过期,需要重新登录\n')
else:
experience = response_json['experience']
nextgrade_experience = response_json['nextgrade']['experience']
nextgrade_experience_coin = response_json['nextgrade']['coin']
money = response_json['money'] / 100
# 计算百分比
percent = (experience / nextgrade_experience) * 100
print(f'账号 [{response_json["nickname"]}] Lv.{response_json["grade"]} 目前金币:{response_json["coins"]} 现金:{money} 剩余{percent:.2f}% 即可升级获得{nextgrade_experience_coin}金币')
log(f'账号 [{response_json["nickname"]}] Lv.{response_json["grade"]} 目前金币:{response_json["coins"]} 现金:{money} 剩余{percent:.2f}% 即可升级获得{nextgrade_experience_coin}金币\n')
except requests.exceptions.RequestException as e:
print(f'账号 [{phone}] 获取用户信息失败: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{phone}] 获取用户信息失败: {e}')
except Exception as e:
print(f'账号 [{phone}] 获取用户信息失败: {e}')
def check_sign(name,token):
try:
response = requests.get(f'https://api3.ali213.net/feedearn/signing?action=set&token={token}', headers=api_headers)
if r'\u7528\u6237\u672a\u767b\u5f55\u6216\u767b\u5f55\u5df2\u8d85\u65f6' in response.text:
print(f'账号 [{name}] 登录过期,需要重新登录')
else:
response_json = response.json()
if response_json['data']['status'] == 1:
print(f'账号 [{name}] {response_json["data"]["msg"]},获得金币:{response_json["data"]["coins"]}')
log(f'账号 [{name}] {response_json["data"]["msg"]},获得金币:{response_json["data"]["coins"]}\n')
elif response_json['data']['status'] == 0:
print(f'账号 [{name}] {response_json["data"]["msg"]}')
log(f'账号 [{name}] {response_json["data"]["msg"]}\n')
else:
print(f'账号 [{name}] 签到失败:{response.text}')
except requests.exceptions.RequestException as e:
print(f'账号 [{name}] 签到失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{name}] 签到失败[JSON]: {e}')
except Exception as e:
print(f'账号 [{name}] 签到失败[其他]: {e}')
def login(phone, password):
headers = {
'Host': 'i.ali213.net',
'accept': '*/*',
'user-agent': 'ali213app',
'accept-language': 'zh-Hans-CN;q=1',
}
time10 = str(int(time.time()))
params = {
'action': 'login',
'from': 'feedearn',
'passwd': password,
'signature': md5_encode(f'username-{phone}-time-{time10}-passwd-{password}-from-feedearn-action-loginBGg)K6ng4?&x9sCIuO%C2%' + '{@TJ?fnFJ,bZKy/[/EWnw9UsC$@1'),
'time': time10,
'username': phone,
}
try:
response = requests.get('https://i.ali213.net/api.html', params=params, headers=headers)
response.raise_for_status()
response_json = response.json()
if response_json['status'] == 1 and response_json['msg'] == '登录成功':
print('登录成功: ' + response_json['data']['userinfo']['nickname'])
log(f'账号 [{response_json["data"]["userinfo"]["nickname"]}] 登录成功\n')
new_data = {
'uid': response_json['data']['userinfo']['uid'],
'nickname': response_json['data']['userinfo']['nickname'],
'token': response_json['data']['token'],
}
save_or_update_phone_data(phone, new_data)
elif response_json['status'] == 0:
print('登录失败: ' + response_json['msg'])
log(f'登录失败: {response_json["msg"]}\n')
else:
print('登录失败: ' + response_json)
except requests.exceptions.RequestException as e:
print(e)
def newusercheck(name, token):
try:
response = requests.get(f'https://api3.ali213.net/feedearn/newusercheck?token={token}', headers=api_headers)
response_json = response.json()
if response_json['status'] == 1 and response_json['msg'] == '您是老用户,所以还是跳老活动页面吧' or response_json['msg'] == '您参与完新用户活动了,现在去老活动页面吧':
# print(f'账号 [{name}] 老用户了,去周签')
olduser_sign(name, token)
elif response_json['status'] == 3 and response_json['msg'] == '您是最新用户,可以跳最新活动页面了':
# print(f'账号 [{name}] 新用户,去首月福利签到')
newuser_sign(name, token)
else:
print(f'账号 [{name}] 未知状态: {response_json}')
except requests.exceptions.RequestException as e:
print(f'账号 [{name}] 检查新用户失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{name}] 检查新用户失败[JSON]: {e}')
except Exception as e:
print(f'账号 [{name}] 检查新用户失败[其他]: {e}')
def newuser_sign(name, token):
try:
response = requests.get(f'https://api3.ali213.net/feedearn/newuseractivitysign?token={token}', headers=api_headers)
response_json = response.json()
if response_json['status'] == 1:
print(f'账号 [{name}] 新用户福利: {response_json["msg"]}')
log(f'账号 [{name}] 新用户福利: {response_json["msg"]}\n')
newuser_monthsigncheck(name, token)
elif response_json['status'] == 0:
print(f'账号 [{name}] 新用户福利: {response_json["msg"]}')
log(f'账号 [{name}] 新用户福利: {response_json["msg"]}\n')
newuser_monthsigncheck(name, token)
else:
print(f'账号 [{name}] 新用户福利:签到失败 {response.text}')
except requests.exceptions.RequestException as e:
print(f'账号 [{name}] 新用户福利签到失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{name}] 新用户福利签到失败[JSON]: {e}')
except Exception as e:
print(f'账号 [{name}] 新用户福利签到失败[其他]: {e}')
def newuser_monthsigncheck(name, token):
try:
response = requests.get(f'https://api3.ali213.net/feedearn/newusermonthactivity?token={token}', headers=api_headers)
response_json = response.json()
if response_json['status'] == 1:
prize = response_json['data']['prize']
today = datetime.datetime.now().strftime('%Y-%m-%d')
for item in prize:
if item['date'] == today:
print(f"账号 [{name}] 【新用户首月福利】 今天({today})的签到信息:")
log(f'账号 [{name}] 【新用户首月福利】 今天({today})的签到信息:\n')
newuser_kjl(name, token, item['con'], item['tit'], item['typeid'])
break
else:
print('没有获取到当天签到数据')
log('没有获取到当天签到数据\n')
month_day = response_json["data"]["qztime"].split(',')
print(f'账号 [{name}] 【新用户首月福利】已签到: {response_json["data"]["wcday"]}天,已领取{response_json["data"]["totalcoin"]}金币')
log(f'账号 [{name}] 【新用户首月福利】已签到: {response_json["data"]["wcday"]}天,已领取{response_json["data"]["totalcoin"]}金币\n')
print(f'账号 [{name}] 【新用户首月福利】从{month_day[0]}开始,到{month_day[1]}结束。记得绑定Steam账号才能领取奖励')
elif response_json['status'] == 0:
print(f'账号 [{name}] 新用户月签查询失败: {response_json["msg"]}')
log(f'账号 [{name}] 新用户月签查询失败: {response_json["msg"]}\n')
else:
print(f'账号 [{name}] 新用户月签查询失败: {response.text}')
log(f'账号 [{name}] 新用户月签查询失败: {response.text}\n')
except requests.exceptions.RequestException as e:
print(f'账号 [{name}] 新用户月签查询失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{name}] 新用户月签查询失败[JSON]: {e}')
except Exception as e:
print(f'账号 [{name}] 新用户月签查询失败[其他]: {e}')
def olduser_sign(name, token):
try:
response = requests.get(f'https://api3.ali213.net/feedearn/olduseractivitysign?token={token}', headers=api_headers)
response_json = response.json()
if response_json['status'] == 1:
print(f'账号 [{name}] 老用户福利: {response_json["msg"]}')
log(f'账号 [{name}] 老用户福利: {response_json["msg"]}\n')
olduser_weeksigncheck(name, user_token)
elif response_json['status'] == 0:
print(f'账号 [{name}] 老用户福利: {response_json["msg"]}')
log(f'账号 [{name}] 老用户福利: {response_json["msg"]}\n')
olduser_weeksigncheck(name, user_token)
else:
print(f'账号 [{name}] 老用户福利:签到失败 {response.text}')
except requests.exceptions.RequestException as e:
print(f'账号 [{name}] 老用户福利签到失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{name}] 老用户福利签到失败[JSON]: {e}')
except Exception as e:
print(f'账号 [{name}] 老用户福利签到失败[其他]: {e}')
def olduser_weeksigncheck(name, token):
try:
response = requests.get(f'https://api3.ali213.net/feedearn/oldusermonthactivity?token={token}', headers=api_headers)
response_json = response.json()
if response_json['status'] == 1:
print(f'账号 [{name}] 【第{response_json["data"]["prizingno"]}阶段】已达成连续签到: {response_json["data"]["signday"]}')
log(f'账号 [{name}] 【第{response_json["data"]["prizingno"]}阶段】已达成连续签到: {response_json["data"]["signday"]}\n')
if response_json["data"]["signday"] == 7:
print(f'账号 [{name}] 第七天了,可领取奖励')
time.sleep(5)
kjl(name, token)
elif response_json['status'] == 0:
print(f'账号 [{name}] 周签查询失败: {response_json["msg"]}')
log(f'账号 [{name}] 周签查询失败: {response_json["msg"]}\n')
else:
print(f'账号 [{name}] 周签查询失败: {response.text}')
except requests.exceptions.RequestException as e:
print(f'账号 [{name}] 周签查询失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{name}] 周签查询失败[JSON]: {e}')
except Exception as e:
print(f'账号 [{name}] 周签查询失败[其他]: {e}')
def kjl(name, token):
try:
response = requests.get(f'https://api3.ali213.net/feedearn/olduseractivityprizing?token={token}', headers=api_headers)
response_json = response.json()
if response_json['status'] == 1 and response_json['msg'] == '恭喜中奖':
print(f'账号 [{name}] 已领取奖励: 《{response_json["data"]["name"]}')
log(f'账号 [{name}] 已领取奖励: 《{response_json["data"]["name"]}\n')
elif response_json['status'] == 0:
print(f'账号 [{name}] 领取奖励失败: {response_json["msg"]}')
log(f'账号 [{name}] 领取奖励失败: {response_json["msg"]}\n')
else:
print(f'账号 [{name}] 领取奖励失败: {response.text}')
except requests.exceptions.RequestException as e:
print(f'账号 [{name}] 领取奖励失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{name}] 领取奖励失败[JSON]: {e}')
except Exception as e:
print(f'账号 [{name}] 领取奖励失败[其他]: {e}')
def newuser_kjl(name,token,coin,mem,typeid):
try:
params = {
"coin": coin,
"mem": mem,
"token": token,
"typeid": str(typeid)
}
response = requests.post("https://api3.ali213.net/feedearn/newuserprizing", params=params, headers=api_headers)
response_json = response.json()
if response_json['status'] == 1 and response_json['msg'] == '成功':
print(f'账号 [{name}] 【新用户首月福利】已领取奖励: {coin}')
log(f'账号 [{name}] 【新用户首月福利】已领取奖励: {coin}\n')
elif response_json['status'] == 0:
print(f'账号 [{name}] 【新用户首月福利】领取奖励失败: {response_json["msg"]}')
log(f'账号 [{name}] 【新用户首月福利】领取奖励失败: {response_json["msg"]}\n')
else:
print(f'账号 [{name}] 【新用户首月福利】领取奖励失败: {response.text}')
except requests.exceptions.RequestException as e:
print(f'账号 [{name}] 【新用户首月福利】领取奖励失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{name}] 【新用户首月福利】领取奖励失败[JSON]: {e}')
except Exception as e:
print(f'账号 [{name}] 【新用户首月福利】领取奖励失败[其他]: {e}')
def luckbox_cookies(phone, token):
headers = {
'Host': 'api3.ali213.net',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'sec-fetch-site': 'none',
'sec-fetch-mode': 'navigate',
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 ali213app',
'accept-language': 'zh-CN,zh-Hans;q=0.9',
'sec-fetch-dest': 'document',
}
try:
response = requests.get(f'https://api3.ali213.net/feedearn/tokenexchanger?token={token}&redirectUrl=https://api3.ali213.net/feedearn/luckybox', headers=headers)
api3AliSSO = response.cookies.get_dict()
if api3AliSSO:
print(f'账号 [{phone}] 获取神秘宝箱cookies成功')
save_or_update_phone_data(phone, api3AliSSO)
else:
print(f'账号 [{phone}] 获取神秘宝箱cookies失败')
log(f'账号 [{phone}] 获取神秘宝箱cookies失败\n')
except requests.exceptions.RequestException as e:
print(f'账号 [{phone}] 获取神秘宝箱cookies失败[请求]: {e}')
except Exception as e:
print(f'账号 [{phone}] 获取神秘宝箱cookies失败[其他]: {e}')
def usermission(name,token):
try:
response = requests.get(f'https://api3.ali213.net/feedearn/usermission?token={token}', headers=api_headers)
response_json = response.json()
if response_json['status'] == 1:
print(f'账号 [{name}] 任务查询成功')
common_mission = response_json['data']['common']
if common_mission:
for mission in common_mission:
mission_name = mission['title']
mission_experience = mission['experience']
mission_total = mission['total']
mission_prize = mission['prize']
print(f'任务名称: {mission_name}, 每日次数: {mission_total}, 奖励经验: {mission_experience}, {mission_prize}')
elif response_json['status'] == 0:
print(f'账号 [{name}] 任务查询失败: {response_json["msg"]}')
else:
print(f'账号 [{name}] 任务查询失败: {response.text}')
except requests.exceptions.RequestException as e:
print(f'账号 [{name}] 任务查询失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{name}] 任务查询失败[JSON]: {e}')
except Exception as e:
print(f'账号 [{name}] 任务查询失败[其他]: {e}')
def share(name,token,entity_id):
try:
response = requests.get(f'https://api3.ali213.net/feedearn/sharearticle?channelID=1&entityID={entity_id}&token={token}', headers=api_headers)
response_json = response.json()
if response_json['status'] == 1:
print(f'账号 [{name}] 分享成功,奖励: {response_json["msg"]}金币')
elif response_json['status'] == 0:
print(f'账号 [{name}] 分享失败: {response_json["msg"]}')
else:
print(f'账号 [{name}] 分享失败: {response.text}')
except requests.exceptions.RequestException as e:
print(f'账号 [{name}] 分享失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{name}] 分享失败[JSON]: {e}')
except Exception as e:
print(f'账号 [{name}] 分享失败[其他]: {e}')
def get_recommendList():
try:
response = requests.get('https://newapi.ali213.net/app/v1/recommendList?confirmNo=0&keyword=&lastId=&navId=2&pageNo=1&pageNum=10', headers=api_headers)
response_json = response.json()
if response_json['code'] == 200:
print('推荐列表数据获取成功')
data = response_json['data']['list']
integer_jump_urls = []
for item in data:
if isinstance(item.get('jumpUrl'), int):
integer_jump_urls.append(item['jumpUrl'])
return integer_jump_urls
else:
print('推荐列表数据获取失败')
log(f'推荐列表数据获取失败\n')
return []
except requests.exceptions.RequestException as e:
print(f'推荐列表数据获取失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'推荐列表数据获取失败[JSON]: {e}')
except Exception as e:
print(f'推荐列表数据获取失败[其他]: {e}')
def get_square():
try:
response = requests.get('https://club.ali213.net/application/forum/square?id=0', headers=api_headers)
response_json = response.json()
if response_json['code'] == 111 and response_json['msg'] == 'success':
print('BBS社区数据获取成功')
threadList = response.json()['data']['threadList']
thread_id = []
for item in threadList:
thread_id.append(item['id'])
return thread_id
else:
print('BBS社区数据获取失败')
log(f'BBS社区数据获取失败\n')
return []
except requests.exceptions.RequestException as e:
print(f'BBS社区数据获取失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'BBS社区数据获取失败[JSON]: {e}')
except Exception as e:
print(f'BBS社区数据获取失败[其他]: {e}')
def readingreward(name,token,threadid):
try:
response = requests.get(f'https://club.ali213.net/application/thread/readingreward?threadid={threadid}&token={token}', headers=api_headers)
response_json = response.json()
if response_json['code'] == 111 and response_json['msg'] == 'success':
print(f'账号 [{name}] 阅读奖励成功,奖励: {response_json["data"]}金币')
elif response_json['code'] == -1 and response_json['msg'] == 'failed':
print(f'账号 [{name}] 阅读奖励失败: 已领取过奖励')
else:
print(f'账号 [{name}] 阅读奖励失败: {response.text}')
except requests.exceptions.RequestException as e:
print(f'账号 [{name}] 阅读奖励失败[请求]: {e}')
except json.JSONDecodeError as e:
print(f'账号 [{name}] 阅读奖励失败[JSON]: {e}')
except Exception as e:
print(f'账号 [{name}] 阅读奖励失败[其他]: {e}')
if __name__ == '__main__':
print('*'*50)
all_user = len(yxwlogin)
print(f"检测到环境变量中存在{all_user}个账号")
for yxwlogin_item in yxwlogin:
get_userdata(yxwlogin_item)
user_data = get_user_ids_and_tokens()
if not user_data:
print("未读取到用户数据,程序退出")
exit(0)
else:
print(f"读取到{len(user_data)}个账号")
recommendList = get_recommendList()
square = get_square()
print('*'*50)
for item in user_data:
print('-' * 50)
log('-' * 35)
user_phone = item['phone_key']
user_name = item['user_name']
user_token = item['token']
new_user_token = check_token(user_phone,user_token)
if new_user_token:
check_sign(user_name, new_user_token)
newusercheck(user_name, new_user_token)
luckbox_cookies(user_phone, user_token)
# usermission(user_name, new_user_token)
if recommendList:
for entity_id in recommendList:
share(user_name, new_user_token, entity_id)
time.sleep(1)
else:
print(f'账号 [{user_phone}] 推荐列表为空')
if square:
for thread_id in square:
readingreward(user_name, new_user_token, thread_id)
time.sleep(1)
else:
print(f'账号 [{user_phone}] BBS社区列表为空')
userinfo(user_phone, new_user_token)
else:
print(f'账号 [{user_phone}] 获取数据失败')
continue
try:
send_notification_message(title='游侠网开宝箱') # 发送通知
except Exception as e:
print('推送失败:' + str(e))

View File

@@ -0,0 +1,118 @@
# Source: https://github.com/lksky8/sign-ql/blob/main/yxw_luckbox.py
# Raw: https://raw.githubusercontent.com/lksky8/sign-ql/main/yxw_luckbox.py
# Repo: lksky8/sign-ql
# Path: yxw_luckbox.py
# UploadedAt: 2025-08-21T12:12:12Z
# SHA256: 7951192443b96cec1fe801de769343a2e080be439b46c9b2bfb4372a4cdfe2e1
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
'''
作者https://github.com/lksky8/sign-ql/
日期2025-8-21
软件:游侠网-开宝箱
功能每隔三小时自动开宝箱领取50金币
定时0,5 */3 * * *
'''
import json
import requests
import time
send_msg = ''
one_msg = ''
def log(cont=''):
global send_msg, one_msg
if cont:
one_msg += f'{cont}\n'
send_msg += f'{cont}\n'
def send_notification_message(title):
try:
from notify import send
print("加载通知服务成功!")
send(title, send_msg)
except Exception as e:
if e:
print('发送通知消息失败!')
def get_user_ids_and_tokens(file_path='youxia_data.json'):
try:
# 1. 读取JSON文件
with open(file_path, 'r', encoding='utf-8') as f:
phone_data = json.load(f)
# 2. 遍历每个手机号
results = []
for phone_key, data in phone_data.items():
user_name = data.get('nickname')
user_token = data.get('token')
api3AliSSO_cookie = data.get('api3AliSSO')
if user_name and user_token: # 确保userId和token存在
results.append({
'phone_key': phone_key,
'user_name': user_name,
'api3AliSSO': api3AliSSO_cookie
})
# print(f"手机号: {phone_key}, userId: {user_id}, token: {token}")
return results
except FileNotFoundError:
print(f"文件 {file_path} 不存在!")
return []
except json.JSONDecodeError:
print(f"文件 {file_path} 格式错误!")
return []
def do_sign(phone, user_name, ck):
headers = {
"user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 ali213app"
}
cookies = {
"api3AliSSO": ck
}
try:
response = requests.get("https://api3.ali213.net/feedearn/luckybox?action=get", headers=headers,cookies=cookies)
response.raise_for_status()
response_json = response.json()
if response_json['logined']:
print(f"账号 [{phone}][{user_name}] 登录成功CK有效")
print(f"账号 [{phone}][{user_name}] {response_json['data']['msg']}")
if response_json['data']['status'] == 1 and response_json['data']['msg'] == '领取成功':
print(f"账号 [{phone}][{user_name}] 获得{response_json['data']['coins']}金币")
else:
print(f"账号 [{phone}][{user_name}] 登录失败CK无效")
log(f"账号 [{phone}][{user_name}] 登录失败CK无效")
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
except json.JSONDecodeError as e:
print(f"JSON解析错误: {e}")
except Exception as e:
print(f"其他错误: {e}")
if __name__ == '__main__':
user_data = get_user_ids_and_tokens()
if not user_data:
print("未读取到用户数据,程序退出")
exit(0)
else:
print(f"读取到{len(user_data)}个账号")
for item in user_data:
phone = item['phone_key']
user_name = item['user_name']
ck = item['api3AliSSO']
do_sign(phone, user_name, ck)
time.sleep(1)
print("-" * 50)
try:
send_notification_message(title='游侠网开宝箱') # 发送通知
except Exception as e:
print('推送失败:' + str(e))

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,297 @@
# Source: https://github.com/lksky8/sign-ql/blob/main/jksign.py
# Raw: https://raw.githubusercontent.com/lksky8/sign-ql/main/jksign.py
# Repo: lksky8/sign-ql
# Path: jksign.py
# UploadedAt: 2025-12-07T17:42:50Z
# SHA256: b722f903ef41b1cab2540fc2a7b84bb51cb2e8d354783a225e3c364b0799a4e6
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
方舟健客app签到
作者https://github.com/lksky8/sign-ql
日期2025-12-5
使用方法APP抓登录包获取refresh_token填入jktoken
支持多用户运行,多用户用&或者@隔开
则变量为
export jktoken="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9........&eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9........"
每日签到一次即可
cron: 0 5 * * *
const $ = new Env("方舟健客签到");
"""
import time
import requests
import re
import os
import datetime
import hashlib
#推送开关开启为True关闭为False
push_message = True
def md5_encrypt(text):
md5_hash = hashlib.md5()
md5_hash.update(text.encode('utf-8'))
md5_result = md5_hash.hexdigest()
return md5_result
def time13():
now = datetime.datetime.now()
timestamp_ms = int(now.timestamp() * 1000) + (now.microsecond // 1000)
return timestamp_ms
def get_jkx():
a = time13() - 1500000000000
j = a % 999983
j2 = a % 9973
h = "6470"
md5_1 = md5_encrypt(f"39CC231D-C1F9-48DC-93DA-4CA0EA53C141{j}{h}")
md5_2 = md5_encrypt(f"{md5_1}{j2}{h}")
return f'{j}#{md5_2}#{j2}#{h}'
api_headers = {
'Host': 'acgi.jianke.com',
'Accept': 'application/json, text/plain, */*',
'Sec-Fetch-Site': 'same-site',
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'platform': 'APP',
'Sec-Fetch-Mode': 'cors',
'Origin': 'https://app-hybrid.jianke.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 jiankeMall/6.47.0 JiankeMall/6.47.0',
'Referer': 'https://app-hybrid.jianke.com/',
'Content-Type': 'application/json;charset=utf-8',
'Sec-Fetch-Dest': 'empty',
}
api_headers2 = {
'Host': 'fe-acgi.jianke.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 jiankeMall/6.47.0',
'versionName': '6.47.0',
'X-JK-UDID': '39CC231D-C1F9-48DC-93DA-4CA0EA53C141',
'versionCode': '6470',
'X-JK-X': get_jkx(),
'platform': 'APP',
'Accept-Language': 'zh-Hans-CN;q=1',
'Accept': 'application/json',
'Content-Type': 'application/json',
}
send_msg = ''
one_msg = ''
def Log(cont=''):
global send_msg, one_msg
if cont:
one_msg += f'{cont}\n'
send_msg += f'{cont}\n'
def send_notification_message(title):
try:
from notify import send
print("加载通知服务成功!")
send(title, send_msg)
except Exception as e:
if e:
print('发送通知消息失败!')
def refresh_token(token):
headers = {'Content-Type': 'application/json; charset=utf-8','User-Agent': 'Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.135 Mobile Safari/537.36 jiankeMall/6.26.0(w1080*h2029)','Host': 'acgi.jianke.com','organizationCode': 'app.jianke'}
data = {'refreshToken': token }
response = requests.post('https://acgi.jianke.com/passport/account/refreshToken', json=data, headers=headers)
if '授权失败' in response.text:
print('账号刷新token已失效请重新获取')
Log('账号刷新token已失效请重新获取')
return False
else:
response_json = response.json()
if response_json['token_type'] == 'bearer':
print("账号token刷新成功新的access_token已填入:\n" + response_json['access_token'])
return response_json['access_token']
else:
print("Failed to send POST request. Status Code:", response.status_code)
print("出错了:", response.text)
def do_sign(new_token,user_name):
# headers = api_headers2.copy()
# headers['Authorization'] = f'bearer {new_token}'
headers = {'Authorization':'bearer ' + new_token,'User-Agent': 'Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.135 Mobile Safari/537.36 jiankeMall/6.26.0(w1080*h2029)','X-JK-X': get_jkx(),'versionName': '6.47.0','X-JK-UDID': '39CC231D-C1F9-48DC-93DA-4CA0EA53C141'}
dl = requests.put('https://acgi.jianke.com/v2/member/signConfig/sign', headers=headers)
dl_json = dl.json()
if dl.status_code == 200:
print(f"[{user_name}] 本次签到获得:{dl_json['coinNum']}金币,今天是本周第{dl_json['cumulativeNum']}天签到")
Log(f"\n{user_name}] 本次签到获得:{dl_json['coinNum']}金币,今天是本周第{dl_json['cumulativeNum']}天签到")
elif dl_json['message'] == '今日已签到':
print(f'[{user_name}] 今天已经签到了')
Log(f'\n[{user_name}] 今天已经签到了')
else:
print("出错了:", dl.text)
def today_question(new_token,task_id,user_name):
headers = api_headers.copy()
headers['Authorization'] = f'bearer {new_token}'
response = requests.get('https://acgi.jianke.com/support/coin/task/daily-tasks/today-question', headers=headers)
response_json = response.json()
if response_json['code'] == '0' and response_json['message'] == 'success':
print(f'[{user_name}]【每日一答】 任务获取成功')
question_id = response_json['data']['id']
rightChoice = response_json['data']['rightChoice']
json_data = {
'id': str(task_id),
'questionItem': {
'id': question_id,
'rightChoice': rightChoice,
'userChoice': rightChoice,
'roundNum': 1,
},
}
response = requests.post('https://acgi.jianke.com/support/coin/task/complete', headers=headers, json=json_data)
response_json = response.json()
if response_json['code'] == '0' and response_json['message'] == 'success':
print(f'[{user_name}]【每日一答】 任务完成')
Log(f'[{user_name}]【每日一答】 任务完成')
else:
print(f'[{user_name}]【每日一答】 {response_json["message"]}')
Log(f'[{user_name}]【每日一答】 {response_json["message"]}')
else:
print(f'[{user_name}]【每日一答】 任务获取失败')
Log(f'[{user_name}]【每日一答】 任务获取失败')
print(response.text)
def get_today_tasks(new_token, user_name):
headers = api_headers.copy()
headers['Authorization'] = f'bearer {new_token}'
response = requests.get('https://acgi.jianke.com/support/coin/task/daily-tasks', headers=headers)
if response.status_code == 200:
response_json = response.json()
task_list = []
for item in response_json['data']:
task_id = item['id']
task_name = item['taskName']
task_list.append({'task_id': task_id, 'task_name': task_name})
return task_list
else:
print(f'{user_name} 获取任务数据失败')
print(response.text)
return None
def do_task(new_token,user_name, task_id, task_name):
headers = api_headers.copy()
headers['Authorization'] = f'bearer {new_token}'
json_data = {
'id': str(task_id)
}
response = requests.post('https://acgi.jianke.com/support/coin/task/complete', headers=headers, json=json_data)
response_json = response.json()
if response_json['code'] == '0' and response_json['message'] == 'success':
print(f'[{user_name}]【{task_name}】 任务完成')
Log(f'[{user_name}]【{task_name}】 任务完成')
else:
print(f'[{user_name}]【{task_name}{response_json["message"]}')
Log(f'[{user_name}]【{task_name}{response_json["message"]}')
def task_receive(new_token, user_name, task_id,task_name):
headers = api_headers.copy()
headers['Authorization'] = f'bearer {new_token}'
json_data = {
'id': task_id,
}
response = requests.post('https://acgi.jianke.com/support/coin/task/receive', headers=headers, json=json_data)
response_json = response.json()
if response_json['code'] == '0' and response_json['message'] == 'success':
print(f'[{user_name}]【{task_name}】 任务奖励:领取成功')
elif response_json['message'] == '奖励领取失败':
print(f'[{user_name}]【{task_name}】 任务奖励:领取失败')
Log(f'[{user_name}]【{task_name}】 任务奖励:领取失败')
else:
print('奖励领取失败')
print(response.text)
def get_coin(new_token, user_name):
headers = api_headers.copy()
headers['Authorization'] = f'bearer {new_token}'
response = requests.get('https://acgi.jianke.com/v1/coin/balance', headers=headers)
if response.status_code == 200:
response_json = response.json()
print(f'[{user_name}] 当前健康币:{response_json["balance"]}')
Log(f'[{user_name}] 当前健康币:{response_json["balance"]}')
else:
print('获取金币数失败')
print(response.text)
def get_userinfo(new_token):
headers = api_headers2.copy()
headers['Authorization'] = f'bearer {new_token}'
response = requests.get('https://fe-acgi.jianke.com/v5/userCenter', headers=headers)
response_json = response.json()
if response_json['statusCode'] == 200:
return response_json['data']['memberInfo']['nickName']
else:
print('获取用户信息失败')
print(response.text)
return None
if __name__ == '__main__':
if 'jktoken' in os.environ:
jktoken = re.split("@|&", os.environ.get("jktoken"))
print(f'查找到{len(jktoken)}个账号')
else:
jktoken = []
print('未填写 jktoken 变量')
if jktoken:
try:
z = 1
for ck in jktoken:
print(f'登录第{z}个账号')
print('----------------------\n')
access_token = refresh_token(ck)
if access_token:
user_nickname = get_userinfo(access_token)
print(f'[{user_nickname}] 刷新token成功')
print('\n开始签到操作>>>>>>>>>>\n')
do_sign(access_token, user_nickname)
print('\n开始执行任务>>>>>>>>>>\n')
task_data = get_today_tasks(access_token, user_nickname)
if task_data:
for task in task_data:
task_id = task['task_id']
task_name = task['task_name']
# print(f'[{user_nickname}] 开始执行任务:{task_name}')
if task_name == '每日一答':
today_question(access_token, task_id, user_nickname)
time.sleep(1)
task_receive(access_token, user_nickname, task_id, task_name)
time.sleep(2)
continue
if task_name == '下单返币':
continue
if task_name == '打开健客医生App':
continue
do_task(access_token, user_nickname, task_id, task_name)
time.sleep(1)
task_receive(access_token, user_nickname, task_id, task_name)
time.sleep(3)
get_coin(access_token, user_nickname)
print('\n----------------------')
z = z + 1
except Exception as e:
print('未知错误:' + str(e))
if push_message:
try:
send_notification_message(title='方舟健客') # 发送通知
except Exception as e:
print('推送失败:' + str(e))

View File

@@ -0,0 +1,389 @@
# Source: https://github.com/lksky8/sign-ql/blob/main/xxcd.py
# Raw: https://raw.githubusercontent.com/lksky8/sign-ql/main/xxcd.py
# Repo: lksky8/sign-ql
# Path: xxcd.py
# UploadedAt: 2025-09-01T15:45:21Z
# SHA256: 40e3aef421127efd0fe80201c786cf341993dd4e8318fe4f8456a912aef026e0
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
星星充电签到
作者https://github.com/lksky8/sign-ql
日期2025-09-01
使用方法打开app随便抓一个包把头部'Authorization'内容填入 export startoken=""
另外可以再填入cityid(抓包获取), export starcityid=""可填可不填
支持多用户运行,多用户用&或者@隔开
export startoken="eyJ0eXAiOiJKV1QiLCJhbGciOiJIU1NiJ9..&eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1J9.."
export starcityid=""
每天运行一次即可
cron: 0 7 * * *
const $ = new Env("星星充电签到");
"""
import requests
import re
import os
import datetime
import hashlib
import time
if 'startoken' in os.environ:
startoken = re.split("@|&",os.environ.get("startoken"))
print(f'查找到{len(startoken)}个账号\n')
else:
startoken =['']
print('无startoken变量')
if 'starcityid' in os.environ:
cityid = os.environ.get("starcityid")
print(f'已填入cityid:{cityid}')
else:
cityid = '440000'
print('没有填写cityid,系统默认使用440000')
def md5_encrypt(text):
md5_hash = hashlib.md5()
md5_hash.update(text.encode('utf-8'))
md5_result = md5_hash.hexdigest()
return md5_result
def time13():
now = datetime.datetime.now()
timestamp_ms = int(now.timestamp() * 1000) + (now.microsecond // 1000)
return str(timestamp_ms)
def find_task_ids(data):
this_week_task_id = None
this_month_task_id = None
for model in data:
for task in model['taskList']:
if task['taskName'] == '本周充电任务':
this_week_task_id = task['taskId']
elif task['taskName'] == '本月充电任务':
this_month_task_id = task['taskId']
return this_week_task_id, this_month_task_id
send_msg = ''
one_msg = ''
def Log(cont=''):
global send_msg, one_msg
if cont:
one_msg += f'{cont}\n'
send_msg += f'{cont}\n'
# 发送通知消息
def send_notification_message(title):
try:
from notify import send
print("加载通知服务成功!")
send(title, send_msg)
except Exception as e:
if e:
print('发送通知消息失败!')
def sign(token):
try:
timestamp = time13()
signature = md5_encrypt(f'nonce=2b4aa7d9-4137-4e51-94e3-7b7355bf202a&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
'appVersion': '7.40.0',
'Origin': 'https://scm-app-h5.starcharge.com',
'signature': signature,
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Site': 'same-site',
'referrer': 'web',
'timestamp': timestamp,
'positCity': cityid,
'Authorization': token,
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'Accept': 'application/json, text/plain, */*',
'channel-id': '98',
'Sec-Fetch-Mode': 'cors',
'Content-Type': 'application/x-www-form-urlencoded',
}
data = {
'nonce': '2b4aa7d9-4137-4e51-94e3-7b7355bf202a',
'timestamp': timestamp,
'userId': '',
}
response = requests.post('https://gateway.starcharge.com/apph5/webApiV2/starPoint/sign',headers=headers, data=data)
response_json = response.json()
if response_json['code'] == '200':
print(f"签到成功:获得{response_json['data']['basePoint']}积分,已连续签到{response_json['data']['continuousDay']}")
Log(f"签到成功:获得{response_json['data']['basePoint']}积分,已连续签到{response_json['data']['continuousDay']}")
return True
elif response_json['code'] == '402':
print('用户数据获取失败,重新尝试获取数据')
return False
else:
print("签到失败:", response.text)
return False
except requests.exceptions.RequestException as e:
print("Failed to send POST request. Status Code:", response.status_code)
except Exception as e:
print("签到出错了:", e)
def Get_list(token):
try:
timestamp = time13()
signature = md5_encrypt(f'city={cityid}&nonce=1b93f289-32ee-4616-a860-5aef04c6c048&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'Accept': 'application/json, text/plain, */*',
'memberAdType': '0-0',
'Authorization': token,
'timestamp': timestamp,
'appVersion': '7.40.0',
'channel-id': '98',
'referrer': 'web',
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'signature': signature,
'positCity': cityid,
'Origin': 'https://scm-app-h5.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_8_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
}
response = requests.get(f'https://gateway.starcharge.com/apph5/webApiV2/userTask/model/list?city={cityid}&nonce=1b93f289-32ee-4616-a860-5aef04c6c048',headers=headers)
response_json = response.json()
if response_json['code'] == '200':
return response_json['data']
else:
print("获取任务列表失败:", response.text)
return False
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
except Exception as e:
print("获取任务列表出错了:", e)
def Do_task(task_id,token):
try:
timestamp = time13()
signature = md5_encrypt(f'nonce=4f63ecd8-e342-4e33-94a4-81bdfd040235&taskId={task_id}&taskType=1&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'Accept': 'application/json, text/plain, */*',
'memberAdType': '0-0',
'Authorization': token,
'timestamp': timestamp,
'appVersion': '7.40.0',
'channel-id': '98',
'referrer': 'web',
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'signature': signature,
'positCity': cityid,
'Origin': 'https://scm-app-h5.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_8_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
}
response = requests.get(f'https://gateway.starcharge.com/apph5/webApiV2/userTask/get?taskId={task_id}&taskType=1&nonce=4f63ecd8-e342-4e33-94a4-81bdfd040235', headers=headers)
response_json = response.json()
if response_json['code'] == None:
return response_json['text']
elif response_json['code'] == '200' and response_json['text'] == None :
return '任务已领取'
else:
print("做任务:", response.text)
return False
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
def Get_info(token):
try:
timestamp = time13()
signature = md5_encrypt(f'city={cityid}&nonce=b7e92ec1-813f-4ec2-ab8a-e91289604733&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
'appVersion': '7.40.0',
'Origin': 'https://scm-app-h5.starcharge.com',
'signature': signature,
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Site': 'same-site',
'referrer': 'web',
'timestamp': timestamp,
'positCity': cityid,
'Authorization': token,
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'Accept': 'application/json, text/plain, */*',
'channel-id': '98',
'Sec-Fetch-Mode': 'cors',
'Content-Type': 'application/x-www-form-urlencoded',
}
response = requests.get(f'https://gateway.starcharge.com/apph5/v2/webApiV2/star/point/user?city={cityid}&nonce=b7e92ec1-813f-4ec2-ab8a-e91289604733', headers=headers)
response_json = response.json()
if response_json['code'] == '200':
print(f'用户({response_json["data"]["nickName"]})目前金币:{response_json["data"]["points"]}')
Log(f'用户({response_json["data"]["nickName"]})目前金币:{response_json["data"]["points"]}\n')
else:
print('用户数据查询失败:' + response.text)
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
except Exception as e:
print("查询用户数据出错了:", e)
def Get_user_info(token):
try:
timestamp = time13()
signature = md5_encrypt(f'cityCode={cityid}&nonce=b6efee74-2ad5-43b3-bf3f-2435613c7c9d&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'Accept': 'application/json, text/plain, */*',
'Authorization': token,
'timestamp': timestamp,
'Sec-Fetch-Site': 'same-site',
'appVersion': '7.40.0',
'channel-id': '98',
'referrer': 'web',
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'signature': signature,
'Sec-Fetch-Mode': 'cors',
'Origin': 'https://scm-app-h5.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
'positCity': cityid,
'Sec-Fetch-Dest': 'empty',
}
response = requests.get(f'https://gateway.starcharge.com/apph5/webApiV2/user/getUserBaseInfo?cityCode={cityid}&nonce=b6efee74-2ad5-43b3-bf3f-2435613c7c9d', headers=headers)
response_data = response.json()
if response_data['code'] == '200':
if response_data['data']['appVipType'] == 1:
print(f'用户({response_data["data"]["nickName"]})已开通VIP到期日{response_data["data"]["appVipExpiration"]}')
vip_sign(token)
check_vip_sign(token)
else:
print(f'用户({response_data["data"]["nickName"]}) 未开通VIP')
else:
print('查询是否VIP失败:' + response.text)
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
except Exception as e:
print("查询是否VIP出错了:", e)
def vip_sign(token):
try:
timestamp = time13()
signature = md5_encrypt('nonce=8f396424-3729-4f50-bf67-bfb8fe38b9c5&timestamp='+timestamp+'&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
'appVersion': '7.40.0',
'Origin': 'https://scm-app-h5.starcharge.com',
'signature': signature,
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Site': 'same-site',
'referrer': 'web',
'timestamp': timestamp,
'positCity': '440600',
'Authorization': token,
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'Accept': 'application/json, text/plain, */*',
'channel-id': '98',
'Sec-Fetch-Mode': 'cors',
'Content-Type': 'application/x-www-form-urlencoded',
}
data = {
'nonce': '8f396424-3729-4f50-bf67-bfb8fe38b9c5',
'timestamp': timestamp,
'userId': '',
}
response = requests.post('https://gateway.starcharge.com/apph5/webApiV2/member/v5/home/sign',headers=headers, data=data).json()
if response['code'] == '200':
print(f"VIP任务签到成功")
else:
print("VIP任务签到失败" + response['text'])
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
except Exception as e:
print("出错了:", e)
def check_vip_sign(token):
try:
timestamp = time13()
signature = md5_encrypt(f'cycleType=1&nonce=2d3d2147-dbce-42b4-8fa9-9268b4fa580f&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'memberAdType': '0-0',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://app-taro.starcharge.com/',
'appVersion': '7.40.0',
'Origin': 'https://app-taro.starcharge.com',
'signature': signature,
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Site': 'same-site',
'referrer': 'web',
'timestamp': timestamp,
'positCity': '440600',
'Authorization': token,
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'Accept': '*/*',
'Content-Type': 'application/x-www-form-urlencoded',
'channel-id': '98',
'Sec-Fetch-Mode': 'cors',
}
response = requests.get(f'https://gateway.starcharge.com/apph5/webApiV2/member/v5/home/sign/records?cycleType=1&nonce=2d3d2147-dbce-42b4-8fa9-9268b4fa580f&timestamp={timestamp}&userId=',headers=headers).json()
if response['code'] == '200':
print(f"VIP任务已连续签到{response['data']['continuousDays']}")
else:
print("VIP任务查询失败" + response)
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
except Exception as e:
print("出错了:", e)
def main():
z = 1
for ck in startoken:
try:
print(f'登录第{z}个账号')
print('----------------------')
print('\n开始签到操作>>>>>>>>>>\n')
while True:
if sign(ck):
break
time.sleep(3)
print('\n完成日常任务>>>>>>>>>>\n')
this_week_id, this_month_id = find_task_ids(Get_list(ck))
print("本周充电任务:", Do_task(this_week_id,ck))
print("本月充电任务:", Do_task(this_month_id,ck))
print('\n获取用户信息>>>>>>>>>>\n')
Get_info(ck)
Get_user_info(ck)
print('\n----------------------')
z = z + 1
except Exception as e:
print(e)
if __name__ == '__main__':
try:
main()
except Exception as e:
print(e)
try:
send_notification_message(title='星星充电') # 发送通知
except Exception as e:
print(e)

View File

@@ -0,0 +1,389 @@
# Source: https://github.com/lksky8/sign-ql/blob/main/xxcd.py
# Raw: https://raw.githubusercontent.com/lksky8/sign-ql/main/xxcd.py
# Repo: lksky8/sign-ql
# Path: xxcd.py
# UploadedAt: 2026-05-23T06:33:21Z
# SHA256: 40e3aef421127efd0fe80201c786cf341993dd4e8318fe4f8456a912aef026e0
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
"""
星星充电签到
作者https://github.com/lksky8/sign-ql
日期2025-09-01
使用方法打开app随便抓一个包把头部'Authorization'内容填入 export startoken=""
另外可以再填入cityid(抓包获取), export starcityid=""可填可不填
支持多用户运行,多用户用&或者@隔开
export startoken="eyJ0eXAiOiJKV1QiLCJhbGciOiJIU1NiJ9..&eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1J9.."
export starcityid=""
每天运行一次即可
cron: 0 7 * * *
const $ = new Env("星星充电签到");
"""
import requests
import re
import os
import datetime
import hashlib
import time
if 'startoken' in os.environ:
startoken = re.split("@|&",os.environ.get("startoken"))
print(f'查找到{len(startoken)}个账号\n')
else:
startoken =['']
print('无startoken变量')
if 'starcityid' in os.environ:
cityid = os.environ.get("starcityid")
print(f'已填入cityid:{cityid}')
else:
cityid = '440000'
print('没有填写cityid,系统默认使用440000')
def md5_encrypt(text):
md5_hash = hashlib.md5()
md5_hash.update(text.encode('utf-8'))
md5_result = md5_hash.hexdigest()
return md5_result
def time13():
now = datetime.datetime.now()
timestamp_ms = int(now.timestamp() * 1000) + (now.microsecond // 1000)
return str(timestamp_ms)
def find_task_ids(data):
this_week_task_id = None
this_month_task_id = None
for model in data:
for task in model['taskList']:
if task['taskName'] == '本周充电任务':
this_week_task_id = task['taskId']
elif task['taskName'] == '本月充电任务':
this_month_task_id = task['taskId']
return this_week_task_id, this_month_task_id
send_msg = ''
one_msg = ''
def Log(cont=''):
global send_msg, one_msg
if cont:
one_msg += f'{cont}\n'
send_msg += f'{cont}\n'
# 发送通知消息
def send_notification_message(title):
try:
from notify import send
print("加载通知服务成功!")
send(title, send_msg)
except Exception as e:
if e:
print('发送通知消息失败!')
def sign(token):
try:
timestamp = time13()
signature = md5_encrypt(f'nonce=2b4aa7d9-4137-4e51-94e3-7b7355bf202a&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
'appVersion': '7.40.0',
'Origin': 'https://scm-app-h5.starcharge.com',
'signature': signature,
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Site': 'same-site',
'referrer': 'web',
'timestamp': timestamp,
'positCity': cityid,
'Authorization': token,
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'Accept': 'application/json, text/plain, */*',
'channel-id': '98',
'Sec-Fetch-Mode': 'cors',
'Content-Type': 'application/x-www-form-urlencoded',
}
data = {
'nonce': '2b4aa7d9-4137-4e51-94e3-7b7355bf202a',
'timestamp': timestamp,
'userId': '',
}
response = requests.post('https://gateway.starcharge.com/apph5/webApiV2/starPoint/sign',headers=headers, data=data)
response_json = response.json()
if response_json['code'] == '200':
print(f"签到成功:获得{response_json['data']['basePoint']}积分,已连续签到{response_json['data']['continuousDay']}")
Log(f"签到成功:获得{response_json['data']['basePoint']}积分,已连续签到{response_json['data']['continuousDay']}")
return True
elif response_json['code'] == '402':
print('用户数据获取失败,重新尝试获取数据')
return False
else:
print("签到失败:", response.text)
return False
except requests.exceptions.RequestException as e:
print("Failed to send POST request. Status Code:", response.status_code)
except Exception as e:
print("签到出错了:", e)
def Get_list(token):
try:
timestamp = time13()
signature = md5_encrypt(f'city={cityid}&nonce=1b93f289-32ee-4616-a860-5aef04c6c048&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'Accept': 'application/json, text/plain, */*',
'memberAdType': '0-0',
'Authorization': token,
'timestamp': timestamp,
'appVersion': '7.40.0',
'channel-id': '98',
'referrer': 'web',
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'signature': signature,
'positCity': cityid,
'Origin': 'https://scm-app-h5.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_8_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
}
response = requests.get(f'https://gateway.starcharge.com/apph5/webApiV2/userTask/model/list?city={cityid}&nonce=1b93f289-32ee-4616-a860-5aef04c6c048',headers=headers)
response_json = response.json()
if response_json['code'] == '200':
return response_json['data']
else:
print("获取任务列表失败:", response.text)
return False
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
except Exception as e:
print("获取任务列表出错了:", e)
def Do_task(task_id,token):
try:
timestamp = time13()
signature = md5_encrypt(f'nonce=4f63ecd8-e342-4e33-94a4-81bdfd040235&taskId={task_id}&taskType=1&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'Accept': 'application/json, text/plain, */*',
'memberAdType': '0-0',
'Authorization': token,
'timestamp': timestamp,
'appVersion': '7.40.0',
'channel-id': '98',
'referrer': 'web',
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'signature': signature,
'positCity': cityid,
'Origin': 'https://scm-app-h5.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_8_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
}
response = requests.get(f'https://gateway.starcharge.com/apph5/webApiV2/userTask/get?taskId={task_id}&taskType=1&nonce=4f63ecd8-e342-4e33-94a4-81bdfd040235', headers=headers)
response_json = response.json()
if response_json['code'] == None:
return response_json['text']
elif response_json['code'] == '200' and response_json['text'] == None :
return '任务已领取'
else:
print("做任务:", response.text)
return False
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
def Get_info(token):
try:
timestamp = time13()
signature = md5_encrypt(f'city={cityid}&nonce=b7e92ec1-813f-4ec2-ab8a-e91289604733&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
'appVersion': '7.40.0',
'Origin': 'https://scm-app-h5.starcharge.com',
'signature': signature,
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Site': 'same-site',
'referrer': 'web',
'timestamp': timestamp,
'positCity': cityid,
'Authorization': token,
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'Accept': 'application/json, text/plain, */*',
'channel-id': '98',
'Sec-Fetch-Mode': 'cors',
'Content-Type': 'application/x-www-form-urlencoded',
}
response = requests.get(f'https://gateway.starcharge.com/apph5/v2/webApiV2/star/point/user?city={cityid}&nonce=b7e92ec1-813f-4ec2-ab8a-e91289604733', headers=headers)
response_json = response.json()
if response_json['code'] == '200':
print(f'用户({response_json["data"]["nickName"]})目前金币:{response_json["data"]["points"]}')
Log(f'用户({response_json["data"]["nickName"]})目前金币:{response_json["data"]["points"]}\n')
else:
print('用户数据查询失败:' + response.text)
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
except Exception as e:
print("查询用户数据出错了:", e)
def Get_user_info(token):
try:
timestamp = time13()
signature = md5_encrypt(f'cityCode={cityid}&nonce=b6efee74-2ad5-43b3-bf3f-2435613c7c9d&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'Accept': 'application/json, text/plain, */*',
'Authorization': token,
'timestamp': timestamp,
'Sec-Fetch-Site': 'same-site',
'appVersion': '7.40.0',
'channel-id': '98',
'referrer': 'web',
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'signature': signature,
'Sec-Fetch-Mode': 'cors',
'Origin': 'https://scm-app-h5.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
'positCity': cityid,
'Sec-Fetch-Dest': 'empty',
}
response = requests.get(f'https://gateway.starcharge.com/apph5/webApiV2/user/getUserBaseInfo?cityCode={cityid}&nonce=b6efee74-2ad5-43b3-bf3f-2435613c7c9d', headers=headers)
response_data = response.json()
if response_data['code'] == '200':
if response_data['data']['appVipType'] == 1:
print(f'用户({response_data["data"]["nickName"]})已开通VIP到期日{response_data["data"]["appVipExpiration"]}')
vip_sign(token)
check_vip_sign(token)
else:
print(f'用户({response_data["data"]["nickName"]}) 未开通VIP')
else:
print('查询是否VIP失败:' + response.text)
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
except Exception as e:
print("查询是否VIP出错了:", e)
def vip_sign(token):
try:
timestamp = time13()
signature = md5_encrypt('nonce=8f396424-3729-4f50-bf67-bfb8fe38b9c5&timestamp='+timestamp+'&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://scm-app-h5.starcharge.com/',
'appVersion': '7.40.0',
'Origin': 'https://scm-app-h5.starcharge.com',
'signature': signature,
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Site': 'same-site',
'referrer': 'web',
'timestamp': timestamp,
'positCity': '440600',
'Authorization': token,
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'Accept': 'application/json, text/plain, */*',
'channel-id': '98',
'Sec-Fetch-Mode': 'cors',
'Content-Type': 'application/x-www-form-urlencoded',
}
data = {
'nonce': '8f396424-3729-4f50-bf67-bfb8fe38b9c5',
'timestamp': timestamp,
'userId': '',
}
response = requests.post('https://gateway.starcharge.com/apph5/webApiV2/member/v5/home/sign',headers=headers, data=data).json()
if response['code'] == '200':
print(f"VIP任务签到成功")
else:
print("VIP任务签到失败" + response['text'])
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
except Exception as e:
print("出错了:", e)
def check_vip_sign(token):
try:
timestamp = time13()
signature = md5_encrypt(f'cycleType=1&nonce=2d3d2147-dbce-42b4-8fa9-9268b4fa580f&timestamp={timestamp}&userId=')[0:18].upper()
headers = {
'Host': 'gateway.starcharge.com',
'memberAdType': '0-0',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148',
'Referer': 'https://app-taro.starcharge.com/',
'appVersion': '7.40.0',
'Origin': 'https://app-taro.starcharge.com',
'signature': signature,
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Site': 'same-site',
'referrer': 'web',
'timestamp': timestamp,
'positCity': '440600',
'Authorization': token,
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
'Accept': '*/*',
'Content-Type': 'application/x-www-form-urlencoded',
'channel-id': '98',
'Sec-Fetch-Mode': 'cors',
}
response = requests.get(f'https://gateway.starcharge.com/apph5/webApiV2/member/v5/home/sign/records?cycleType=1&nonce=2d3d2147-dbce-42b4-8fa9-9268b4fa580f&timestamp={timestamp}&userId=',headers=headers).json()
if response['code'] == '200':
print(f"VIP任务已连续签到{response['data']['continuousDays']}")
else:
print("VIP任务查询失败" + response)
except requests.exceptions.RequestException as e:
print("An error occurred:", e)
except Exception as e:
print("出错了:", e)
def main():
z = 1
for ck in startoken:
try:
print(f'登录第{z}个账号')
print('----------------------')
print('\n开始签到操作>>>>>>>>>>\n')
while True:
if sign(ck):
break
time.sleep(3)
print('\n完成日常任务>>>>>>>>>>\n')
this_week_id, this_month_id = find_task_ids(Get_list(ck))
print("本周充电任务:", Do_task(this_week_id,ck))
print("本月充电任务:", Do_task(this_month_id,ck))
print('\n获取用户信息>>>>>>>>>>\n')
Get_info(ck)
Get_user_info(ck)
print('\n----------------------')
z = z + 1
except Exception as e:
print(e)
if __name__ == '__main__':
try:
main()
except Exception as e:
print(e)
try:
send_notification_message(title='星星充电') # 发送通知
except Exception as e:
print(e)