增加百度贴吧签到脚本

This commit is contained in:
UPToZ 2025-06-02 17:59:24 +08:00
parent be13cc915e
commit 1e248d72df
2 changed files with 484 additions and 0 deletions

152
TeiBa/README.md Normal file
View File

@ -0,0 +1,152 @@
# 百度贴吧自动签到脚本
## 项目简介
这是一个用于百度贴吧自动签到的青龙面板脚本支持多账号管理、自动获取关注的贴吧列表并执行签到操作同时提供签到结果通知功能。脚本通过读取青龙环境变量或配置文件中的Cookie信息实现无人值守的贴吧签到任务。
## 功能特点
- 自动获取所有关注的百度贴吧并执行签到
- 支持多账号同时管理和签到
- 智能处理已签到、被屏蔽的贴吧
- 详细的签到结果统计和日志输出
- 支持青龙面板通知功能,实时推送签到结果
- 自动处理网络请求异常,包含重试机制
## 前提条件
1. 已部署青龙面板环境v2或v2.1+
2. 拥有有效的百度账号Cookie包含BDUSS字段
3. 青龙面板已安装通知模块(可选,用于推送签到结果)
## 配置步骤
### 1. 获取百度贴吧Cookie
#### 获取BDUSS的方法
1. 使用浏览器登录百度账号
2. 访问百度贴吧任意页面(如 https://tieba.baidu.com
3. 按F12打开开发者工具切换到"应用程序"(Application)选项卡
4. 在左侧菜单中选择"Cookie",找到`BDUSS`字段
5. 复制`BDUSS`的值,格式类似:`xxx&yyy=zzz; ...`
#### 完整Cookie获取方法
1. 登录百度贴吧后,右键网页空白处选择"检查"
2. 在开发者工具中切换到"网络"(Network)选项卡
3. 刷新页面,找到任意请求(如`tbs`或`like`
4. 在请求详情中找到"请求标头"(Request Headers)
5. 复制整个`Cookie`字段的值
### 2. 配置青龙环境变量
在青龙面板中添加环境变量:
1. 进入青龙面板 -> 环境变量 -> 新增
2. 变量名:`TIEBA`
3. 变量值粘贴获取的Cookie多账号用换行分隔
**多账号示例:**
```
BDUSS=xxx1; STOKEN=yyy1; ...
BDUSS=xxx2; STOKEN=yyy2; ...
```
### 3. 配置文件方式(可选)
如果不想使用环境变量,也可以在青龙中创建配置文件:
1. 在青龙脚本目录下创建`config.json`文件
2. 内容格式:
```json
{
"TIEBA": [
{"cookie": "BDUSS=xxx1; STOKEN=yyy1; ..."},
{"cookie": "BDUSS=xxx2; STOKEN=yyy2; ..."}
]
}
```
3. 脚本会优先读取环境变量,若不存在则尝试读取配置文件
## 使用方法
1. 将脚本文件上传到青龙面板的`scripts`目录
2. 在青龙面板中手动运行脚本,或设置定时任务
3. 查看脚本运行日志或接收通知获取签到结果
## 定时任务设置
在青龙面板中设置定时任务:
1. 进入青龙面板 -> 定时任务 -> 新增
2. 任务名称:自定义(如"百度贴吧签到"
3. 命令:`python3 /ql/scripts/tieba_sign.py`(根据实际路径调整)
4. Cron表达式`0 0 1 * * ?`每天凌晨1点执行可自定义
**常用Cron示例**
- 每天0点执行`0 0 * * * ?`
- 每周一0点执行`0 0 * * 1 ?`
- 每月1-5号0点执行`0 0 1-5 * * ?`
## 通知功能配置
脚本支持青龙面板的通知功能,需确保青龙已安装`notify.py`通知模块:
1. 确保青龙面板中存在`notify.py`文件
2. 脚本会自动调用`notify.send`方法发送通知
3. 签到完成后会汇总所有账号结果并发送通知
## 脚本日志说明
脚本运行时会输出详细日志:
- 成功签到:显示贴吧名称和签到排名
- 已签到:提示今日已完成签到
- 被屏蔽:显示贴吧已被屏蔽
- 错误信息:包含具体错误码和原因
- 账号间延迟:处理多账号时的等待时间
- 汇总统计:显示各账号签到结果和总体统计
## 常见问题
### 1. 签到失败,提示"登录失败Cookie异常"
- 原因Cookie已过期或缺少必要字段
- 解决方法重新获取最新Cookie确保包含`BDUSS`字段
### 2. 无法获取贴吧列表
- 原因:网络请求异常或账号权限问题
- 解决方法检查网络连接尝试更换Cookie
### 3. 提示"今日已签到"
- 原因:该贴吧当天已完成签到
- 解决方法:无需处理,脚本会自动跳过已签到的贴吧
### 4. 通知发送失败
- 原因:青龙未安装通知模块或模块路径错误
- 解决方法:安装`notify.py`通知模块,或检查模块路径
### 5. 多账号处理时速度过慢
- 原因:脚本为避免频繁请求设置了延迟
- 解决方法:如需加快速度,可调整`sign_forums`方法中的延迟参数
## 脚本更新
1. 如需更新脚本,直接替换青龙面板中的脚本文件
2. 建议定期更新以适应百度贴吧接口变化
3. 若签到失败率突然升高,可能是接口变动,需检查脚本是否需要更新
## 注意事项
1. 请勿频繁使用同一Cookie大量签到避免账号异常
2. Cookie有效期通常为7-15天建议定期更新
3. 脚本仅供个人使用,请勿用于商业用途
4. 百度可能随时变更接口,脚本可能需要不定期维护
5. 多账号处理时,账号间延迟可避免触发风控机制
通过以上步骤配置后,脚本将自动完成百度贴吧的签到任务,并通过通知推送结果,实现无人值守的贴吧签到管理。

332
TeiBa/tb_signin.py Normal file
View File

@ -0,0 +1,332 @@
"""
任务名称
name: 百度贴吧签到
定时规则
cron: 0 0 1 * * ?
"""
import hashlib
import json
import os
import random
import time
from typing import Optional, Union
import requests
class Tieba(object):
name = "百度贴吧"
def __init__(self, check_item: dict):
self.TBS_URL = "http://tieba.baidu.com/dc/common/tbs"
self.LIKE_URL = "http://c.tieba.baidu.com/c/f/forum/like"
self.SIGN_URL = "http://c.tieba.baidu.com/c/c/forum/sign"
self.LOGIN_INFO_URL = "https://zhidao.baidu.com/api/loginInfo"
self.SIGN_KEY = "tiebaclient!!!"
self.HEADERS = {
"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",
}
self.SIGN_DATA = {
"_client_type": "2",
"_client_version": "9.7.8.0",
"_phone_imei": "000000000000000",
"model": "MI+5",
"net_type": "1",
}
self.session = requests.Session()
self.session.headers.update(self.HEADERS)
cookie = check_item.get("cookie")
if not cookie:
raise ValueError("必须提供 BDUSS 或完整 Cookie")
cookie_dict = {
item.split("=")[0]: item.split("=")[1]
for item in cookie.split("; ")
if "=" in item
}
requests.utils.add_dict_to_cookiejar(self.session.cookies, cookie_dict)
self.bduss = cookie_dict.get("BDUSS", "")
if not self.bduss:
raise ValueError("Cookie 中未找到 BDUSS")
def request(
self, url: str, method: str = "get", data: Optional[dict] = None, retry: int = 3
) -> dict:
for i in range(retry):
try:
if method.lower() == "get":
response = self.session.get(url, timeout=10)
else:
response = self.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"请求失败: {str(e)}")
wait_time = 1.5 * (2**i) + random.uniform(0, 1)
time.sleep(wait_time)
raise Exception(f"请求失败,已达最大重试次数 {retry}")
def encode_data(self, data: dict) -> dict:
s = ""
for key in sorted(data.keys()):
s += f"{key}={data[key]}"
sign = hashlib.md5((s + self.SIGN_KEY).encode("utf-8")).hexdigest().upper()
data.update({"sign": sign})
return data
def get_user_info(self) -> tuple[Union[str, bool], str]:
try:
result = self.request(self.TBS_URL)
if result.get("is_login", 0) == 0:
return False, "登录失败Cookie 异常"
tbs = result.get("tbs", "")
try:
user_info = self.request(self.LOGIN_INFO_URL)
user_name = user_info.get("userName", "未知用户")
except Exception:
user_name = "未知用户"
return tbs, user_name
except Exception as e:
return False, f"登录验证异常: {e}"
def get_favorite(self) -> list[dict]:
forums = []
page_no = 1
while True:
data = {
"BDUSS": self.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",
}
data = self.encode_data(data)
try:
res = self.request(self.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):
forums.extend(items)
elif isinstance(items, dict):
forums.append(items)
if res.get("has_more") != "1":
break
page_no += 1
time.sleep(random.uniform(1, 2))
except Exception as e:
print(f"获取贴吧列表出错: {e}")
break
print(f"共获取到 {len(forums)} 个关注的贴吧")
return forums
def sign_forums(self, forums, tbs: str) -> dict:
success_count, error_count, exist_count, shield_count = 0, 0, 0, 0
total = len(forums)
print(f"开始签到 {total} 个贴吧")
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)
print(f"已签到 {idx + 1}/{total} 个贴吧,休息 {extra_delay:.2f}")
time.sleep(extra_delay)
forum_name = forum.get("name", "")
forum_id = forum.get("id", "")
log_prefix = f"{forum_name}】吧({idx + 1}/{total})"
try:
data = self.SIGN_DATA.copy()
data.update(
{
"BDUSS": self.bduss,
"fid": forum_id,
"kw": forum_name,
"tbs": tbs,
"timestamp": str(int(time.time())),
}
)
data = self.encode_data(data)
result = self.request(self.SIGN_URL, "post", data)
error_code = result.get("error_code", "")
if error_code == "0":
success_count += 1
if "user_info" in result:
rank = result["user_info"]["user_sign_rank"]
print(f"{log_prefix} 签到成功,第{rank}个签到")
else:
print(f"{log_prefix} 签到成功")
elif error_code == "160002":
exist_count += 1
print(f"{log_prefix} {result.get('error_msg', '今日已签到')}")
elif error_code == "340006":
shield_count += 1
print(f"{log_prefix} 贴吧已被屏蔽")
else:
error_count += 1
print(
f"{log_prefix} 签到失败,错误: {result.get('error_msg', '未知错误')}"
)
except Exception as e:
error_count += 1
print(f"{log_prefix} 签到异常: {str(e)}")
return {
"total": total,
"success": success_count,
"exist": exist_count,
"shield": shield_count,
"error": error_count,
}
def main(self) -> str:
try:
tbs, user_name = self.get_user_info()
if not tbs:
return f"账号: {user_name}\n登录状态: Cookie可能已过期"
forums = self.get_favorite()
if forums:
stats = self.sign_forums(forums, tbs)
msg = [
{"name": "帐号信息", "value": user_name},
{"name": "贴吧总数", "value": stats["total"]},
{"name": "签到成功", "value": stats["success"]},
{"name": "已经签到", "value": stats["exist"]},
{"name": "被屏蔽的", "value": stats["shield"]},
{"name": "签到失败", "value": stats["error"]},
]
else:
msg = [
{"name": "帐号信息", "value": user_name},
{"name": "获取贴吧列表失败,无法完成签到", "value": ""},
]
except Exception as e:
msg = [
{"name": "帐号信息", "value": "未知用户"},
{"name": "签到失败", "value": str(e)},
]
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
# 从青龙环境变量读取Cookie并处理多账户
def get_tieba_cookies():
cookies = []
# 尝试从环境变量读取
tieba_env = os.getenv('TIEBA', '')
if not tieba_env:
print("未找到环境变量 TIEBA")
# 尝试从配置文件读取
try:
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
config_cookies = datas.get("TIEBA", [])
for item in config_cookies:
if isinstance(item, dict) and 'cookie' in item:
cookies.append(item['cookie'])
if cookies:
print(f"从配置文件读取到 {len(cookies)} 个账号")
return cookies
except Exception as e:
print(f"读取配置文件失败: {e}")
return []
# 处理环境变量中的多账户(用换行分隔)
lines = tieba_env.strip().split('\n')
for line in lines:
line = line.strip()
if line:
cookies.append(line)
print(f"从环境变量读取到 {len(cookies)} 个账号")
return cookies
# 发送青龙面板通知
def send_notification(title, content):
try:
# 尝试导入青龙的通知模块
from notify import send
return send(title, content)
except Exception as e:
print(f"通知发送失败: {e}")
print(f"通知内容: {title}\n{content}")
return "通知发送失败"
if __name__ == "__main__":
cookies = get_tieba_cookies()
if not cookies:
print("没有找到有效的百度贴吧Cookie")
exit(1)
results = []
for idx, cookie in enumerate(cookies, 1):
print(f"\n==== 处理第 {idx}/{len(cookies)} 个账号 ====")
try:
check_item = {"cookie": cookie}
tieba = Tieba(check_item)
result = tieba.main()
results.append(result)
print(f"账号 {idx} 处理完成")
except Exception as e:
error_msg = f"账号 {idx} 处理失败: {str(e)}"
results.append(error_msg)
print(error_msg)
# 账号间随机延迟
if idx < len(cookies):
delay = random.uniform(3, 8)
print(f"等待 {delay:.2f} 秒后处理下一个账号...")
time.sleep(delay)
# 汇总所有结果并发送通知
final_title = "百度贴吧签到结果汇总"
final_content = "\n\n".join([f"【账号 {i+1}\n{result}" for i, result in enumerate(results)])
# 添加统计信息
success_count = sum(1 for r in results if "签到成功" in r)
total_count = len(results)
final_content += f"\n\n📊 统计信息:\n成功: {success_count}/{total_count}\n失败: {total_count-success_count}/{total_count}"
print("\n==== 开始发送通知 ====")
notify_result = send_notification(final_title, final_content)
print(f"通知发送结果: {notify_result}")
print("\n==== 全部处理完成 ====")