Collect authenticated Qinglong scripts batch
This commit is contained in:
333
脚本库/web版/账密/百度贴吧签到/2026-05-23_Tieba_9b1ac223.py
Normal file
333
脚本库/web版/账密/百度贴吧签到/2026-05-23_Tieba_9b1ac223.py
Normal 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)
|
||||
Reference in New Issue
Block a user