1+ #!/usr/bin/env python3
2+ # -*- coding: utf-8 -*-
3+ # 作者: 青龙面板适配
4+ # 说明: 360社区自动签到脚本(青龙面板专用)
5+ # 依赖: requests
6+ # 用法: 在青龙面板环境变量中设置 BBS360_COOKIE
7+ # 请确保Cookie包含 __cfduid, uid 等必要字段
8+
9+ import os
10+ import re
11+ import time
12+ import random
13+ import requests
14+ from dataclasses import dataclass
15+ from typing import Optional , Tuple
16+
17+ SIGN_PAGE = "https://bbs.360.cn/dsu_paulsign-sign.html"
18+ SIGN_API = "https://bbs.360.cn/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1&inajax=1"
19+
20+ @dataclass
21+ class CheckinResult :
22+ ok : bool
23+ status : str
24+ detail : str
25+
26+ class BBS360Checkin :
27+ """360社区签到客户端(青龙面板适配)"""
28+ def __init__ (self , cookie : str , timeout : int = 20 ):
29+ self .cookie = cookie .strip ()
30+ self .timeout = timeout
31+ self .session = requests .Session ()
32+ self .session .headers .update ({
33+ "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0 Safari/537.36" ,
34+ "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" ,
35+ "Accept-Language" : "zh-CN,zh;q=0.9" ,
36+ "Connection" : "keep-alive" ,
37+ "Cookie" : self .cookie ,
38+ "Referer" : "https://bbs.360.cn/" ,
39+ })
40+
41+ def fetch_formhash (self ) -> Tuple [Optional [str ], str ]:
42+ """拉取签到页并提取 formhash"""
43+ resp = self .session .get (SIGN_PAGE , timeout = self .timeout , allow_redirects = True )
44+ text = resp .text or ""
45+
46+ # 青龙面板特殊处理:如果返回403,可能是需要验证
47+ if resp .status_code == 403 :
48+ return None , "403 Forbidden(可能需要绑定手机号)"
49+
50+ # 未登录/未绑定手机号时提示
51+ if "您需要先登录才能继续本操作" in text or "请使用手机微信扫码安全登录" in text :
52+ return None , "未登录或账号未绑定手机号(需在360社区绑定手机号)"
53+
54+ # 提取 formhash
55+ m = re .search (r'formhash=([0-9a-zA-Z]{6,})' , text )
56+ if not m :
57+ m = re .search (r'name="formhash"\s+value="([0-9a-zA-Z]{6,})"' , text )
58+
59+ if not m :
60+ return None , "未解析到 formhash(页面结构可能变更)"
61+
62+ return m .group (1 ), "OK"
63+
64+ def submit_checkin (self , formhash : str ) -> CheckinResult :
65+ """提交签到请求"""
66+ moods = ["kx" , "ym" , "tp" , "ng" , "wl" ]
67+ payload = {
68+ "formhash" : formhash ,
69+ "qdxq" : random .choice (moods ),
70+ "qdmode" : "1" ,
71+ "todaysay" : random .choice ([
72+ "打卡签到,愿一切顺利!" ,
73+ "新的一天,继续加油~" ,
74+ "保持热爱,奔赴山海。" ,
75+ "今日签到,万事胜意。" ,
76+ "坚持自律,慢慢变强。" ,
77+ ]),
78+ "fastreply" : "0" ,
79+ }
80+
81+ resp = self .session .post (SIGN_API , data = payload , timeout = self .timeout )
82+ raw = resp .text or ""
83+
84+ # 青龙面板特殊处理:返回403或500
85+ if resp .status_code != 200 :
86+ return CheckinResult (False , f"http_{ resp .status_code } " , f"HTTP { resp .status_code } " )
87+
88+ # 检查签到结果
89+ if "签到成功" in raw or ("恭喜" in raw and "签到" in raw ):
90+ return CheckinResult (True , "success" , self ._extract_message (raw ) or "签到成功" )
91+ if "已经签到" in raw or "已签到" in raw or "请勿重复签到" in raw :
92+ return CheckinResult (True , "already" , self ._extract_message (raw ) or "今日已签到" )
93+ if ("formhash" in raw and "错误" in raw ) or "请求无效" in raw :
94+ return CheckinResult (False , "bad_formhash" , self ._extract_message (raw ) or "formhash无效/过期" )
95+
96+ return CheckinResult (False , "unknown" , self ._extract_message (raw ) or raw [:200 ])
97+
98+ @staticmethod
99+ def _extract_message (text : str ) -> str :
100+ """提取提示信息"""
101+ m = re .search (r"showmessage\('([^']+)'\)" , text )
102+ if m :
103+ return m .group (1 )
104+
105+ m = re .search (r"([^\n\r]{0,20}(签到|已签到|重复签到)[^\n\r]{0,40})" , text )
106+ if m :
107+ return m .group (1 )
108+
109+ return ""
110+
111+ def run (self ) -> CheckinResult :
112+ formhash , info = self .fetch_formhash ()
113+ if not formhash :
114+ return CheckinResult (False , "no_login_or_parse_failed" , info )
115+
116+ time .sleep (random .uniform (1.0 , 2.5 ))
117+ return self .submit_checkin (formhash )
118+
119+ def main ():
120+ # 青龙面板专用:从环境变量获取Cookie
121+ cookie = os .getenv ("BBS360_COOKIE" , "" ).strip ()
122+
123+ if not cookie :
124+ print ("❌ 未设置环境变量 BBS360_COOKIE" )
125+ print ("💡 请在青龙面板 → 环境变量 → 添加以下内容:" )
126+ print (" KEY: BBS360_COOKIE" )
127+ print (" VALUE: 从浏览器复制的完整Cookie(包含__cfduid, uid等)" )
128+ return
129+
130+ # 青龙面板特殊处理:检测Cookie是否包含必要字段
131+ if "__cfduid" not in cookie or "uid" not in cookie :
132+ print ("❌ Cookie无效:缺少必要字段(需包含__cfduid和uid)" )
133+ print ("💡 请重新复制Cookie:" )
134+ print (" 1. 登录 bbs.360.cn → F12 → Application → Cookies" )
135+ print (" 2. 复制 bbs.360.cn 下的所有Cookie字段" )
136+ return
137+
138+ client = BBS360Checkin (cookie = cookie , timeout = 20 )
139+ result = client .run ()
140+
141+ # 青龙面板专用输出格式
142+ if result .ok :
143+ print (f"✅ 360签到成功 | { result .status } | { result .detail } " )
144+ else :
145+ print (f"❌ 360签到失败 | { result .status } | { result .detail } " )
146+
147+ if __name__ == "__main__" :
148+ main ()
0 commit comments