Summary: This script automates daily sign-ins on Chaohe Forum. It uses your cookie to simulate login and supports two Discuz plugins: dsu_paulsign and k_misign. It includes retry logic and result reporting.
阿里云:
服务器购买地址
https://t.aliyun.com/U/kcPAeY若失效,可用地址
https://www.aliyun.com/daily-act/ecs/activity_selection?source=5176.29345612&userCode=49hts92d腾讯云:
https://curl.qcloud.com/wJpWmSfU若失效,可用地址
https://cloud.tencent.com/act/cps/redirect?redirect=2446&cps_key=ad201ee2ef3b771157f72ee5464b1fea&from=console华为云
https://activity.huaweicloud.com/cps.html?fromacct=64b5cf7cc11b4840bb4ed2ea0b2f4468&utm_source=V1g3MDY4NTY=&utm_medium=cps&utm_campaign=2019052.部署教程
3.代码如下
#!/usr/bin/env python3# -*- coding: utf-8 -*-import osimport reimport timeimport randomfrom dataclasses import dataclassfrom typing import Optional, Tuple, Dictimport requests# -------------------------- 配置区 --------------------------BASE_URL = "https://www.238000.net"ENV_COOKIE_KEY = "CHAOHE_COOKIE"UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ""(KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36")DEFAULT_TIMEOUT = 15RETRY_TIMES = 3# -------------------------- 数据结构 --------------------------class SignResult:ok: boolmethod: strmessage: strraw: str = ""# -------------------------- 核心客户端 --------------------------class ChaoheForumSigner:def __init__(self, cookie: str):self.cookie = cookie.strip()self.sess = requests.Session()self.sess.headers.update({"User-Agent": UA,"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language": "zh-CN,zh;q=0.9","Connection": "keep-alive",})# ---------- 基础请求 ----------def request_with_retry(self,method: str,url: str,*,headers: Optional[Dict[str, str]] = None,params: Optional[dict] = None,data: Optional[dict] = None,allow_redirects: bool = True,timeout: int = DEFAULT_TIMEOUT,) -> requests.Response:last_err = Nonefor i in range(RETRY_TIMES):try:h = {}if headers:h.update(headers)# 强制带 cookieh["Cookie"] = self.cookieresp = self.sess.request(method=method.upper(),url=url,headers=h,params=params,data=data,allow_redirects=allow_redirects,timeout=timeout,)return respexcept Exception as e:last_err = esleep_s = 1 + iprint(f"[WARN] 请求失败,第 {i+1}/{RETRY_TIMES} 次重试:{e},{sleep_s}s 后重试")time.sleep(sleep_s)raise RuntimeError(f"请求最终失败: {last_err}")# ---------- Discuz: 获取 formhash ----------def get_formhash(self) -> Optional[str]:# Discuz 的 formhash 通常在 forum.php / 首页等页面url = f"{BASE_URL}/forum.php"resp = self.request_with_retry("GET", url, allow_redirects=True)if resp.status_code != 200:return None# 常见形态:name="formhash" value="xxxx"m = re.search(r'name="formhash"\s+value="(\w+)"', resp.text)if m:return m.group(1)# 有些页面会用 JS 变量m2 = re.search(r"formhash\s*=\s*['\"](\w+)['\"]", resp.text)if m2:return m2.group(1)return None# ---------- Discuz: dsu_paulsign 签到 ----------def sign_dsu_paulsign(self) -> SignResult:"""典型签到页: plugin.php?id=dsu_paulsign:sign提交: plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1&inajax=1"""formhash = self.get_formhash()if not formhash:return SignResult(False, "dsu_paulsign", "未获取到 formhash(可能未登录/站点结构变化)")referer = f"{BASE_URL}/plugin.php?id=dsu_paulsign:sign"submit_url = f"{referer}&operation=qiandao&infloat=1&inajax=1"# 常见字段(不同站点可能略有差异,但大多数兼容)payload = {"formhash": formhash,"qdxq": "kx", # 心情:开心(常见值:kx/ym/wl/ng等)"qdmode": "1", # 签到模式"todaysay": "今日签到,万事顺意~","fastreply": "0",}headers = {"Referer": referer,"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8","X-Requested-With": "XMLHttpRequest",}resp = self.request_with_retry("POST", submit_url, headers=headers, data=payload)raw = resp.text.strip()# Discuz ajax 返回可能是 XML/HTML/JSON 混合,这里用关键词兜底判断success_kw = ["签到成功", "恭喜", "您已签到", "打卡成功"]already_kw = ["已经签到", "已签到", "请勿重复"]if any(k in raw for k in success_kw):return SignResult(True, "dsu_paulsign", "签到成功", raw=raw[:500])if any(k in raw for k in already_kw):return SignResult(True, "dsu_paulsign", "今日已签到", raw=raw[:500])# 常见未登录提示if "登录" in raw and ("您还未登录" in raw or "请先登录" in raw):return SignResult(False, "dsu_paulsign", "Cookie 可能无效/未登录", raw=raw[:500])return SignResult(False, "dsu_paulsign", f"签到失败(HTTP {resp.status_code})", raw=raw[:500])# ---------- Discuz: k_misign 签到(抓 JD_sign href 再访问) ----------def sign_k_misign(self) -> SignResult:"""常见签到页: /k_misign-sign.html页面里会有:id="JD_sign" href="xxx"访问 href 即完成签到"""sign_page = f"{BASE_URL}/k_misign-sign.html"resp = self.request_with_retry("GET", sign_page, allow_redirects=True)raw_html = resp.text# 找到签到链接m = re.search(r'id="JD_sign"[^>]*href="([^"]+)"', raw_html, re.I)if not m:# 可能已签到 或页面结构不同if any(k in raw_html for k in ["已签到", "已经签到", "今日已签到"]):return SignResult(True, "k_misign", "今日已签到", raw=raw_html[:500])return SignResult(False, "k_misign", "未找到 JD_sign 签到入口(可能站点未使用 k_misign)", raw=raw_html[:500])url_path = m.group(1).replace("&", "&")if not url_path.startswith("http"):if not url_path.startswith("/"):url_path = "/" + url_pathreal_url = BASE_URL + url_pathelse:real_url = url_pathheaders = {"Referer": sign_page}resp2 = self.request_with_retry("GET", real_url, headers=headers, allow_redirects=True)raw2 = resp2.textif resp2.status_code in (200, 302):# 兜底判断if any(k in raw2 for k in ["签到成功", "打卡成功", "已签到", "已经签到", "今日已签到"]):return SignResult(True, "k_misign", "签到成功/已签到", raw=raw2[:500])return SignResult(True, "k_misign", "已提交签到请求(请以站点实际结果为准)", raw=raw2[:500])return SignResult(False, "k_misign", f"签到请求失败(HTTP {resp2.status_code})", raw=raw2[:500])# ---------- 主流程 ----------def run(self) -> SignResult:"""签到优先级:1) dsu_paulsign2) k_misign"""print("[INFO] 开始执行巢湖论坛签到…")# 增加一点随机延迟,降低"固定脚本特征"time.sleep(random.uniform(1.0, 2.5))# 1) 先试 dsu_paulsignr1 = self.sign_dsu_paulsign()if r1.ok:return r1print(f"[WARN] dsu_paulsign 未成功:{r1.message}")time.sleep(random.uniform(0.8, 1.8))# 2) 再试 k_misignr2 = self.sign_k_misign()return r2def main():cookie = os.getenv(ENV_COOKIE_KEY, "").strip()if not cookie:print(f"❌ 未检测到环境变量 {ENV_COOKIE_KEY}")print("请先设置 Cookie 后再运行。")print("示例:")print(f" export {ENV_COOKIE_KEY}='xxx_saltkey=...; xxx_auth=...; ...'")returnsigner = ChaoheForumSigner(cookie)try:result = signer.run()print("=" * 60)print(f"站点: {BASE_URL}")print(f"方式: {result.method}")print(f"结果: {'✅成功' if result.ok else '❌失败'}")print(f"说明: {result.message}")if result.raw:print("-" * 60)print("响应片段(前500字):")print(result.raw)print("=" * 60)except Exception as e:print("❌ 运行异常:", e)if __name__ == "__main__":main()
该脚本为巢湖论坛自动签到脚本,主要作用包括:
使用你提供的 Cookie 模拟已登录状态
自动识别并尝试论坛常见的两种签到机制:
Discuz
dsu_paulsign插件签到(最常见)k_misign签到页模式(常见于/k_misign-sign.html)输出签到结果(成功 / 已签到 / Cookie 失效 / 站点不匹配等)
主要方法
request_with_retry → 统一的 HTTP 请求入口,自动携带 Cookie,带超时和重试,减少网络波动导致的失败。
get_formhash → 从 Discuz 页面中提取 formhash(Discuz 提交表单的关键参数),用于后续签到提交。
sign_dsu_paulsign → 按 dsu_paulsign 插件的典型流程完成签到:先拿 formhash,再 POST 提交签到表单,并用关键词判断"成功/已签到/未登录"。
sign_k_misign → 访问 /k_misign-sign.html,解析页面里的 id="JD_sign" 签到链接,再请求该链接完成签到(兼容另一类常见签到插件)。
run → 控制签到执行顺序:先尝试 dsu_paulsign,失败后自动降级尝试 k_misign。
main → 程序入口:读取环境变量 Cookie,执行签到并打印结果。
注意:
本文部分变量已做脱敏处理,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。技术层面需要提供帮助,可以通过打赏的方式进行探讨。
没有评论:
发表评论