360社区签到客户端(青龙面板适配)
| 25 | detail: str |
| 26 | |
| 27 | class BBS360Checkin: |
| 28 | """360社区签到客户端(青龙面板适配)""" |
| 29 | def __init__(self, cookie: str, timeout: int = 20): |
| 30 | self.cookie = cookie.strip() |
| 31 | self.timeout = timeout |
| 32 | self.session = requests.Session() |
| 33 | self.session.headers.update({ |
| 34 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0 Safari/537.36", |
| 35 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", |
| 36 | "Accept-Language": "zh-CN,zh;q=0.9", |
| 37 | "Connection": "keep-alive", |
| 38 | "Cookie": self.cookie, |
| 39 | "Referer": "https://bbs.360.cn/", |
| 40 | }) |
| 41 | |
| 42 | def fetch_formhash(self) -> Tuple[Optional[str], str]: |
| 43 | """拉取签到页并提取 formhash""" |
| 44 | resp = self.session.get(SIGN_PAGE, timeout=self.timeout, allow_redirects=True) |
| 45 | text = resp.text or "" |
| 46 | |
| 47 | # 青龙面板特殊处理:如果返回403,可能是需要验证 |
| 48 | if resp.status_code == 403: |
| 49 | return None, "403 Forbidden(可能需要绑定手机号)" |
| 50 | |
| 51 | # 未登录/未绑定手机号时提示 |
| 52 | if "您需要先登录才能继续本操作" in text or "请使用手机微信扫码安全登录" in text: |
| 53 | return None, "未登录或账号未绑定手机号(需在360社区绑定手机号)" |
| 54 | |
| 55 | # 提取 formhash |
| 56 | m = re.search(r'formhash=([0-9a-zA-Z]{6,})', text) |
| 57 | if not m: |
| 58 | m = re.search(r'name="formhash"\s+value="([0-9a-zA-Z]{6,})"', text) |
| 59 | |
| 60 | if not m: |
| 61 | return None, "未解析到 formhash(页面结构可能变更)" |
| 62 | |
| 63 | return m.group(1), "OK" |
| 64 | |
| 65 | def submit_checkin(self, formhash: str) -> CheckinResult: |
| 66 | """提交签到请求""" |
| 67 | moods = ["kx", "ym", "tp", "ng", "wl"] |
| 68 | payload = { |
| 69 | "formhash": formhash, |
| 70 | "qdxq": random.choice(moods), |
| 71 | "qdmode": "1", |
| 72 | "todaysay": random.choice([ |
| 73 | "打卡签到,愿一切顺利!", |
| 74 | "新的一天,继续加油~", |
| 75 | "保持热爱,奔赴山海。", |
| 76 | "今日签到,万事胜意。", |
| 77 | "坚持自律,慢慢变强。", |
| 78 | ]), |
| 79 | "fastreply": "0", |
| 80 | } |
| 81 | |
| 82 | resp = self.session.post(SIGN_API, data=payload, timeout=self.timeout) |
| 83 | raw = resp.text or "" |
| 84 |