增加百度贴吧签到脚本
This commit is contained in:
parent
be13cc915e
commit
1e248d72df
152
TeiBa/README.md
Normal file
152
TeiBa/README.md
Normal 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
332
TeiBa/tb_signin.py
Normal 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==== 全部处理完成 ====")
|
Loading…
Reference in New Issue
Block a user