2026年2月1日星期日

New Tiantongyuan Community Check-in Script Guide

Content Summary: This script automates check-in for Tiantongyuan community, including server setup tutorials, code implementation with login and check-in functions, and detailed technical instructions for deployment.

1.购买服务器

阿里云:

服务器购买地址

https://t.aliyun.com/U/siC86h

若失效,可用地址

https://www.aliyun.com/benefit?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=201905

2.部署教程

2024年最新青龙面板跑脚本教程(一)持续更新中

3.代码如下

# -*- coding: utf-8 -*-
import reimport sysimport timeimport randomfrom dataclasses import dataclassfrom typing import OptionalTupleList
import requestsfrom bs4 import BeautifulSoup

BASE_URL = "https://www.ttysq.com"

@dataclassclass SignResult:    ok: bool    message: str    used_url: str = ""

class TtysSignIn:    def __init__(self, username: str, password: str, timeout: int = 20):        self.username = username        self.password = password        self.timeout = timeout
        self.sess = requests.Session()        # 伪装常见浏览器 UA,尽量降低被挡概率        self.sess.headers.update({            "User-Agent": (                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "                "AppleWebKit/537.36 (KHTML, like Gecko) "                "Chrome/122.0.0.0 Safari/537.36"            ),            "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 _sleep_jitter(self, a: float = 0.8, b: float = 1.8):        time.sleep(random.uniform(a, b))
    def _abs(self, path: str) -> str:        if path.startswith("http"):            return path        if not path.startswith("/"):            path = "/" + path        return BASE_URL + path
    def _get(self, url: str, **kwargs) -> requests.Response:        return self.sess.get(url, timeout=self.timeout, allow_redirects=True, **kwargs)
    def _post(self, url: str, data=None, **kwargs) -> requests.Response:        return self.sess.post(url, data=data, timeout=self.timeout, allow_redirects=True, **kwargs)
    def _extract_formhash(self, html: str) -> Optional[str]:        """        Discuz 常见:formhash=xxxxx        可能出现在 hidden input 或 JS 变量里        """        m = re.search(r'name="formhash"\s+value="([^"]+)"', html)        if m:            return m.group(1)        m = re.search(r"formhash=([0-9a-zA-Z]+)", html)        if m:            return m.group(1)        return None
    def _is_logged_in(self, html: str) -> bool:        """        粗略判断:Discuz 登录后常见有"退出/设置/消息/space-uid"等痕迹        """        keys = ["退出""设置""space-uid""pwderr""欢迎您回来"]        return any(k in html for k in keys)
    # ------------------------- 核心:登录 -------------------------
    def login(self) -> Tuple[boolstr]:        """        走 Discuz 常见登录流程:        1) 访问登录页拿 formhash        2) 提交 member.php?mod=logging&action=login&loginsubmit=yes...        """        # Discuz 常见登录页        login_page = self._abs("/member.php?mod=logging&action=login")        try:            r1 = self._get(login_page)        except Exception as e:            return Falsef"访问登录页失败:{e}"
        if r1.status_code in (403429):            return Falsef"站点拒绝访问({r1.status_code}),可能有风控/反爬,需要更换网络或加白"
        formhash = self._extract_formhash(r1.text)        if not formhash:            # 有些站点 formhash 在首页            self._sleep_jitter()            home = self._abs("/")            r_home = self._get(home)            formhash = self._extract_formhash(r_home.text)
        if not formhash:            return False"未获取到 formhash(可能不是 Discuz / 或页面结构不同)"
        self._sleep_jitter()
        # Discuz 常见登录提交地址(loginsubmit=yes)        login_submit = self._abs(            "/member.php?mod=logging&action=login&loginsubmit=yes&inajax=1"        )
        payload = {            "formhash": formhash,            "referer": BASE_URL + "/",            "username"self.username,            "password"self.password,            "questionid""0",            "answer""",        }
        # 某些站点要求 X-Requested-With        headers = {"X-Requested-With""XMLHttpRequest""Referer": login_page}
        try:            r2 = self._post(login_submit, data=payload, headers=headers)        except Exception as e:            return Falsef"提交登录失败:{e}"
        # Discuz inajax=1 往往返回 XML/HTML 片段        # 这里再访问一次首页验证是否登录态生效        self._sleep_jitter()        r3 = self._get(self._abs("/"))        if self._is_logged_in(r3.text):            return True"登录成功"        else:            # 尝试从返回内容里挖错误提示            msg = self._extract_discuz_msg(r2.text) or "登录失败(账号/密码/验证码/风控)"            return False, msg
    def _extract_discuz_msg(self, text: str) -> Optional[str]:        """        Discuz 常见 message:<p>xxx</p> 或者 XML 中的 <![CDATA[xxx]]>        """        m = re.search(r"<!\[CDATA\[(.*?)\]\]>", text, re.S)        if m:            return re.sub(r"\s+"" ", m.group(1)).strip()        # 粗略提取 p 标签文本        soup = BeautifulSoup(text, "html.parser")        p = soup.find("p")        if p and p.get_text(strip=True):            return p.get_text(strip=True)        return None
    # ------------------------- 核心:签到 -------------------------
    def sign_in(self) -> SignResult:        """        自动尝试多个常见 Discuz 签到插件路径:        - dsu_paulsign(最常见)        - k_misign(另一个常见)        - 以及部分站点自定义 action        """        # 先拿最新 formhash(很多签到接口需要)        r_home = self._get(self._abs("/"))        formhash = self._extract_formhash(r_home.text) or ""
        # 候选签到 URL(按常见程度排序)        candidates = self._build_sign_candidates(formhash)
        last_err = ""        for url, method, data in candidates:            self._sleep_jitter(0.61.2)            try:                if method == "GET":                    resp = self._get(url, headers={"Referer": BASE_URL + "/"})                else:                    resp = self._post(url, data=data, headers={"Referer": BASE_URL + "/"})            except Exception as e:                last_err = f"请求异常:{e}"                continue
            # 403/风控直接记下            if resp.status_code in (403429):                last_err = f"请求被拒绝:HTTP {resp.status_code}"                continue
            ok, msg = self._parse_sign_response(resp.text)            if ok:                return SignResult(True, msg, used_url=url)            else:                # 记录最后一次失败原因继续尝试下一个                last_err = msg or "签到失败(未知原因)"
        return SignResult(Falsef"所有候选签到接口均失败:{last_err}", used_url="")
    def _build_sign_candidates(self, formhash: str) -> List[Tuple[strstrdict]]:        """        组装候选请求:        返回 (url, method, data)        """        fh = formhash or ""        return [            # 1) dsu_paulsign 常见:operation=qiandao            (self._abs(f"/plugin.php?id=dsu_paulsign:sign&operation=qiandao&inajax=1&formhash={fh}"), "GET", {}),            (self._abs("/plugin.php?id=dsu_paulsign:sign&operation=qiandao&inajax=1"), "POST", {"formhash": fh, "qdmode""1"}),
            # 2) k_misign 常见:operation=qiandao            (self._abs(f"/plugin.php?id=k_misign:sign&operation=qiandao&inajax=1&formhash={fh}"), "GET", {}),            (self._abs("/plugin.php?id=k_misign:sign&operation=qiandao&inajax=1"), "POST", {"formhash": fh}),
            # 3) 少数站点:直接 sign            (self._abs(f"/plugin.php?id=dsu_paulsign:sign&inajax=1&formhash={fh}"), "GET", {}),            (self._abs(f"/plugin.php?id=k_misign:sign&inajax=1&formhash={fh}"), "GET", {}),        ]
    def _parse_sign_response(self, text: str) -> Tuple[boolstr]:        """        尝试从返回内容判断是否签到成功/已签到/失败原因        """        # 先做通用清洗        raw = re.sub(r"\s+"" ", text).strip()
        # 常见成功/已签到关键词(不同插件返回差异很大,这里做模糊判断)        success_keywords = ["签到成功""打卡成功""已签到""您已签到""success""Success""恭喜"]        fail_keywords = ["失败""error""Error""需要先登录""请先登录""验证码""权限""拒绝访问"]
        if any(k in raw for k in success_keywords):            # 尽量提取一句话            msg = self._extract_discuz_msg(text) or "签到成功/已签到"            return True, msg
        if any(k in raw for k in fail_keywords):            msg = self._extract_discuz_msg(text) or "签到失败(可能未登录/验证码/权限/风控)"            return False, msg
        # 如果返回非常短,可能是 inajax 的提示        if len(raw) < 200 and raw:            return False, raw
        return False"签到接口返回无法识别(可能不是这些插件/需要额外参数)"
    # ------------------------- 统一入口 -------------------------
    def run(self) -> int:        ok, msg = self.login()        print(f"[LOGIN] {msg}")        if not ok:            return 1
        sign_res = self.sign_in()        if sign_res.ok:            print(f"[SIGN ] ✅ {sign_res.message}")            print(f"[URL  ] {sign_res.used_url}")            return 0        else:            print(f"[SIGN ] ❌ {sign_res.message}")            if sign_res.used_url:                print(f"[URL  ] {sign_res.used_url}")            return 2

if __name__ == "__main__":    # 也可以改成从环境变量读取    TTY_USERNAME = os.getenv("TTYSQ_USERNAME""").strip()    TTY_PASSWORD = os.getenv("TTYSQ_PASSWORD""").strip()
    if not TTY_USERNAME or not TTY_PASSWORD:        print("请先设置账号密码:")        print("  Windows(PowerShell):")        print("    setx TTYSQ_USERNAME \"你的账号\"")        print("    setx TTYSQ_PASSWORD \"你的密码\"")        print("  Linux/macOS:")        print("    export TTYSQ_USERNAME='你的账号'")        print("    export TTYSQ_PASSWORD='你的密码'")        sys.exit(1)
    bot = TtysSignIn(TTY_USERNAME, TTY_PASSWORD)    sys.exit(bot.run())
解析
该脚本为天通苑自动签到脚本,主要功能包括:
  • 使用 requests.Session() 保持登录态(Cookie)

  • 自动从页面提取 formhash(Discuz 常用 CSRF 参数)

  • 按"候选签到插件 URL 列表"逐个尝试签到(兼容常见 dsu_paulsign / k_misign

  • 输出"签到成功 / 已签到 / 失败原因",方便快速定位需要替换的真实签到接口

主要方法

  • run → 脚本统一入口:先登录,再签到,最后返回退出码

  • login → 执行 Discuz 常见登录流程(获取 formhash → 提交登录 → 首页校验登录态)

  • _extract_formhash → 从 HTML 中提取 formhash(用于登录/签到等请求的关键参数)

  • _is_logged_in → 通过页面关键字粗略判断当前是否已登录

  • _extract_discuz_msg → 从 Discuz 的 inajax 返回内容里提取人类可读的提示文本(成功/失败原因)

  • sign_in → 执行签到:先获取最新 formhash,然后遍历候选签到 URL 逐个尝试

  • _build_sign_candidates → 构建"候选签到接口列表"(常见插件路径 + GET/POST 两种形态)

  • _parse_sign_response → 解析签到返回文本,判断成功/已签到/失败,并提取提示信息

  • _get / _post → 对 requests 的 GET/POST 做统一封装(带 timeout、redirect 等)

  • _sleep_jitter → 随机抖动等待,降低触发风控的概率

  • _abs → 拼接相对路径为完整 URL


注意

本文部分变量已做脱敏处理,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。技术层面需要提供帮助,可以通过打赏的方式进行探讨。


历史脚本txt文件获取>>
服务器搭建,人工服务咨询>>

没有评论:

发表评论

揭秘烟酒店盈利:合规渠道与经营策略分析

烟酒店盈利不单靠零售。合法途径包括喜宴供货、节日礼品、企业团购及囤货低买高卖;高额流水则涉及供应链分工。另需警惕回收烟酒、跨区销售等违法行为。 烟酒店的盈利探秘 我家楼下烟酒店听说一年能够赚两百多个,一天也不见得进几个人,你猜他们都是怎么赚钱的?我来用两分钟跟你说清楚,一家烟...