开源一个掘金自动签到的油猴脚本

引言

作为一名掘金的忠实用户,我每天打开网站的第一件事就是签到。最近在写小册《油猴脚本实战指南》的收尾章节---------如何将油猴脚本打包成原生谷歌插件 时,想着既然都提到提到谷歌插件开发了,于是顺手把 Chrome 插件的快速入门教程整理到小册里。

就是因为这几天持续的写作,居然连续忘了好几次掘金签到,难受!作为脚本开发者,这事儿不能忍,必须写一个掘金自动签到脚本干它!

脚本效果与使用方式

要使用这个脚本,必须先通过谷歌商店,下载油猴扩展插件。

如果你无法翻墙下载,可以加我,shc1139874527,群里有学习资料和油猴插件下载地址。

然后,就可以通过脚本地址安装插件并使用。

脚本使用非常简单,当你打开任意网页且掘金没有签到时,它就会自动帮你签到。如下图,当我打开百度页面时,自动打开掘金后台标签,签到完成后,后台标签关闭,首页进行了提示。

实现原理

技术栈

脚本的技术栈很简单,就是将一段签到脚本(javascript代码)通过油猴注入到网页中执行逻辑。

油猴 是一个谷歌扩展程序,你可以在Chrome应用商店中,搜索 "篡改猴"进行安装。

用户可以将自己编写的任何javascript脚本放在油猴中执行,从而实现网页加强的功能。此外,油猴还提供了一些API,实现了突破浏览器限制的JS能力,比如跨域请求无视CSP限制、后台打开标签等。

如果你对脚本开发感兴趣,不妨看看《油猴脚本实战指南》这本小册,目前7折,可冲。

脚本原理

脚本的原理其实非常简单,当用户打开任意网站后,脚本会利用油猴提供的 GM_openInTab API 打开掘金的签到页面:

js 复制代码
const targetPage = "https://juejin.cn/user/center/signin"; // 掘金签到页面地址
const bgTab = GM_openInTab(targetPage); 

在掘金签到页,脚本会通过获取签到按钮的Dom元素文本内容,判断用户是否签到。如果用户没有签到,脚本则模拟用户点击签到按钮。

js 复制代码
const signBtn = document.querySelector(".code-calender button.btn"); // 查找签到按钮
if (signBtn) {
  if (signBtn.innerText.includes("立即签到")) {
    signBtn.click(); // 模拟点击签到按钮
  }
}

完成签到后,脚本会自动关闭该标签页,并通过 GM_setValue 储存签到状态。这样,下一次用户访问其他网页时,脚本会先判断是否已经签过到,避免重复触发,提高效率。

完整代码

下面是脚本的完整代码,大家可以直接复制到油猴的脚本新建页面中使用。

js 复制代码
// ==UserScript==
// @name         掘金自动签到助手
// @namespace    http://tampermonkey.net/
// @version      0.0.1
// @description  掘金自动签到助手,后台打开标签页版本
// @author       石小石Orz
// @match        *://*/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_deleteValue
// @grant        GM_getTab
// @grant        GM_getTabs
// @grant        GM_saveTab
// @grant        GM_addElement
// @grant        unsafeWindow
// @grant        GM_openInTab
// @run-at       document-body
// @noframes
// ==/UserScript==

(async function () {
  "use strict";

  const targetPage = "https://juejin.cn/user/center/signin"; // 掘金签到页面地址
  const currentDate = new Date().toLocaleDateString(); // 获取当前日期(本地格式)
  const storedDate = GM_getValue("signTime", ""); // 读取上次签到的日期(默认空字符串)

  // 如果已经签到(存储的日期和今天一样),终止脚本执行
  if (storedDate === currentDate) return;

  // 显示签到成功提示框
  function showSuccessMessage(text = "掘金自动签到成功", duration = 3000) {
    const el = GM_addElement(document.body, "div", {
      textContent: text,
      style: `
            position: fixed;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            background-color: #DAF7E1;
            color: #0C9B4A;
            padding: 10px 16px;
            font-size: 14px;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
            z-index: 99999;
            opacity: 0;
            transition: opacity 0.3s ease, transform 0.3s ease;
          `,
    });

    // 动画效果:渐显+下移
    requestAnimationFrame(() => {
      el.style.opacity = "1";
      el.style.transform = "translateX(-50%) translateY(10px)";
    });

    // 指定时间后自动移除提示框
    setTimeout(() => {
      el.style.opacity = "0";
      el.style.transform = "translateX(-50%) translateY(0)";
      setTimeout(() => el.remove(), 300);
    }, duration);
  }

  //   尝试执行签到操作(仅在签到页使用)
  const trySignIn = (close) => {
    unsafeWindow.addEventListener("load", () => {
      setTimeout(() => {
        const signBtn = document.querySelector(".code-calender button.btn"); // 查找签到按钮
        if (signBtn) {
          if (signBtn.innerText.includes("立即签到")) {
            signBtn.click(); // 模拟点击签到按钮
          }
          // 无论是否签到成功,都保存当前日期作为签到日期
          GM_setValue("signTime", currentDate);
          close && window.close();
        }
      }, 1000);
    });
  };

  // 获取当前标签页对象与所有已知标签页
  const [tab, tabs] = await Promise.all([GM.getTab(), GM.getTabs()]);

  // 判断是否已有"主页面"存在(主页面用于协调多个标签页避免重复签到)
  const hasMainPage = Object.values(tabs).some((t) => t?.isMainPage);

  // 如果没有主页面
  if (!hasMainPage) {
    if (location.href.startsWith(targetPage)) {
      // 当前页面就是签到页,直接尝试签到
      trySignIn();
    } else {
      // 当前不是签到页,将本标签页设为主页面,并在后台打开签到页面
      tab.isMainPage = true;
      await GM.saveTab(tab);
      const bgTab = GM_openInTab(targetPage); // 打开后台签到页面
      bgTab.onclose = () => {
        showSuccessMessage(); // 签到页关闭后显示提示
      };
    }
  } else {
    // 如果已有主页面,仅在签到页执行签到逻辑
    if (location.href.startsWith(targetPage)) {
      trySignIn(!tab?.isMainPage); // 主页面不关闭,其他页面签到完关闭
    } else {
      // 非签到页,重复打开一个签到页面进行操作
      const bgTab = GM_openInTab(targetPage);
      bgTab.onclose = () => {
        showSuccessMessage(); // 签到页关闭后显示提示
      };
    }
  }
})();

上述代码中,使用了一些GM_setValueGM_getTabGM_addElementGM_openInTab等一些油猴的API能力,其余代码和普通前端代码是没有任何差异的。

这些API小册中有详细介绍,你也可以参考官方API文档学习。

总结

这篇文章给大家带来了一个非常实用的油猴脚本------掘金自动签到,有需求的同学还不快用起来!JYM,快成为矿石大亨!

油猴脚本开发对前端同学来说非常容易入门,感兴趣的同学可以去学习哇!

相关推荐
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax