在 Linux 服务器上跑自动签到脚本:API 直连 + 多账号 + 飞书推送
⚡ 效率提升 🤖 自动化脚本 ubuntu 脚本 自动化 python 26

TL;DR:手里有台 24 小时在线的 Linux 小鸡,却还在每天手动点网页签到?这篇用纯 Python(只依赖 requests)直接打 API 完成登录+签到,支持多账号、带飞书加签卡片推送,1 核 512M 也能秒级跑完。核心难点是网站的 FingerprintJS 浏览器指纹——用「抓一次、长期复用」绕过。脚本可直接抄。

为什么不用 Selenium

很多签到教程让你上 Selenium 模拟浏览器,但它太吃内存,无头(Headless)模式还容易报错,在小内存 VPS 上很难受。

我的做法是直接模拟 API 请求:抓清楚登录/签到接口要哪些字段,用 requests 构造 HTTP 请求发过去。好处很直接:

  • 资源占用极低(几 MB 内存)
  • 速度快(秒级完成)
  • 稳定(不受网页加载影响)

唯一的小坎是网站用了 FingerprintJS(浏览器指纹)做风控。但指纹只要环境不变就基本固定,所以抓一次、长期复用即可。

第一步:抓到关键的 Fingerprint

这步最关键。因为登录成功后页面会瞬间跳转,普通抓包根本看不清,得讲点顺序:

🚨 严格按顺序操作,顺序错了就抓不到。

  1. 用电脑浏览器(Chrome/Edge)打开登录页。
  2. F12 打开开发者工具,切到 Network(网络) 面板。
  3. 确保左上角圆点是红色(正在录制)。
  4. 务必勾选 "Preserve log"(保留日志)——防止页面跳转后登录请求被清空,这是最容易漏的一步。
  5. "Fetch/XHR" 筛选,只看数据请求。
  6. 输入账号密码,点登录
  7. 列表里会出现名为 login(或 auth/login)的请求,点开它,在右侧 Payload 里找到 fingerprint,把那串长字符复制下来备用。

第二步:准备配置文件

为了安全,账号密码和代码分开。在服务器上建个目录,比如 /root/scripts/neworld/,创建 config.json

{
  "url_base": "https://neworld.cloud",
  "feishu": {
    "enable": true,
    "webhook": "https://open.feishu.cn/open-apis/bot/v2/hook/你的Webhook地址",
    "secret": "你的加签密钥(在飞书机器人安全设置里看)"
  },
  "accounts": [
    {
      "email": "user1@gmail.com",
      "password": "mypassword123",
      "fingerprint": "这里填刚刚抓到的那一串字符_1",
      "note": "我的主力号"
    },
    {
      "email": "user2@qq.com",
      "password": "mypassword456",
      "fingerprint": "这里填刚刚抓到的那一串字符_2",
      "note": "我的小号"
    }
  ]
}

💡 多账号就在 accounts 里复制粘贴大括号块,想加几个加几个。

第三步:部署核心脚本

脚本集成了三块:飞书 HmacSHA256 加签每账号独立 Session(会话隔离)顺序执行、以及飞书卡片生成。先装依赖:

pip install requests

创建 auto_sign.py

# -*- coding: utf-8 -*-
import requests, json, logging, time, random, os, hashlib, base64, hmac

# ==================== 基础配置 ====================
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
CONFIG_FILE = os.path.join(BASE_DIR, 'config.json')
LOG_FILE = os.path.join(BASE_DIR, 'sign_task.log')

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', filename=LOG_FILE, filemode='a')
console = logging.StreamHandler()
logging.getLogger('').addHandler(console)

# ==================== 飞书签名算法 ====================
def gen_sign(timestamp, secret):
    string_to_sign = '{}\n{}'.format(timestamp, secret)
    hmac_code = hmac.new(string_to_sign.encode("utf-8"), digestmod=hashlib.sha256).digest()
    return base64.b64encode(hmac_code).decode('utf-8')

# ==================== 发送飞书美化卡片 ====================
def send_feishu_card(config, results):
    feishu = config.get('feishu', {})
    if not feishu.get('enable'): return

    timestamp = str(int(time.time()))
    sign = gen_sign(timestamp, feishu['secret']) if feishu.get('secret') else ""

    # 构建卡片元素
    elements = [{"tag": "div", "text": {"tag": "lark_md", "content": f"📅 **执行时间**: {time.strftime('%Y-%m-%d %H:%M:%S')}"}}, {"tag": "hr"}]

    for res in results:
        status_icon = "🟢" if res['login'] else "🔴"
        # 结果图标逻辑:成功🎉 / 重复🔁 / 失败📝
        msg_icon = "🎉" if "成功" in res['msg'] else ("🔁" if "已经" in res['msg'] else "📝")

        elements.append({
            "tag": "div",
            "text": {"tag": "lark_md", "content": f"👤 **{res['name']}**\n{status_icon} {'登录成功' if res['login'] else '登录失败'} | {msg_icon} {res['msg']}"}
        })
        elements.append({"tag": "hr"})

    elements.append({"tag": "note", "elements": [{"tag": "plain_text", "content": "来自 Linux 最强自动签到脚本"}]})

    payload = {
        "timestamp": timestamp, "sign": sign, "msg_type": "interactive",
        "card": {"config": {"wide_screen_mode": True}, "header": {"template": "blue", "title": {"content": "☁️ 新界云 自动签到报告", "tag": "plain_text"}}, "elements": elements}
    }
    try:
        requests.post(feishu['webhook'], json=payload)
        logging.info("🔔 飞书通知已发送")
    except Exception as e:
        logging.error(f"🔔 发送失败: {e}")

# ==================== 机器人逻辑 ====================
class Bot:
    def __init__(self, acc, url):
        self.acc, self.url = acc, url
        self.sess = requests.Session()
        self.sess.headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/115.0.0.0 Safari/537.36", "Content-Type": "application/json", "Origin": url, "Referer": f"{url}/auth/login"})

    def run(self):
        res = {"name": self.acc.get('note', self.acc['email']), "login": False, "msg": "未执行"}
        try:
            # 1. 登录
            logging.info(f"[{res['name']}] 正在登录...")
            login_resp = self.sess.post(f"{self.url}/auth/login", data=json.dumps({
                "email": self.acc['email'], "passwd": self.acc['password'], "fingerprint": self.acc['fingerprint'], "code": "", "remember_me": "false"
            }), timeout=15).json()

            if login_resp.get("ret") == 1:
                res['login'] = True
                time.sleep(random.uniform(2, 5)) # 模拟人类延迟
                # 2. 签到
                self.sess.headers.update({"Referer": f"{self.url}/user"})
                check_resp = self.sess.post(f"{self.url}/user/checkin", timeout=15).json()
                res['msg'] = check_resp.get('msg', '未知返回')
                logging.info(f"[{res['name']}] ✅ 结果: {res['msg']}")
            else:
                res['msg'] = f"登录失败: {login_resp.get('msg')}"
                logging.error(f"[{res['name']}] ❌ {res['msg']}")
        except Exception as e:
            res['msg'] = f"异常: {str(e)}"
            logging.error(f"[{res['name']}] 💥 {res['msg']}")
        return res

def main():
    logging.info("🚀 任务启动")
    if not os.path.exists(CONFIG_FILE): return logging.error("找不到配置文件")
    with open(CONFIG_FILE, 'r', encoding='utf-8') as f: config = json.load(f)

    results = []
    for i, acc in enumerate(config.get('accounts', [])):
        results.append(Bot(acc, config['url_base']).run())
        if i < len(config['accounts']) - 1: time.sleep(random.randint(5, 10)) # 多号间隔防止封IP

    send_feishu_card(config, results)
    logging.info("🏁 任务结束")

if __name__ == "__main__":
    main()

几个值得留意的设计点:

  • 飞书加签gen_sign 按飞书要求用 timestamp\nsecret 做 HmacSHA256 再 base64,对应机器人「加签」安全模式。
  • 顺序执行 + 随机间隔:多账号是 for 循环依次跑的(不是多线程),每个账号一个独立 requests.Session,账号之间 sleep(5~10) 随机间隔降低风控风险。
  • 登录判据:接口返回 ret == 1 视为登录成功,再带着同一 Session 去打 /user/checkin

第四步:挂上定时任务(crontab)

让它每天 8:30 自动跑。crontab -e 加一行:

# 每天 08:30 运行
30 8 * * * /usr/bin/python3 /root/scripts/neworld/auto_sign.py

效果

每天早上飞书会收到这样一张卡片:

☁️ 新界云 自动签到报告 📅 执行时间: 2026-01-23 08:30:15 ────────────────────── 👤 我的主力号 🟢 登录成功 | 🎉 签到成功 (获得 500MB) ────────────────────── 👤 我的小号 🟢 登录成功 | 🔁 今天已经签到过了

常见问题(FAQ)

Q:Fingerprint 会过期吗? A:基本不会。只要那台电脑硬件和浏览器不升级,指纹就固定。我实测用了一年都没变。

Q:日志提示「环境异常」? A:极少数情况。可能是脚本里写的 User-Agent 和你抓指纹时的浏览器差太多。把脚本里的 User-Agent 换成你自己抓包看到的那个即可。

Q:配置文件安全吗? A:建议 chmod 600 config.json,只有你自己能读,防止同机其他用户偷看密码。

小结

整套方案的核心就一句话:与其模拟浏览器,不如直接打 API——前提是花点功夫把 fingerprint 抓出来复用。配好之后挂 crontab,服务器替你每天签到,结果直接推到飞书。这类「让 24 小时在线的机器替你打工」的玩法,前提通常是能远程管到那台机器——如果你也在折腾内网设备,可以看看我另一篇 用 FRP 给内网设备做 SSH 穿透

在 Linux 服务器上跑自动签到脚本:API 直连 + 多账号 + 飞书推送
http://localhost:8090/archives/linux-auto-checkin-feishu
作者
fnidore
发布于
更新于
许可