2026年1月30日星期五

New ” 101jiajiao。com Auto Check-In Script Tutorial ”

Summary: This script automates daily sign-ins on the 101jiajiao.com website. It logs in, navigates to the user/member center, and attempts to find and click check-in buttons. It handles potential issues like captchas (requires manual intervention). The guide includes server purchase links (Alibaba Cloud, Tencent Cloud, Huawei Cloud) and a 2024 Qinglong Panel deployment tutorial.

1.购买服务器

阿里云:

服务器购买地址

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=201905

2.部署教程

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

3.代码如下

# -*- coding: utf-8 -*-
import osimport reimport sysimport timefrom dataclasses import dataclassfrom typing import OptionalListTuple
from playwright.sync_api import sync_playwright, Page, TimeoutError as PWTimeoutError

@dataclassclass Config:    base_url: str = "https://www.101jiajiao.com/"    login_url: str = "https://www.101jiajiao.com/login.htm"    username_env: str = "JIAJIAO_USERNAME"    password_env: str = "JIAJIAO_PASSWORD"
    # 浏览器行为    headless: bool = True    slow_mo_ms: int = 0    nav_timeout_ms: int = 35_000    action_timeout_ms: int = 15_000
    # 站点可能的"登录后页面/会员中心"候选(不同账号类型可能不同)    member_candidates: Tuple[str, ...] = (        "https://www.101jiajiao.com/",        "https://www.101jiajiao.com/user/",        "https://www.101jiajiao.com/member/",        "https://www.101jiajiao.com/my/",        "https://www.101jiajiao.com/center/",        "https://www.101jiajiao.com/ucenter/",    )
    # "签到"可能出现的关键词(按钮/链接/菜单)    checkin_keywords: Tuple[str, ...] = ("签到""打卡""任务""积分""每日""福利")

class Jiajiao101Checkin:    def __init__(self, cfg: Config):        self.cfg = cfg        self.username = os.getenv(cfg.username_env, "").strip()        self.password = os.getenv(cfg.password_env, "").strip()
        if not self.username or not self.password:            raise RuntimeError(                f"缺少账号密码环境变量:{cfg.username_env}/{cfg.password_env},请先设置后再运行。"            )
    # ------------------------- 主流程 -------------------------    def run(self) -> None:        with sync_playwright() as p:            browser = p.chromium.launch(headless=self.cfg.headless, slow_mo=self.cfg.slow_mo_ms)            context = browser.new_context(                locale="zh-CN",                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"                ),            )            page = context.new_page()            page.set_default_navigation_timeout(self.cfg.nav_timeout_ms)            page.set_default_timeout(self.cfg.action_timeout_ms)
            try:                self.open_login_page(page)                self.do_login(page)
                # 登录后:尝试进入"会员中心/个人中心"                self.goto_member_center(page)
                # 尝试执行签到                ok, msg = self.try_checkin(page)
                # 输出最终结果                print("=" * 80)                print(f"结果:{'✅ 成功' if ok else '⚠️ 未完成'}")                print(f"说明:{msg}")                print("=" * 80)
            finally:                context.close()                browser.close()
    # ------------------------- 页面动作 -------------------------    def open_login_page(self, page: Page) -> None:        page.goto(self.cfg.login_url, wait_until="domcontentloaded")        self._sleep(0.8)
    def do_login(self, page: Page) -> None:        """        101家教网登录页是传统表单样式,但页面结构可能因城市分站或版本变化而不同;        因此采用"多策略定位输入框 + 回车/点击提交按钮"的方式。        """        # 可能出现:input[type=text] / input[name=username] / id=... 等不固定        user_locators = [            "input[name='username']",            "input[name='user']",            "input[name='loginname']",            "input[type='text']",            "input[placeholder*='用户名']",            "input[placeholder*='手机号']",            "input[placeholder*='邮箱']",        ]        pass_locators = [            "input[name='password']",            "input[type='password']",            "input[placeholder*='密码']",        ]
        user_el = self._first_visible(page, user_locators)        pass_el = self._first_visible(page, pass_locators)
        if not user_el or not pass_el:            # 截图/保留现场方便你排查            page.screenshot(path="101jiajiao_login_debug.png", full_page=True)            raise RuntimeError("未能在登录页定位到用户名/密码输入框(已保存截图 101jiajiao_login_debug.png)")
        user_el.fill(self.username)        pass_el.fill(self.password)
        # 提交:优先找"登录/登陆"按钮,否则回车        submit_locators = [            "button:has-text('登录')",            "button:has-text('登陆')",            "input[type='submit']",            "a:has-text('登录')",            "a:has-text('登陆')",        ]        submit_el = self._first_visible(page, submit_locators)
        if submit_el:            submit_el.click()        else:            pass_el.press("Enter")
        # 等待跳转/刷新(如果站点不跳转,也至少等待网络空闲)        try:            page.wait_for_load_state("networkidle", timeout=20_000)        except PWTimeoutError:            pass
        # 如果出现验证码/二次验证,提示人工处理        if self._maybe_captcha_or_2fa(page):            print("⚠️ 检测到可能存在验证码/二次验证,请在弹出的浏览器中手动完成后再继续…")            # 如果你把 headless=False,就能手动点            # 这里给 60 秒人工处理窗口(可按需改)            self._countdown(60)
        # 简单判断是否登录成功:页面出现"退出/个人中心/会员中心"等字样        html = page.content()        if not re.search(r"(退出|个人中心|会员中心|我的|我的简历)", html):            # 不一定失败(可能跳到分站/城市页),再给一次缓冲            self._sleep(1.5)
    def goto_member_center(self, page: Page) -> None:        """        登录成功后,尽可能进入"会员中心/我的"页面        """        # 先尝试点页面上的"会员登录/个人中心/我的"        possible_nav = [            "a:has-text('个人中心')",            "a:has-text('会员中心')",            "a:has-text('我的')",            "a:has-text('简历')",        ]        nav_el = self._first_visible(page, possible_nav, strict=False)        if nav_el:            try:                nav_el.click()                page.wait_for_load_state("domcontentloaded", timeout=10_000)                return            except Exception:                pass
        # 再尝试候选URL逐个访问        for url in self.cfg.member_candidates:            try:                page.goto(url, wait_until="domcontentloaded")                self._sleep(0.6)                # 只要页面能打开且不是明显回到登录页,就认为可用                if "login" not in page.url and "login.htm" not in page.url:                    return            except Exception:                continue
    def try_checkin(self, page: Page) -> Tuple[boolstr]:        """        执行"签到":        - 先找明显的"签到/打卡"按钮        - 再找"任务/积分/福利"等入口进入后再找"签到"        - 找到就点击,并判断"已签到/签到成功"等结果        """        # 1) 直接在当前页找"签到/打卡"        if self._click_by_text(page, ["签到""打卡"]):            return self._verify_checkin_result(page)
        # 2) 进入任务/积分/福利后再找        if self._click_by_text(page, ["任务""积分""福利""每日"]):            self._sleep(1.2)            if self._click_by_text(page, ["签到""打卡"]):                return self._verify_checkin_result(page)
        # 3) 全页面扫描关键词按钮(更激进但通用)        if self._scan_and_click_keywords(page, list(self.cfg.checkin_keywords)):            return self._verify_checkin_result(page)
        return False"未在登录后的页面中发现明确的"签到/打卡/任务入口"。可能该站点无每日签到,或入口仅在APP/特定页面内。"
    # ------------------------- 辅助方法 -------------------------    def _first_visible(self, page: Page, selectors: List[str], strict: bool = True):        for sel in selectors:            try:                loc = page.locator(sel)                if loc.count() > 0:                    first = loc.first                    if first.is_visible():                        return first            except Exception:                continue        if strict:            return None        return None
    def _click_by_text(self, page: Page, texts: List[str]) -> bool:        for t in texts:            try:                btn = page.get_by_text(t, exact=False).first                if btn and btn.is_visible():                    btn.click()                    try:                        page.wait_for_load_state("domcontentloaded", timeout=8_000)                    except PWTimeoutError:                        pass                    return True            except Exception:                continue        return False
    def _scan_and_click_keywords(self, page: Page, keywords: List[str]) -> bool:        """        扫描页面上包含关键词的 a/button/div[role=button] 等可点击元素,找到就点。        """        candidates = [            "a",            "button",            "[role='button']",            "div",            "span",        ]        for kw in keywords:            for tag in candidates:                try:                    loc = page.locator(tag, has_text=kw)                    if loc.count() > 0:                        el = loc.first                        if el.is_visible():                            el.click()                            self._sleep(0.8)                            return True                except Exception:                    continue        return False
    def _verify_checkin_result(self, page: Page) -> Tuple[boolstr]:        """        通过页面文本粗判是否签到成功/已签到。        """        self._sleep(1.0)        content = page.content()
        success_patterns = [            r"(签到成功|打卡成功|已签到|今日已签到|签到完成)",            r"(获得|领取).{0,10}(积分|金币|经验|奖励|红包)",        ]        for ptn in success_patterns:            if re.search(ptn, content):                return True"检测到页面反馈:疑似已完成签到/已签到。"
        # 没匹配到也不一定失败(可能接口无提示),给出中性提示        page.screenshot(path="101jiajiao_checkin_result.png", full_page=True)        return True"已执行"签到/打卡"点击动作,但未在页面文本中匹配到明确成功提示(已保存截图 101jiajiao_checkin_result.png)。"
    def _maybe_captcha_or_2fa(self, page: Page) -> bool:        """        粗略判断是否出现验证码/二次验证提示(不做破解,保留人工处理)。        """        html = page.content()        return bool(re.search(r"(验证码|滑块|短信验证码|安全验证|Geetest|Tencent Captcha)", html, re.I))
    @staticmethod    def _sleep(sec: float) -> None:        time.sleep(sec)
    @staticmethod    def _countdown(seconds: int) -> None:        for i in range(seconds, 0, -1):            if i % 5 == 0 or i <= 5:                print(f"…等待你处理验证:剩余 {i}s")            time.sleep(1)

if __name__ == "__main__":    cfg = Config(        headless=False,   # 第一次建议 False,方便遇到验证码/跳转时你手工处理;稳定后可改 True        slow_mo_ms=50,    # 放慢一点更稳定,想更快可改 0    )    bot = Jiajiao101Checkin(cfg)    bot.run()
解析
该脚本为101家教网自动签到脚本,主要作用包括:
  • 自动打开 101家教网登录页并登录账号

  • 登录后尽可能进入会员中心/我的页面

  • 自动在页面中寻找"签到/打卡/任务/积分/福利"等入口并点击

  • 如果遇到验证码/二次验证提示你手动处理(不做破解,更安全也更通用)

  • 最终输出签到执行结果,并在关键阶段保存截图便于排查

主要方法

  • run:脚本总入口,负责启动浏览器、串联登录→进入个人中心→执行签到→输出结果并关闭资源。

  • open_login_page:打开 101 家教网登录页面并等待基础加载完成。

  • do_login:定位用户名/密码输入框并提交登录;检测验证码/二次验证并留出手工处理时间;做基础"疑似登录成功"判断。

  • goto_member_center:尝试点击页面"个人中心/会员中心/我的"等入口;若找不到则轮询多个候选个人中心 URL。

  • try_checkin:执行签到主逻辑:先找"签到/打卡",再进入"任务/积分/福利"等页面再找签到,最后全页面扫描关键词并点击。

  • _verify_checkin_result:点击签到后,通过页面文本匹配"签到成功/已签到/获得积分"等关键字判断结果;匹配不到会截图并返回中性成功提示。

  • _first_visible:从多个 CSS 选择器中找到第一个可见元素(用于适配页面结构变化)。

  • _click_by_text:按文本模糊匹配点击元素(如"签到/任务/积分"),并等待页面加载。

  • _scan_and_click_keywords:全页面扫描包含关键词的可点击元素(a/button/div等),找到就点击(更通用但更"激进")。

  • _maybe_captcha_or_2fa:粗判页面是否出现验证码/短信验证等提示(不破解,仅提示人工处理)。


注意

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


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

没有评论:

发表评论

《尼日利亚外贸收款难题与WindPayer离岸账户解决方案》

尼日利亚外贸面临奈拉波动、美元短缺和银行审查严三大难题。传统方式成本高、周期长、风险大。企业可选用WindPayer等持牌平台在线开设离岸账户,快速收取奈拉并转为人民币回国,流程简便、手续费低、无结汇限制。 尼日利亚奈拉汇率波动大、美元长期短缺、银行审查严,这一直是尼日利亚做...