1.购买服务器阿里云:服务器购买地址https://t.aliyun.com/U/PfsP97若失效,可用地址
阿里云:
服务器购买地址
https://t.aliyun.com/U/PfsP97若失效,可用地址
https://www.aliyun.com/activity/wuying/dj?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.代码如下
// 飞牛社区自动签到脚本const axios = require('axios');const cheerio = require('cheerio');const notify = require('./sendNotify'); // 青龙面板内置通知函数// 从环境变量获取完整Cookie字符串const fullCookieString = process.env.FN_COOKIE || '';/*** 获取动态的sign参数[3](@ref)* @returns {Promise<string>} 动态的sign参数值*/async function getDynamicSign() {try {console.log('开始获取动态sign参数...');const response = await axios.get('https://club.fnnas.com/plugin.php?id=zqlj_sign', {headers: {'Cookie': fullCookieString,'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'}});const $ = cheerio.load(response.data);// 尝试从签到按钮的链接中提取sign参数[3](@ref)const signLink = $('a.btna').attr('href');if (!signLink) {throw new Error('无法从页面中找到签到链接(可能Cookie失效或页面改版)');}const signMatch = signLink.match(/sign=([a-f0-9]+)/);if (signMatch && signMatch[1]) {console.log('动态sign参数获取成功:', signMatch[1]);return signMatch[1];} else {throw new Error('从签到链接中提取sign参数失败');}} catch (error) {console.error('日志信息 获取动态sign参数失败:', error.message);await notify.sendNotify('飞牛签到失败', `获取动态sign参数失败: ${error.message}`);throw error; // 重新抛出错误,阻止后续签到执行}}/*** 执行签到操作* @param {string} dynamicSign 动态获取的sign参数*/async function signIn(dynamicSign) {try {const signUrl = `https://club.fnnas.com/plugin.php?id=zqlj_sign&sign=${dynamicSign}`;console.log(' 发送签到请求:', signUrl);const response = await axios.get(signUrl, {headers: {'Cookie': fullCookieString,'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'}});if (response.data.includes('恭喜您,打卡成功!')) {console.log(' 打卡成功');await getSignInInfo(); // 获取并推送签到详情} else if (response.data.includes('您今天已经打过卡了')) {console.log(' 已经打过卡了');await notify.sendNotify('飞牛论坛', '您今天已经打过卡了'); // 推送已签到通知} else {// 可能的情况:Cookie失效、签到链接错误、网站改版const errorMsg = '打卡失败, cookies可能已经过期或站点更新.';console.log('日志信息', errorMsg);await notify.sendNotify('飞牛论坛', errorMsg);}} catch (error) {console.error('日志信息 签到请求失败:', error.message);await notify.sendNotify('飞牛论坛', `签到请求失败: ${error.message}`);}}/*** 获取签到详情信息并推送[1,3](@ref)*/async function getSignInInfo() {try {console.log(' 获取签到详情信息...');const response = await axios.get('https://club.fnnas.com/plugin.php?id=zqlj_sign', {headers: {'Cookie': fullCookieString,'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'}});const $ = cheerio.load(response.data);const content = []; // 存储提取的签到信息// 定义要提取的信息项及其选择器[1](@ref)const patterns = [{ name: '最近打卡', selector: 'li:contains("最近打卡")' },{ name: '本月打卡', selector: 'li:contains("本月打卡")' },{ name: '连续打卡', selector: 'li:contains("连续打卡")' },{ name: '累计打卡', selector: 'li:contains("累计打卡")' },{ name: '累计奖励', selector: 'li:contains("累计奖励")' },{ name: '最近奖励', selector: 'li:contains("最近奖励")' },{ name: '当前打卡等级', selector: 'li:contains("当前打卡等级")' }];// 提取数据patterns.forEach(pattern => {const elementText = $(pattern.selector).text();if (elementText) {// 提取冒号后的值部分[3](@ref)const value = elementText.replace(/.*:/, '').trim(); // 注意正则表达式修改,匹配中文冒号content.push(`${pattern.name}: ${value}`);}});if (content.length > 0) {const message = content.join('\n');console.log(' 签到详情:\n' + message);// 推送签到成功及详情[1](@ref)await notify.sendNotify('飞牛论坛打卡成功', message);} else {throw new Error('未找到签到详情信息,页面结构可能已变更');}} catch (error) {console.error(' 获取打卡信息失败:', error.message);await notify.sendNotify('飞牛论坛', `获取打卡信息失败: ${error.message}`);}}/*** 主执行函数*/async function main() {console.log(' 开始执行飞牛社区自动签到任务...');console.log(' 当前时间:', new Date().toLocaleString('zh-CN'));// 1. 检查Cookie是否配置if (!fullCookieString) {const errorMsg = '未设置环境变量 FN_COOKIE,请先在青龙面板中配置。';console.error('', errorMsg);await notify.sendNotify('飞牛签到配置错误', errorMsg);return;}console.log(' FN_COOKIE 环境变量已设置');try {// 2. 动态获取sign参数[3](@ref)const dynamicSign = await getDynamicSign();// 3. 执行签到await signIn(dynamicSign);} catch (error) {// getDynamicSign 中的错误已处理,此处捕获其他潜在错误console.error(' 任务执行过程中发生未预期错误:', error.message);} finally {console.log(' 任务执行完毕。');}}// 执行主函数main();
解析
该脚本为飞牛社区自动签到脚本,主要作用包括:
自动完成飞牛社区(club.fnnas.com)每日签到:
通过携带环境变量里的 FN_COOKIE(完整 Cookie)访问签到页面,先抓取当日动态 sign 参数,再构造签到请求完成打卡。结果通知:
结合青龙面板的sendNotify,在成功、已签或失败等场景推送消息(如"打卡成功/已打过/失败原因"等)。
关键依赖 & 配置
依赖:
axios(HTTP 请求)、cheerio(HTML 解析)、sendNotify(青龙通知)。环境变量:
FN_COOKIE(必须),为飞牛社区的完整 Cookie 字符串。
主要方法作用
getDynamicSign()访问签到页
plugin.php?id=zqlj_sign,解析 HTML。用
cheerio找到签到按钮链接a.btna的href,从中提取当日动态 sign 参数(正则匹配sign=xxxx)。失败会调用通知并抛错,阻止后续流程。
signIn(dynamicSign)包含"恭喜您,打卡成功!"→ 视为成功,并调用
getSignInInfo()拉取详情并通知。包含"您今天已经打过卡了"→ 推送"已签到"通知。
否则视为失败(可能 Cookie 失效、站点改版或 sign 错误)并通知。
以
https://club.fnnas.com/plugin.php?id=zqlj_sign&sign=${dynamicSign}
发送 GET 请求完成签到。
根据返回页面内容判断:
getSignInInfo()再次访问签到页,抽取打卡统计信息,如:最近打卡、本月打卡、连续打卡、累计打卡、累计/最近奖励、当前打卡等级等。
解析方式:用选择器定位
li,把文本中冒号后的值提取出来,拼成多行消息,通过通知推送。若页面结构变更导致解析不到信息,会通知失败。
main()(主流程)检查
FN_COOKIE是否存在;调用
getDynamicSign()拿到 sign;用
signIn(sign)完成签到;全程日志输出,结束后打印"任务执行完毕"。
运行流程概览
读取环境变量
FN_COOKIE。抓签到页 → 解析签到链接 → 提取 sign。
带
sign访问签到接口 → 判断结果:成功/已签/失败。成功则抓取并推送签到详情;其他情况推送错误或已签通知。
常见失败原因(脚本内已有处理/提示)
Cookie 过期/错误(未登陆态)。
页面结构调整(找不到签到链接或统计信息)。
sign 规则变化或接口调整。
注意:
本文部分变量已做脱敏处理,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。技术层面需要提供帮助,可以通过打赏的方式进行探讨。
【相关文章】
没有评论:
发表评论