1.购买服务器阿里云:服务器购买地址https://t.aliyun.com/U/DT4XYh若失效,可用地址
阿里云:
服务器购买地址
https://t.aliyun.com/U/DT4XYh
若失效,可用地址
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=201905
2.部署教程
3.代码如下
# cron:10 0 * * *
# new Env('NodeSeek签到');
import base64
import hashlib
import hmac
import os
import random
import time
import urllib.parse
import cloudscraper
# ==============================================
# 初始化cloudscraper
# ==============================================
# 获取代理环境变量
proxies = []
NS_PROXIES = os.environ.get("NS_PROXIES", None)
if NS_PROXIES:
proxies = [proxy for proxy in NS_PROXIES.split(",")]
# cloudscraper基础配置
scraper = cloudscraper.create_scraper(
# 代理配置
rotating_proxies=proxies,
proxy_options={"rotation_strategy": "smart", "ban_time": 300},
# 基础配置
interpreter="js2py",
delay=6,
enable_stealth=True,
stealth_options={
"min_delay": 5.0,
"max_delay": 10.0,
"human_like_delays": True,
"randomize_headers": True,
"browser_quirks": True,
},
# Browser emulation
browser="chrome",
# Debug mode
debug=False,
)
# ==============================================
# 配置区域 (Configuration Section)
# 所有配置通过环境变量获取,便于青龙面板管理
# ==============================================
# NodeSeek环境变量
## 获取NodeSeek Cookie环境变量
NS_COOKIE = os.environ.get("NS_COOKIE", "")
## NodeSeek签到模式:true->随机签到 false->固定签到,默认随机签到
NS_RANDOM = os.environ.get("NS_RANDOM", "true")
## NodeSeek成员ID,https://www.nodeseek.com/space/26589 ->26589就是成员ID
NS_MEMBER_ID = os.environ.get("NS_MEMBER_ID", "")
# 钉钉机器人通知(本地运行,直接填写下面三个环境变量即可)
## 本地运行请给为True,默认为False,调用青龙系统通知API
DD_BOT_ENABLE = False
## 钉钉机器人Token,access_token=XXX 等于=符号后面的XXX即可
DD_BOT_TOKEN = os.environ.get("DD_BOT_TOKEN", "")
## 钉钉机器人Secret
DD_BOT_SECRET = os.environ.get("DD_BOT_SECRET", "")
# ==============================================
# 工具函数 (Utility Functions)
# ==============================================
# 随机等待
def wait_random_interval(min_seconds, max_seconds):
"""等待min_seconds到max_seconds之间的随机时长"""
delay = random.uniform(min_seconds, max_seconds)
print(f"等待 {delay:.2f} 秒后继续...")
time.sleep(delay)
print("执行下一步操作!")
# ==============================================
# 核心功能 (Core Functions)
# ==============================================
# NodeSeek用户信息,不设置NodeSeek成员ID则不显示
def ns_info(ns_member_id):
"""
获取NodeSeek用户信息
:param ns_member_id: 用户ID
:return: 格式化后的用户信息字符串
"""
if not ns_member_id:
print(
"未设置NodeSeek成员ID,请检测NS_MEMBER_ID环境变量设置是否正确,跳过NodeSeek用户信息获取"
)
return ""
url = f"https://www.nodeseek.com/api/account/getInfo/{ns_member_id}?readme=1"
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Origin": "https://www.nodeseek.com",
"Referer": "https://www.nodeseek.com/space/{ns_member_id}",
"Sec-CH-UA": '"Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"',
"Sec-CH-UA-Mobile": "?0",
"Sec-CH-UA-Platform": '"Windows"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
}
try:
response = scraper.get(url, headers=headers)
# 示例:{'success': True, 'detail': {'member_id': 26589, 'member_name': 'WG', 'isAdmin': 0, 'rank': 1, 'coin': 226, 'bio': '技术宅拯救世界!', 'created_at': '2025-02-02T05:52:33.000Z', 'nPost': 0, 'nComment': 5, 'follows': 0, 'fans': 0, 'created_at_str': '99days ago', 'roles': []}}
data = response.json()
ns_user_data = data["detail"]
return f"用户信息:\n【用户】:{ns_user_data['member_name']}\n【等级】:{ns_user_data['rank']}\n【鸡腿数目】:{ns_user_data['coin']}\n【主题帖数】:{ns_user_data['nPost']}\n【评论数】:{ns_user_data['nComment']}"
except Exception as e:
print("NodeSeek用户信息获取失败,错误信息: ", str(e))
return "用户信息报错:NodeSeek用户信息获取失败,请检查成员ID是否正确"
# NodeSeek签到
def ns_signin(ns_cookie, ns_random="true"):
"""
NodeSeek签到函数
:param ns_cookie: 用户Cookie
:param ns_random: 是否随机签到
:return: 签到结果信息
"""
if not ns_cookie:
print("未设置NodeSeek Cookie,请检查NS_COOKIE环境变量设置是否正确")
return "签到失败:未设置NodeSeek Cookie,请检查NS_COOKIE环境变量设置是否正确"
url = f"https://www.nodeseek.com/api/attendance?random={ns_random}"
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Content-Length": "0",
"Origin": "https://www.nodeseek.com",
"Referer": "https://www.nodeseek.com/board",
"Sec-CH-UA": '"Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"',
"Sec-CH-UA-Mobile": "?0",
"Sec-CH-UA-Platform": '"Windows"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
"Cookie": ns_cookie,
}
try:
response = scraper.post(url, headers=headers)
# 示例:{'success': False, 'message': '今天已完成签到,请勿重复操作'}
data = response.json()
msg = data.get("message", "")
return f"签到信息:{msg}"
except Exception as e:
print("NodeSeek签到报错,错误信息: ", str(e))
return "签到报错:NodeSeek签到报错,请检查Cookie是否正确"
# 消息推送到钉钉
def send_to_dingtalk(token, secret, message):
"""
发送消息到钉钉机器人
:param token: 机器人Token
:param secret: 机器人Secret
:param message: 要发送的消息
"""
if not token: # 只有配置了钉钉token才推送
print("未配置钉钉机器人,跳过消息推送")
return
# 生成时间戳和签名
timestamp = str(round(time.time() * 1000))
secret_enc = secret.encode("utf-8")
string_to_sign = f"{timestamp}\n{secret}"
string_to_sign_enc = string_to_sign.encode("utf-8")
hmac_code = hmac.new(
secret_enc, string_to_sign_enc, digestmod=hashlib.sha256
).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
# 生成请求URL
url = f"https://oapi.dingtalk.com/robot/send?access_token={token}×tamp={timestamp}&sign={sign}"
headers = {"Content-Type": "application/json"}
data = {
"msgtype": "text",
"text": {"content": f"「NodeSeek签到」\n{message}"},
}
response = scraper.post(url, json=data, headers=headers)
if response.status_code == 200:
print("消息推送成功:", response)
else:
print("消息推送失败:", response)
# 消息推送(调用的是青龙系统通知API)
def message_push(title, message):
"""
消息推送通知
:param title: 消息标题
:param message: 消息内容
"""
response = QLAPI.systemNotify({"title": title, "content": message})
if response.get("code", 400) == 200:
print("消息推送成功:", response)
else:
print("消息推送失败:", response)
# ==============================================
# 主程序入口 (Main Entry)
# ==============================================
if __name__ == "__main__":
wait_random_interval(5, 20) # 随机等待10-20秒
print("===========================正在进行NodeSeek签到==========================")
# 示例输出:签到信息:今天已完成签到,请勿重复操作
try:
ns_signin_data = ns_signin(NS_COOKIE, NS_RANDOM)
print(ns_signin_data)
except Exception as e:
ns_signin_data = "NodeSeek签到报错:NodeSeek签到失败,请检查Cookie是否正确或者失效,官网是否加强Cloudflare。"
print("NodeSeek签到报错,错误信息: ", str(e))
print(ns_signin_data)
wait_random_interval(5, 20) # 随机等待10-20秒
print("=========================正在获取NodeSeek用户信息=========================")
# 示例输出:用户信息:\n【用户】:WG\n【等级】:1\n【鸡腿数目】:226\n【主题帖数】:0\n【评论数】:5
try:
ns_info_data = ns_info(NS_MEMBER_ID)
print(ns_info_data)
except Exception as e:
ns_info_data = "NodeSeek用户信息获取失败:请检查成员ID是否正确。"
print("NodeSeek用户信息获取失败,错误信息: ", str(e))
print(ns_info_data)
print("=========================正在推送NodeSeek签到信息=========================")
try:
content = f"{str(ns_info_data)}\n{str(ns_signin_data)}\n时间:{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}"
if DD_BOT_ENABLE:
send_to_dingtalk(DD_BOT_TOKEN, DD_BOT_SECRET, content)
else:
message_push("「NodeSeek签到」", content)
except Exception as e:
print("推送失败,错误信息: ", str(e))
print(
"1、本地运行:请检查DD_BOT_ENABLE、DD_BOT_TOKEN和DD_BOT_SECRET环境变量是否正确\n2、青龙面板:请检查青龙系统设置-》通知设置-》是否配置。"
)
print("=============================NodeSeek运行结束============================")
解析
该脚本为NodeSeek 论坛自动签到 脚本,主要作用:
通过
NS_COOKIE
执行每日签到(可随机或固定模式)。可选拉取指定成员(
NS_MEMBER_ID
)的用户信息(等级、鸡腿、发帖/评论数)。支持两类通知:
本地运行:钉钉机器人(
DD_BOT_TOKEN
/DD_BOT_SECRET
,开关DD_BOT_ENABLE=True
)。青龙面板:调用青龙系统通知 API(默认)。
内置 Cloudflare 反爬处理(
cloudscraper
+ 轮换代理)与人类化随机延时。
主要方法的作用
全局初始化(cloudscraper )
读取NS_PROXIES
(逗号分隔),构建cloudscraper
实例:启用轮换代理、智能延迟、伪装与浏览器仿真,提升在 Cloudflare 防护下的成功率。wait_random_interval(min_seconds, max_seconds)
在关键步骤间随机暂停(打印等待时长),降低自动化特征。ns_info(ns_member_id)
GEThttps://www.nodeseek.com/api/account/getInfo/{member_id}
拉取用户信息。
若没设置NS_MEMBER_ID
,直接跳过。返回格式化的"用户、等级、鸡腿、主题、评论"等字符串。ns_signin(ns_cookie, ns_random="true")
POSThttps://www.nodeseek.com/api/attendance?random={ns_random}
执行签到。
必须提供NS_COOKIE
;NS_RANDOM
控制是否随机签到位置。返回"今天已完成签到"等提示信息。send_to_dingtalk(token, secret, message)
本地运行用的钉钉机器人通知:用timestamp + secret
生成 HMAC-SHA256 签名,拼接 URL,发送文本消息。message_push(title, message)
青龙面板的系统通知调用封装(QLAPI.systemNotify
),推送签到结果与用户信息汇总。__main__
主流程随机等待 → 执行签到并打印结果;
再次随机等待 → 拉取用户信息并打印;
拼装汇总内容 → 根据运行环境选择钉钉或青龙通知;
打印结束标识。
需要的环境变量:
NS_COOKIE
(必填)、NS_RANDOM
(可选,默认 "true")、NS_MEMBER_ID
(可选)、NS_PROXIES
(可选,逗号分隔)、DD_BOT_TOKEN
/DD_BOT_SECRET
(本地钉钉通知可选),以及青龙环境自带的通知能力。
注意:
本文部分变量已做脱敏处理,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。技术层面需要提供帮助,可以通过打赏的方式进行探讨。
【相关文章】
没有评论:
发表评论