Collect authenticated Qinglong scripts batch

This commit is contained in:
Hermes Agent
2026-05-24 03:53:42 +00:00
parent 0d80b33d25
commit 28d62fef03
86 changed files with 18420 additions and 5 deletions

View File

@@ -0,0 +1,333 @@
# Source: https://github.com/CN-Grace/QinglongScripts/blob/main/Tieba.py
# Raw: https://raw.githubusercontent.com/CN-Grace/QinglongScripts/main/Tieba.py
# Repo: CN-Grace/QinglongScripts
# Path: Tieba.py
# UploadedAt: 2026-05-23T15:48:24Z
# SHA256: 9b1ac22330324c1b5579826fd6202a49e6e4aa857d1819be3cd7073dd7c092c2
# Category: web版/账密
# Evidence: web/H5关键词 + username/password/login
#!/usr/bin/env python3
"""
cron: 0 0 * * *
new Env("百度贴吧签到")
百度贴吧 每日自动签到脚本
- 获取用户登录状态
- 获取关注的贴吧列表(含等级、经验值)
- 对每个贴吧进行签到
- 统计签到结果和等级分布
"""
import hashlib
import os
import random
import time
import requests
from typing import Optional, List, Dict, Any
from utils import log_info, log_success, log_warning, log_error, beijing_time_str
from notifier import send as notify_send
# ==================== 用户配置 ====================
TIEBA_COOKIE = os.environ.get("TIEBA_COOKIE", "")
def create_session(cookie: str) -> requests.Session:
"""创建带 Cookie 的 requests.Session贴吧专用 User-Agent 和 Host"""
session = requests.Session()
session.headers.update({
"Host": "tieba.baidu.com",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36",
"Connection": "keep-alive",
"Accept-Encoding": "gzip, deflate",
"Cache-Control": "no-cache",
})
cookie_dict = {item.split("=")[0]: item.split("=")[1] for item in cookie.split("; ") if "=" in item}
requests.utils.add_dict_to_cookiejar(session.cookies, cookie_dict)
return session
def encode_data(data: Dict, sign_key: str = "tiebaclient!!!") -> Dict:
"""对请求数据进行签名"""
s = ""
for key in sorted(data.keys()):
s += f"{key}={data[key]}"
sign = hashlib.md5((s + sign_key).encode("utf-8")).hexdigest().upper()
data.update({"sign": sign})
return data
def request(session: requests.Session, url: str, method: str = "get", data: Optional[Dict] = None, retry: int = 3) -> Dict:
"""带重试的请求函数"""
for i in range(retry):
try:
if method.lower() == "get":
response = session.get(url, timeout=10)
else:
response = session.post(url, data=data, timeout=10)
response.raise_for_status()
if not response.text.strip():
raise ValueError("空响应内容")
return response.json()
except Exception as e:
if i == retry - 1:
raise Exception(f"请求失败: {e!s}")
wait_time = 1.5 * (2 ** i) + random.uniform(0, 1)
time.sleep(wait_time)
raise Exception(f"请求失败,已达最大重试次数 {retry}")
# ---------- 核心功能 ----------
def get_user_info(session: requests.Session) -> tuple:
"""获取用户登录信息,返回 (tbs, user_name) 或 (False, 错误信息)"""
try:
result = request(session, "http://tieba.baidu.com/dc/common/tbs")
if result.get("is_login", 0) == 0:
return False, "登录失败Cookie 异常"
tbs = result.get("tbs", "")
try:
user_info = request(session, "https://tieba.baidu.com/f/user/json_userinfo")
user_data = user_info.get("data", "")
user_name = user_data.get("show_nickname", "未知用户") if isinstance(user_data, dict) else "未知用户"
except Exception:
user_name = "未知用户"
return tbs, user_name
except Exception as e:
return False, f"登录验证异常: {e}"
def get_favorite(session: requests.Session, bduss: str) -> List[Dict]:
"""获取用户关注的贴吧列表,包含等级信息"""
forums = []
page_no = 1
like_url = "http://c.tieba.baidu.com/c/f/forum/like"
while True:
data = encode_data({
"BDUSS": bduss,
"_client_type": "2",
"_client_id": "wappc_1534235498291_488",
"_client_version": "9.7.8.0",
"_phone_imei": "000000000000000",
"from": "1008621y",
"page_no": str(page_no),
"page_size": "200",
"model": "MI+5",
"net_type": "1",
"timestamp": str(int(time.time())),
"vcode_tag": "11",
})
try:
res = request(session, like_url, "post", data)
if "forum_list" in res:
for forum_type in ["non-gconforum", "gconforum"]:
if forum_type in res["forum_list"]:
items = res["forum_list"][forum_type]
if isinstance(items, list):
for f in items:
f["_is_signed"] = (forum_type == "gconforum")
forums.extend(items)
elif isinstance(items, dict):
items["_is_signed"] = (forum_type == "gconforum")
forums.append(items)
if res.get("has_more") != "1":
break
page_no += 1
time.sleep(random.uniform(1, 2))
except Exception as e:
log_error(f"获取贴吧列表出错: {e}")
break
log_info(f"共获取到 {len(forums)} 个关注的贴吧")
return forums
def build_level_summary(forums: List[Dict]) -> Dict:
"""从贴吧列表中提取等级汇总"""
total_exp = 0
level_stats = {}
forum_levels = []
for f in forums:
name = f.get("name", "")
level_id = int(f.get("level_id", 0))
cur_score = int(f.get("cur_score", 0))
levelup_score = int(f.get("levelup_score", 0))
total_exp += cur_score
if level_id not in level_stats:
level_stats[level_id] = {"count": 0, "total_exp": 0}
level_stats[level_id]["count"] += 1
level_stats[level_id]["total_exp"] += cur_score
forum_levels.append({
"name": name,
"level_id": level_id,
"cur_score": cur_score,
"levelup_score": levelup_score,
"exp_percent": round(cur_score / levelup_score * 100, 1) if levelup_score > 0 else 0,
})
sorted_levels = sorted(level_stats.items(), key=lambda x: x[0], reverse=True)
return {
"forum_count": len(forums),
"total_exp": total_exp,
"level_stats": sorted_levels,
"forum_levels": forum_levels,
}
def sign_forums(session: requests.Session, bduss: str, forums: List[Dict], tbs: str) -> Dict[str, Any]:
"""对贴吧列表进行签到"""
success_count = 0
error_count = 0
exist_count = 0
shield_count = 0
total = len(forums)
details = []
log_info(f"开始签到 {total} 个贴吧")
base_data = {
"_client_type": "2",
"_client_version": "9.7.8.0",
"_phone_imei": "000000000000000",
"model": "MI+5",
"net_type": "1",
}
last_request_time = time.time()
for idx, forum in enumerate(forums):
elapsed = time.time() - last_request_time
delay = max(0, 1.0 + random.uniform(0.5, 1.5) - elapsed)
time.sleep(delay)
last_request_time = time.time()
if (idx + 1) % 10 == 0:
extra_delay = random.uniform(5, 10)
log_info(f"已签到 {idx + 1}/{total} 个贴吧,休息 {extra_delay:.2f}")
time.sleep(extra_delay)
forum_name = forum.get("name", "")
forum_id = forum.get("id", "")
level_id = forum.get("level_id", "?")
log_prefix = f"{forum_name}】吧(Lv.{level_id})({idx + 1}/{total})"
try:
data = base_data.copy()
data.update({"BDUSS": bduss, "fid": forum_id, "kw": forum_name, "tbs": tbs, "timestamp": str(int(time.time()))})
data = encode_data(data)
result = request(session, "http://c.tieba.baidu.com/c/c/forum/sign", "post", data)
error_code = result.get("error_code", "")
rank = None
if error_code == "0":
success_count += 1
if "user_info" in result:
rank = result["user_info"].get("user_sign_rank")
log_success(f"{log_prefix} 签到成功,第{rank}个签到" if rank else f"{log_prefix} 签到成功")
else:
log_success(f"{log_prefix} 签到成功")
details.append({"name": forum_name, "status": "success", "rank": rank, "level": level_id})
elif error_code == "160002":
exist_count += 1
log_warning(f"{log_prefix} {result.get('error_msg', '今日已签到')}")
details.append({"name": forum_name, "status": "exist", "rank": None, "level": level_id})
elif error_code == "340006":
shield_count += 1
log_warning(f"{log_prefix} 贴吧已被屏蔽")
details.append({"name": forum_name, "status": "shield", "rank": None, "level": level_id})
else:
error_count += 1
log_error(f"{log_prefix} 签到失败,错误: {result.get('error_msg', '未知错误')}")
details.append({"name": forum_name, "status": "error", "rank": None, "level": level_id})
except Exception as e:
error_count += 1
log_error(f"{log_prefix} 签到异常: {e!s}")
details.append({"name": forum_name, "status": "error", "rank": None, "level": level_id})
return {"total": total, "success": success_count, "exist": exist_count, "shield": shield_count, "error": error_count, "details": details}
def build_report(stats: Dict, user_name: str, details: List[Dict], level_summary: Optional[Dict] = None) -> str:
"""构建签到报告"""
lines = ["📢 百度贴吧 签到报告", "", f"👤 账号: {user_name}", ""]
lines.append("📊 签到统计")
lines.append(f"📌 贴吧总数: {stats['total']}")
lines.append(f"✅ 签到成功: {stats['success']}")
lines.append(f"⚠️ 已经签到: {stats['exist']}")
lines.append(f"🚫 被屏蔽的: {stats['shield']}")
lines.append(f"❌ 签到失败: {stats['error']}")
if level_summary:
lines.append("")
lines.append("🎯 等级汇总")
lines.append(f"📈 总经验值: {level_summary['total_exp']:,}")
top_levels = level_summary["level_stats"][:5]
level_dist = " | ".join([f"Lv.{lv}: {info['count']}个吧" for lv, info in top_levels])
lines.append(f"🏅 等级分布: {level_dist}")
if details:
lines.append("")
lines.append("📋 详细签到情况")
for d in details:
name = d["name"]
status = d["status"]
rank = d.get("rank")
level = d.get("level", "?")
if status == "success":
emoji = ""
rank_text = f" (第{rank}个)" if rank else ""
elif status == "exist":
emoji = "⚠️"; rank_text = ""
elif status == "shield":
emoji = "🚫"; rank_text = ""
else:
emoji = ""; rank_text = ""
lines.append(f"{emoji} {name} Lv.{level}{rank_text}")
lines.append("")
lines.append("" * 18)
lines.append(f"🕒 执行时间: {beijing_time_str()}")
return "\n".join(lines)
def main() -> Dict:
"""主流程"""
cookie_dict = {item.split("=")[0]: item.split("=")[1] for item in TIEBA_COOKIE.split("; ") if "=" in item}
bduss = cookie_dict.get("BDUSS", "")
if not bduss:
log_error("Cookie 中未找到 BDUSS请检查配置")
return {"user_name": "未知", "stats": {"total": 0, "success": 0, "exist": 0, "shield": 0, "error": 0}, "details": [], "level_summary": None}
session = create_session(TIEBA_COOKIE)
tbs, user_name = get_user_info(session)
if not tbs:
log_error(user_name)
return {"user_name": "登录失败", "stats": {"total": 0, "success": 0, "exist": 0, "shield": 0, "error": 0}, "details": [], "level_summary": None}
log_success(f"登录成功,用户名: {user_name}")
forums = get_favorite(session, bduss=bduss)
if not forums:
log_warning("未获取到任何贴吧,请检查 Cookie 或网络")
return {"user_name": user_name, "stats": {"total": 0, "success": 0, "exist": 0, "shield": 0, "error": 0}, "details": [], "level_summary": None}
level_summary = build_level_summary(forums)
log_info(f"总经验值: {level_summary['total_exp']:,},最高等级: Lv.{level_summary['level_stats'][0][0] if level_summary['level_stats'] else '?'}")
result = sign_forums(session, bduss, forums, tbs)
log_info(f"签到完成: 总数 {result['total']},成功 {result['success']},已签 {result['exist']},屏蔽 {result['shield']},失败 {result['error']}")
return {"user_name": user_name, "stats": result, "details": result["details"], "level_summary": level_summary}
if __name__ == "__main__":
result = main()
if result:
report = build_report(result["stats"], result["user_name"], result["details"], result.get("level_summary"))
notify_send("百度贴吧 签到报告", report)