mirror of
https://github.com/wq-h/qinglong.git
synced 2025-12-18 15:55:03 +08:00
优化脚本
This commit is contained in:
38
Ruishu.py
38
Ruishu.py
@@ -14,6 +14,7 @@ from Crypto.Cipher import DES3
|
|||||||
from Crypto.Util.Padding import pad, unpad
|
from Crypto.Util.Padding import pad, unpad
|
||||||
from aiohttp import ClientSession, TCPConnector
|
from aiohttp import ClientSession, TCPConnector
|
||||||
import httpx
|
import httpx
|
||||||
|
import logging
|
||||||
|
|
||||||
diffValue = 2
|
diffValue = 2
|
||||||
filename='Cache.js'
|
filename='Cache.js'
|
||||||
@@ -77,35 +78,50 @@ custom_client = httpx.Client(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 添加日志记录
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||||
|
)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def initCookie(getUrl='https://wapact.189.cn:9001/gateway/standQuery/detailNew/exchange'):
|
def initCookie(getUrl='https://wapact.189.cn:9001/gateway/standQuery/detailNew/exchange'):
|
||||||
|
try:
|
||||||
global js_code_ym, fileContent
|
global js_code_ym, fileContent
|
||||||
cookie = ''
|
|
||||||
response = custom_client.post(getUrl)
|
response = custom_client.post(getUrl)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
# 解析响应内容
|
||||||
content = response.text.split(' content="')[2].split('" r=')[0]
|
content = response.text.split(' content="')[2].split('" r=')[0]
|
||||||
code1 = response.text.split('$_ts=window')[1].split('</script><script type="text/javascript"')[0]
|
code1 = response.text.split('$_ts=window')[1].split('</script><script type="text/javascript"')[0]
|
||||||
code1Content = '$_ts=window' + code1
|
code1Content = '$_ts=window' + code1
|
||||||
Url = response.text.split('$_ts.lcd();</script><script type="text/javascript" charset="utf-8" src="')[1].split('" r=')[0]
|
Url = response.text.split('$_ts.lcd();</script><script type="text/javascript" charset="utf-8" src="')[1].split('" r=')[0]
|
||||||
urls = getUrl.split('/')
|
|
||||||
rsurl = urls[0] + '//' + urls[2] + Url
|
# 处理文件缓存
|
||||||
filename = 'Cache.js'
|
if not fileContent:
|
||||||
if fileContent == '':
|
fileRes = custom_client.get(Url)
|
||||||
if not os.path.exists(filename):
|
|
||||||
fileRes = custom_client.get(rsurl)
|
|
||||||
fileContent = fileRes.text
|
|
||||||
if fileRes.status_code == 200:
|
if fileRes.status_code == 200:
|
||||||
|
fileContent = fileRes.text
|
||||||
with open(filename, 'w', encoding='utf-8') as file:
|
with open(filename, 'w', encoding='utf-8') as file:
|
||||||
file.write(fileRes.text)
|
file.write(fileRes.text)
|
||||||
else:
|
else:
|
||||||
print(f"Failed to download {rsurl}. Status code: {fileRes.status_code}")
|
logger.error(f"Failed to download {Url}. Status code: {fileRes.status_code}")
|
||||||
if response.headers['Set-Cookie']:
|
return None
|
||||||
cookie = response.headers['Set-Cookie'].split(';')[0].split('=')[1]
|
|
||||||
|
# 处理cookies
|
||||||
|
cookie = response.headers.get('Set-Cookie', '').split(';')[0].split('=')[1]
|
||||||
runJs = js_code_ym.replace('content_code', content).replace("'ts_code'", code1Content + fileContent)
|
runJs = js_code_ym.replace('content_code', content).replace("'ts_code'", code1Content + fileContent)
|
||||||
execjsRun = RefererCookie(runJs)
|
execjsRun = RefererCookie(runJs)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'cookie': cookie,
|
'cookie': cookie,
|
||||||
'execjsRun': execjsRun
|
'execjsRun': execjsRun
|
||||||
}
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"初始化cookies失败: {str(e)}")
|
||||||
|
return None
|
||||||
|
|
||||||
def RefererCookie(runJs):
|
def RefererCookie(runJs):
|
||||||
try:
|
try:
|
||||||
execjsRun = execjs.compile(runJs)
|
execjsRun = execjs.compile(runJs)
|
||||||
|
|||||||
114
chinatelecom.py
114
chinatelecom.py
@@ -2,14 +2,14 @@
|
|||||||
新电信抢话费
|
新电信抢话费
|
||||||
|
|
||||||
群里发的,未测试好,自测
|
群里发的,未测试好,自测
|
||||||
修改内容如下“
|
修改内容如下"
|
||||||
1.删除内置的一个手机账号
|
1.删除内置的一个手机账号
|
||||||
2.修改环境变量名保持和拉菲电信金豆本环境变量一致
|
2.修改环境变量名保持和拉菲电信金豆本环境变量一致
|
||||||
3.恢复瑞数通杀.js调用地址,确实也不知道是啥。398、399行注释
|
3.恢复瑞数通杀.js调用地址,确实也不知道是啥。398、399行注释
|
||||||
|
|
||||||
环境变量chinaTelecomAccount,值为:账号#密码
|
环境变量chinaTelecomAccount,值为:账号#密码
|
||||||
|
|
||||||
cron: 57 9,13,23 * * *
|
cron: 56 59 09,13 * * *
|
||||||
const $ = new Env("新电信抢话费");
|
const $ = new Env("新电信抢话费");
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -40,11 +40,27 @@ from Crypto.Util.Padding import pad, unpad
|
|||||||
from aiohttp import ClientSession, TCPConnector
|
from aiohttp import ClientSession, TCPConnector
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||||
|
handlers=[
|
||||||
|
logging.FileHandler('chinatelecom.log'),
|
||||||
|
logging.StreamHandler()
|
||||||
|
]
|
||||||
|
)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
run_num=os.environ.get('reqNUM') or "2"
|
run_num=os.environ.get('reqNUM') or "2"
|
||||||
|
|
||||||
MAX_RETRIES = 3
|
# 添加配置类
|
||||||
RATE_LIMIT = 10 # 每秒请求数限制
|
class Config:
|
||||||
|
MAX_RETRIES = 3
|
||||||
|
RATE_LIMIT = 10
|
||||||
|
REQUEST_TIMEOUT = 30
|
||||||
|
BASE_URL = "https://wapact.189.cn:9001"
|
||||||
|
USER_AGENT = "Mozilla/5.0 (Linux; Android 13; 22081212C Build/TKQ1.220829.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36"
|
||||||
|
|
||||||
class RateLimiter:
|
class RateLimiter:
|
||||||
def __init__(self, rate_limit):
|
def __init__(self, rate_limit):
|
||||||
@@ -427,27 +443,89 @@ async def qgNight(phone, ticket, timeDiff,isTrue):
|
|||||||
async def qgDay(phone, ticket, timeDiff, isTrue):
|
async def qgDay(phone, ticket, timeDiff, isTrue):
|
||||||
async with AsyncSessionManager() as s:
|
async with AsyncSessionManager() as s:
|
||||||
pass
|
pass
|
||||||
async def main(timeDiff,isTRUE,hour):
|
|
||||||
tasks = []
|
# 修改 RequestUtil 类
|
||||||
PHONES=os.environ.get('chinaTelecomAccount')
|
class RequestUtil:
|
||||||
|
def __init__(self):
|
||||||
|
# 在创建 ClientSession 时通过 headers 参数设置请求头
|
||||||
|
self.session = aiohttp.ClientSession(headers={"User-Agent": Config.USER_AGENT})
|
||||||
|
self.rate_limiter = RateLimiter(Config.RATE_LIMIT)
|
||||||
|
|
||||||
|
async def safe_request(self, method, url, **kwargs):
|
||||||
|
for attempt in range(Config.MAX_RETRIES):
|
||||||
|
try:
|
||||||
|
await self.rate_limiter.acquire()
|
||||||
|
async with self.session.request(method, url, timeout=Config.REQUEST_TIMEOUT, **kwargs) as response:
|
||||||
|
response.raise_for_status()
|
||||||
|
return await response.json()
|
||||||
|
except Exception as e:
|
||||||
|
if attempt == Config.MAX_RETRIES - 1:
|
||||||
|
raise
|
||||||
|
await asyncio.sleep(2 ** attempt)
|
||||||
|
|
||||||
|
async def close(self):
|
||||||
|
if self.session and not self.session.closed:
|
||||||
|
await self.session.close()
|
||||||
|
|
||||||
|
# 修改 main 函数,增加日志记录
|
||||||
|
async def main(timeDiff, isTRUE, hour):
|
||||||
|
config = Config()
|
||||||
|
request_util = RequestUtil()
|
||||||
|
|
||||||
|
try:
|
||||||
|
PHONES = os.environ.get('chinaTelecomAccount')
|
||||||
|
if not PHONES:
|
||||||
|
logger.error("未找到环境变量 chinaTelecomAccount")
|
||||||
|
raise ValueError("未找到环境变量 chinaTelecomAccount")
|
||||||
|
|
||||||
phone_list = PHONES.split('\n')
|
phone_list = PHONES.split('\n')
|
||||||
|
tasks = []
|
||||||
|
logger.info(f"开始处理 {len(phone_list)} 个账号")
|
||||||
|
|
||||||
for phoneV in phone_list:
|
for phoneV in phone_list:
|
||||||
|
try:
|
||||||
value = phoneV.split('#')
|
value = phoneV.split('#')
|
||||||
|
if len(value) != 2:
|
||||||
|
logger.warning(f"账号格式错误: {phoneV}")
|
||||||
|
continue
|
||||||
|
|
||||||
phone, password = value[0], value[1]
|
phone, password = value[0], value[1]
|
||||||
printn(f'{get_first_three(phone)}开始登录')
|
logger.info(f'{get_first_three(phone)} 开始登录')
|
||||||
ticket = userLoginNormal(phone,password)
|
|
||||||
if ticket:
|
ticket = userLoginNormal(phone, password)
|
||||||
# hour=datetime.datetime.now().hour
|
if not ticket:
|
||||||
# hour=23
|
logger.error(f'{get_first_three(phone)} 登录失败')
|
||||||
|
continue
|
||||||
|
|
||||||
|
logger.info(f'{get_first_three(phone)} 登录成功')
|
||||||
|
|
||||||
if hour > 15:
|
if hour > 15:
|
||||||
|
logger.info(f'{get_first_three(phone)} 加入夜间任务队列')
|
||||||
tasks.append(qgNight(phone, ticket, timeDiff, isTRUE))
|
tasks.append(qgNight(phone, ticket, timeDiff, isTRUE))
|
||||||
# await asyncio.sleep(0.1)
|
|
||||||
else:#十点//十四点场次
|
|
||||||
tasks.append(qgDay(phone, ticket, timeDiff, isTRUE))
|
|
||||||
# await asyncio.sleep(0.1)
|
|
||||||
else:
|
else:
|
||||||
printn(f'{phone} 登录失败')
|
logger.info(f'{get_first_three(phone)} 加入日间任务队列')
|
||||||
await asyncio.gather(*tasks)
|
tasks.append(qgDay(phone, ticket, timeDiff, isTRUE))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f'{get_first_three(phone)} 处理失败: {str(e)}')
|
||||||
|
continue
|
||||||
|
|
||||||
|
logger.info(f"开始执行 {len(tasks)} 个任务")
|
||||||
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
||||||
|
|
||||||
|
# 记录任务执行结果
|
||||||
|
for i, result in enumerate(results, start=1): # 从1开始计数
|
||||||
|
if isinstance(result, Exception):
|
||||||
|
logger.error(f"任务 {i} 执行失败: {str(result)}")
|
||||||
|
else:
|
||||||
|
logger.info(f"任务 {i} 执行成功")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f'主程序运行失败: {str(e)}', exc_info=True)
|
||||||
|
finally:
|
||||||
|
logger.info("正在关闭请求会话")
|
||||||
|
await request_util.close()
|
||||||
|
logger.info("程序执行完毕")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
h = datetime.datetime.now().hour
|
h = datetime.datetime.now().hour
|
||||||
|
|||||||
@@ -8,17 +8,43 @@ export Ikuuu_HOST="ikuuu.one"
|
|||||||
cron: 33 08 * * *
|
cron: 33 08 * * *
|
||||||
const $ = new Env("ikuuu 机场签到");
|
const $ = new Env("ikuuu 机场签到");
|
||||||
*/
|
*/
|
||||||
const { sendNotify } = require("./sendNotify"); // 引入 sendNotify.js 模块
|
const { sendNotify } = require("./sendNotify");
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
const host = process.env.Ikuuu_HOST || "ikuuu.one";
|
// 配置类
|
||||||
|
class Config {
|
||||||
|
static get HOST() {
|
||||||
|
return process.env.Ikuuu_HOST || "ikuuu.one";
|
||||||
|
}
|
||||||
|
|
||||||
const protocolPrefix = "https://";
|
static get PROTOCOL_PREFIX() {
|
||||||
const logInUrl = `${protocolPrefix}${host}/auth/login`;
|
return "https://";
|
||||||
const checkInUrl = `${protocolPrefix}${host}/user/checkin`;
|
}
|
||||||
|
|
||||||
function parseCookie(rawCookie) {
|
static get LOGIN_URL() {
|
||||||
|
return `${Config.PROTOCOL_PREFIX}${Config.HOST}/auth/login`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get CHECKIN_URL() {
|
||||||
|
return `${Config.PROTOCOL_PREFIX}${Config.HOST}/user/checkin`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日志配置
|
||||||
|
const logStream = fs.createWriteStream(path.join(__dirname, 'ikuuu.log'), { flags: 'a' });
|
||||||
|
|
||||||
|
function log(level, message) {
|
||||||
|
const timestamp = new Date().toISOString();
|
||||||
|
const logMessage = `[${timestamp}] [${level}] ${message}\n`;
|
||||||
|
logStream.write(logMessage);
|
||||||
|
console.log(logMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cookie 工具类
|
||||||
|
class CookieUtil {
|
||||||
|
static parseCookie(rawCookie) {
|
||||||
let cookieSets = rawCookie.split("path=/,");
|
let cookieSets = rawCookie.split("path=/,");
|
||||||
|
|
||||||
const cookies = {};
|
const cookies = {};
|
||||||
|
|
||||||
cookieSets.forEach((cookie) => {
|
cookieSets.forEach((cookie) => {
|
||||||
@@ -26,7 +52,6 @@ function parseCookie(rawCookie) {
|
|||||||
if (match) {
|
if (match) {
|
||||||
const fieldName = match[1].trim();
|
const fieldName = match[1].trim();
|
||||||
let fieldValue = match[2].trim();
|
let fieldValue = match[2].trim();
|
||||||
|
|
||||||
fieldValue = decodeURIComponent(fieldValue);
|
fieldValue = decodeURIComponent(fieldValue);
|
||||||
|
|
||||||
if (!cookies[fieldName]) {
|
if (!cookies[fieldName]) {
|
||||||
@@ -36,53 +61,70 @@ function parseCookie(rawCookie) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return cookies;
|
return cookies;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateCookieStr(cookieObject) {
|
static generateCookieStr(cookieObject) {
|
||||||
return Object.entries(cookieObject)
|
return Object.entries(cookieObject)
|
||||||
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
||||||
.join("; ");
|
.join("; ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function logIn(email, passwd) {
|
// Ikuuu 客户端类
|
||||||
console.log(`Logging in with email: ${email}...`);
|
class IkuuuClient {
|
||||||
|
constructor(email, password) {
|
||||||
|
this.email = email;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
async login() {
|
||||||
|
log('INFO', `Logging in with email: ${this.email}...`);
|
||||||
|
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
formData.append("host", host);
|
formData.append("host", Config.HOST);
|
||||||
formData.append("email", email);
|
formData.append("email", this.email);
|
||||||
formData.append("passwd", passwd);
|
formData.append("passwd", this.password);
|
||||||
formData.append("code", "");
|
formData.append("code", "");
|
||||||
formData.append("remember_me", "off");
|
formData.append("remember_me", "off");
|
||||||
|
|
||||||
let response = await fetch(logInUrl, {
|
try {
|
||||||
|
let response = await fetch(Config.LOGIN_URL, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData,
|
body: formData,
|
||||||
});
|
});
|
||||||
|
|
||||||
let rawCookie = response.headers.get("set-cookie");
|
let rawCookie = response.headers.get("set-cookie");
|
||||||
|
|
||||||
let responseJson = await response.json();
|
let responseJson = await response.json();
|
||||||
|
|
||||||
if (responseJson) {
|
if (responseJson) {
|
||||||
console.log(responseJson.msg);
|
log('INFO', responseJson.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseCookie(rawCookie);
|
return CookieUtil.parseCookie(rawCookie);
|
||||||
}
|
} catch (error) {
|
||||||
|
log('ERROR', `Login failed for ${this.email}: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function checkIn(cookie) {
|
async checkIn(cookie) {
|
||||||
return fetch(checkInUrl, {
|
try {
|
||||||
|
let response = await fetch(Config.CHECKIN_URL, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
Cookie: generateCookieStr(cookie),
|
Cookie: CookieUtil.generateCookieStr(cookie),
|
||||||
},
|
},
|
||||||
})
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((resJson) => {
|
|
||||||
if (resJson) {
|
|
||||||
console.log(resJson.msg);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let responseJson = await response.json();
|
||||||
|
if (responseJson) {
|
||||||
|
log('INFO', responseJson.msg);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log('ERROR', `Check-in failed for ${this.email}: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 延迟函数,单位为毫秒
|
// 延迟函数,单位为毫秒
|
||||||
@@ -95,7 +137,7 @@ async function main() {
|
|||||||
let passwords = process.env.Ikuuu_PASSWD;
|
let passwords = process.env.Ikuuu_PASSWD;
|
||||||
|
|
||||||
if (!emails || !passwords) {
|
if (!emails || !passwords) {
|
||||||
console.log("ENV ERROR: Please set both Ikuuu_EMAIL and Ikuuu_PASSWD.");
|
log('ERROR', "ENV ERROR: Please set both Ikuuu_EMAIL and Ikuuu_PASSWD.");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,32 +145,40 @@ async function main() {
|
|||||||
let passwdList = passwords.split(";");
|
let passwdList = passwords.split(";");
|
||||||
|
|
||||||
if (emailList.length !== passwdList.length) {
|
if (emailList.length !== passwdList.length) {
|
||||||
console.log("Error: The number of emails does not match the number of passwords.");
|
log('ERROR', "Error: The number of emails does not match the number of passwords.");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建一个通知数组,避免多次发送相同的消息
|
|
||||||
let notifications = [];
|
let notifications = [];
|
||||||
|
|
||||||
// 遍历每个账号执行登录并签到
|
|
||||||
for (let i = 0; i < emailList.length; i++) {
|
for (let i = 0; i < emailList.length; i++) {
|
||||||
let email = emailList[i];
|
let email = emailList[i];
|
||||||
let passwd = passwdList[i];
|
let passwd = passwdList[i];
|
||||||
let cookie = await logIn(email, passwd);
|
let client = new IkuuuClient(email, passwd);
|
||||||
await checkIn(cookie);
|
|
||||||
|
|
||||||
// 每个账号的操作只添加一条通知
|
try {
|
||||||
|
let cookie = await client.login();
|
||||||
|
await client.checkIn(cookie);
|
||||||
notifications.push(`账号 ${email} 登录成功,签到完成`);
|
notifications.push(`账号 ${email} 登录成功,签到完成`);
|
||||||
|
} catch (error) {
|
||||||
|
notifications.push(`账号 ${email} 操作失败: ${error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
// 每次登录后延迟 2 秒
|
|
||||||
await delay(2000); // 延迟 2 秒
|
await delay(2000); // 延迟 2 秒
|
||||||
}
|
}
|
||||||
|
|
||||||
// 合并所有通知为一条消息,避免多次发送
|
// 过滤掉 undefined 值
|
||||||
const notificationMessage = notifications.join("\n");
|
const notificationMessage = notifications
|
||||||
|
.filter(msg => msg !== undefined)
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
|
// 调试:打印通知数组
|
||||||
|
console.log("通知数组内容:", notifications);
|
||||||
|
|
||||||
// 发送合并后的消息通知
|
|
||||||
sendNotify(`多个账号操作完成:\n${notificationMessage}`);
|
sendNotify(`多个账号操作完成:\n${notificationMessage}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main().catch(error => {
|
||||||
|
log('ERROR', `Main function failed: ${error.message}`);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|||||||
44
tieba.py
44
tieba.py
@@ -7,6 +7,7 @@ import os
|
|||||||
import time
|
import time
|
||||||
from requests import session
|
from requests import session
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from sendNotify import send
|
from sendNotify import send
|
||||||
@@ -14,6 +15,11 @@ except ImportError:
|
|||||||
print("加载通知服务失败")
|
print("加载通知服务失败")
|
||||||
|
|
||||||
class Tieba():
|
class Tieba():
|
||||||
|
# 将配置项提取为类变量
|
||||||
|
MAX_RETRY = 10 # 最大重试次数
|
||||||
|
REQUEST_TIMEOUT = 30 # 请求超时时间
|
||||||
|
SLEEP_TIME = 10 # 退出前等待时间
|
||||||
|
|
||||||
Tieba_BDUSS = os.getenv("Tieba_BDUSS")
|
Tieba_BDUSS = os.getenv("Tieba_BDUSS")
|
||||||
|
|
||||||
def __init__(self, STOKEN):
|
def __init__(self, STOKEN):
|
||||||
@@ -40,13 +46,17 @@ class Tieba():
|
|||||||
self.session.cookies.update({'BDUSS': self.BDUSS, 'STOKEN': self.STOKEN})
|
self.session.cookies.update({'BDUSS': self.BDUSS, 'STOKEN': self.STOKEN})
|
||||||
|
|
||||||
def fetch_tbs(self):
|
def fetch_tbs(self):
|
||||||
|
try:
|
||||||
r = self.session.get('http://tieba.baidu.com/dc/common/tbs').json()
|
r = self.session.get('http://tieba.baidu.com/dc/common/tbs').json()
|
||||||
if r['is_login'] == 1:
|
if r['is_login'] == 1:
|
||||||
self.tbs = r['tbs']
|
self.tbs = r['tbs']
|
||||||
else:
|
else:
|
||||||
raise Exception('获取tbs错误!以下为返回数据:' + str(r))
|
raise Exception('获取tbs错误!以下为返回数据:' + str(r))
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f'获取tbs时发生异常:{str(e)}')
|
||||||
|
|
||||||
def fetch_likes(self):
|
def fetch_likes(self):
|
||||||
|
try:
|
||||||
self.rest = set()
|
self.rest = set()
|
||||||
self.already = set()
|
self.already = set()
|
||||||
r = self.session.get('https://tieba.baidu.com/mo/q/newmoindex?').json()
|
r = self.session.get('https://tieba.baidu.com/mo/q/newmoindex?').json()
|
||||||
@@ -58,14 +68,17 @@ class Tieba():
|
|||||||
self.rest.add(forum['forum_name'])
|
self.rest.add(forum['forum_name'])
|
||||||
else:
|
else:
|
||||||
raise Exception('获取关注贴吧错误!以下为返回数据:' + str(r))
|
raise Exception('获取关注贴吧错误!以下为返回数据:' + str(r))
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f'获取关注贴吧时发生异常:{str(e)}')
|
||||||
|
|
||||||
def sign(self, forum_name):
|
def sign(self, forum_name):
|
||||||
|
try:
|
||||||
data = {
|
data = {
|
||||||
'kw': forum_name,
|
'kw': forum_name,
|
||||||
'tbs': self.tbs,
|
'tbs': self.tbs,
|
||||||
'sign': md5(f'kw={forum_name}tbs={self.tbs}tiebaclient!!!'.encode('utf8')).hexdigest()
|
'sign': md5(f'kw={forum_name}tbs={self.tbs}tiebaclient!!!'.encode('utf8')).hexdigest()
|
||||||
}
|
}
|
||||||
r = self.session.post('http://c.tieba.baidu.com/c/c/forum/sign', data).json()
|
r = self.session.post('http://c.tieba.baidu.com/c/c/forum/sign', data, timeout=self.REQUEST_TIMEOUT).json()
|
||||||
if r['error_code'] == '160002':
|
if r['error_code'] == '160002':
|
||||||
print(f'"{forum_name}"已签到')
|
print(f'"{forum_name}"已签到')
|
||||||
self.sign_list.append(forum_name)
|
self.sign_list.append(forum_name)
|
||||||
@@ -79,17 +92,28 @@ class Tieba():
|
|||||||
print(f'"{forum_name}"签到失败!以下为返回数据:{str(r)}')
|
print(f'"{forum_name}"签到失败!以下为返回数据:{str(r)}')
|
||||||
self.fail_list.append(forum_name)
|
self.fail_list.append(forum_name)
|
||||||
return False
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f'"{forum_name}"签到时发生异常:{str(e)}')
|
||||||
|
self.fail_list.append(forum_name)
|
||||||
|
return False
|
||||||
|
|
||||||
def loop(self, n):
|
def loop(self, n):
|
||||||
print(f'* 开始第{n}轮签到 *')
|
print(f'* 开始第{n}轮签到 *')
|
||||||
rest = set()
|
rest = set()
|
||||||
self.fetch_tbs()
|
self.fetch_tbs()
|
||||||
for forum_name in self.rest:
|
# 使用线程池并发签到
|
||||||
flag = self.sign(forum_name)
|
with ThreadPoolExecutor(max_workers=5) as executor:
|
||||||
if not flag:
|
futures = {executor.submit(self.sign, forum_name): forum_name for forum_name in self.rest}
|
||||||
|
for future in as_completed(futures):
|
||||||
|
forum_name = futures[future]
|
||||||
|
try:
|
||||||
|
if not future.result():
|
||||||
|
rest.add(forum_name)
|
||||||
|
except Exception as e:
|
||||||
|
print(f'"{forum_name}"签到异常:{str(e)}')
|
||||||
rest.add(forum_name)
|
rest.add(forum_name)
|
||||||
self.rest = rest
|
self.rest = rest
|
||||||
if n >= 10: # 最大重试次数
|
if n >= self.MAX_RETRY: # 使用类变量
|
||||||
self.rest = set()
|
self.rest = set()
|
||||||
|
|
||||||
def main(self, max):
|
def main(self, max):
|
||||||
@@ -114,6 +138,7 @@ class Tieba():
|
|||||||
self.send_notification_message()
|
self.send_notification_message()
|
||||||
|
|
||||||
def send_notification_message(self):
|
def send_notification_message(self):
|
||||||
|
try:
|
||||||
msg = "贴吧签到结果:\n"
|
msg = "贴吧签到结果:\n"
|
||||||
|
|
||||||
if self.success_list:
|
if self.success_list:
|
||||||
@@ -124,8 +149,9 @@ class Tieba():
|
|||||||
|
|
||||||
if self.sign_list:
|
if self.sign_list:
|
||||||
msg += "- **已经签到的贴吧**:\n"
|
msg += "- **已经签到的贴吧**:\n"
|
||||||
msg += " " + "\n ".join(self.sign_list) + "\n"
|
msg += " " + ", ".join(self.sign_list) # 去掉末尾的换行符
|
||||||
|
|
||||||
|
# 直接拼接统计信息,去掉前面的空行
|
||||||
msg += f"\n共关注了{len(self.already) + len(self.success_list)}个贴吧,"
|
msg += f"\n共关注了{len(self.already) + len(self.success_list)}个贴吧,"
|
||||||
msg += f"本次成功签到了{len(self.success_list)}个,"
|
msg += f"本次成功签到了{len(self.success_list)}个,"
|
||||||
msg += f"失败了{len(self.fail_list)}个,"
|
msg += f"失败了{len(self.fail_list)}个,"
|
||||||
@@ -134,8 +160,10 @@ class Tieba():
|
|||||||
# 发送通知
|
# 发送通知
|
||||||
send('Tieba_Sign', msg)
|
send('Tieba_Sign', msg)
|
||||||
|
|
||||||
# Add a 10-second delay before exiting
|
# 使用类变量
|
||||||
time.sleep(10)
|
time.sleep(self.SLEEP_TIME)
|
||||||
|
except Exception as e:
|
||||||
|
print(f'发送通知时发生异常:{str(e)}')
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
BDUSS_values = os.getenv("Tieba_BDUSS")
|
BDUSS_values = os.getenv("Tieba_BDUSS")
|
||||||
|
|||||||
Reference in New Issue
Block a user