首先麻烦务必看下原大佬的原帖的配置,我这里省略了主要步骤,主要提供修改后的代码:
前言:由于本人水平有限,只能看代码和改代码,不会自己无中生有的编代码(很慢),所以尝试了眼下最近大火的deepseek满血版。
修改内容如下:
1.原本的环境变量fn_pvRK_2132_saltkey、fn_pvRK_2132_auth、fn_pvRK_2132_sign的前两个都是cookie的一部分,所以合并为一个环境变量FN_COOKIE,这样无论你是新配置还是改配置,都只需要复制飞牛论坛的cookie的完整cookie即可。环境变量设置方式见原帖。
2.配置Server酱的PUSH_KEY,我将这个环境变量名称变为PUSH_KEY_fnos,因为我其他签到脚本也会使用这个 环境变量,而免费版Server酱每天只有五条免费推送的机会。
3.增加了大量备注说明,有条件你可以自己修改内容。
4.通知方式只保留Server酱。
5.更新错误处理和通知逻辑,签到失败也会通过Server酱微信通知你。
6.获取签到详情数据,换行推送(显示更加清楚明了)。
以下是分别是我测试代码时青龙面板中脚本运行时的日志,和微信收取到的Server酱通知样式。


#!/usr/bin/env python3
# coding: utf-8
"""
飞牛社区青龙面板自动签到脚本
1. 使用单个COOKIE环境变量读取盐值信息
2. 仅保留Server酱通知方式
环境变量需要配置:
- FN_COOKIE:完整的飞牛社区Cookie字符串(包含pvRK_2132_saltkey和pvRK_2132_auth)
- fn_pvRK_2132_sign:签到请求的签名参数
- PUSH_KEY_fnos:Server酱的推送密钥
"""
import os
import requests
from bs4 import BeautifulSoup
def parse_cookie(cookie_str: str) -> dict:
"""
将Cookie字符串解析为字典格式
示例输入:"pvRK_2132_saltkey=abc; pvRK_2132_auth=123"
返回:{'pvRK_2132_saltkey': 'abc', 'pvRK_2132_auth': '123'}
"""
cookie_dict = {}
# 分割每个Cookie条目
for item in cookie_str.split(';'):
# 去除首尾空格后分割键值对
key_value = item.strip().split('=', 1)
if len(key_value) == 2:
cookie_dict[key_value[0]] = key_value[1]
return cookie_dict
# 从环境变量读取配置信息
COOKIE_STR = os.getenv('FN_COOKIE', '') # 完整的Cookie字符串,名称自己按需修改
FN_SIGN = os.getenv('fn_pvRK_2132_sign', '') # 签到请求的签名参数,名称自己按需修改
PUSH_KEY = os.getenv('PUSH_KEY_fnos', '') # Server酱推送密钥,名称自己按需修改
# 解析Cookie获取关键参数
cookie_dict = parse_cookie(COOKIE_STR)
required_cookies = {
'pvRK_2132_saltkey': cookie_dict.get('pvRK_2132_saltkey'),
'pvRK_2132_auth': cookie_dict.get('pvRK_2132_auth')
}
def sign_in():
"""
执行签到操作,处理三种状态:
1. 签到成功 2. 已签到 3. 签到失败
"""
try:
# 构建签到请求URL(需要签名参数)
sign_url = f'https://club.fnnas.com/plugin.php?id=zqlj_sign&sign={FN_SIGN}'
response = requests.get(sign_url, cookies=required_cookies)
if '恭喜您,打卡成功!' in response.text:
print('✅ 签到成功')
get_sign_in_info()
elif '您今天已经打过卡了' in response.text:
print('⏰ 今日已签到')
get_sign_in_info()
else:
error_msg = '❌ 失败:Cookie可能失效或网站改版'
print(error_msg)
push_message('飞牛签到失败', error_msg)
except Exception as e:
error_msg = f'🚨 请求异常:{str(e)}'
print(error_msg)
push_message('飞牛签到异常', error_msg)
def get_sign_in_info():
"""
获取签到详情数据并推送
使用CSS选择器定位关键数据
"""
try:
response = requests.get('https://club.fnnas.com/plugin.php?id=zqlj_sign',
cookies=required_cookies)
soup = BeautifulSoup(response.text, 'html.parser')
# 定义需要抓取的数据项和对应CSS选择器
target_data = {
'最近打卡': 'li:-soup-contains("最近打卡")',
'本月打卡': 'li:-soup-contains("本月打卡")',
'连续打卡': 'li:-soup-contains("连续打卡")',
'累计打卡': 'li:-soup-contains("累计打卡")',
'累计奖励': 'li:-soup-contains("累计奖励")',
'最近奖励': 'li:-soup-contains("最近奖励")',
'当前等级': 'li:-soup-contains("当前打卡等级")',
}
# 提取并格式化数据
result = []
for name, selector in target_data.items():
element = soup.select_one(selector)
if element:
# 提取文本并分割出数值部分
text = element.get_text().split(':')[-1].strip()
result.append(f'{name}: {text}')
# 推送格式化后的消息
if result:
msg_content = '\n'.join(result)
print('📊 签到详情:\n' + msg_content)
push_message('飞牛签到成功', msg_content)
else:
raise Exception('未找到签到数据,页面结构可能已变更')
except Exception as e:
error_msg = f'抓取详情失败:{str(e)}'
print(error_msg)
push_message('飞牛签到详情异常', error_msg)
def push_message(title: str, content: str):
"""
Server酱消息推送
文档:https://sct.ftqq.com/
"""
if not PUSH_KEY:
print('⚠️ 未配置Server酱密钥,跳过推送')
return
# 构建推送请求
api_url = f'https://sctapi.ftqq.com/{PUSH_KEY}.send'
payload = {
'title': title,
'desp': content.replace('\n', '\n\n') # Server酱要求空行用两个换行
}
try:
resp = requests.post(api_url, data=payload)
if resp.json().get('code') == 0:
print('📤 推送成功')
else:
print(f'推送失败:{resp.text}')
except Exception as e:
print(f'🚨 推送异常:{str(e)}')
def validate_config():
"""
启动前校验必要配置
"""
errors = []
if not COOKIE_STR:
errors.append('缺少FN_COOKIE环境变量')
if not FN_SIGN:
errors.append('缺少fn_pvRK_2132_sign环境变量')
if not required_cookies.get('pvRK_2132_saltkey'):
errors.append('Cookie中缺少pvRK_2132_saltkey')
if not required_cookies.get('pvRK_2132_auth'):
errors.append('Cookie中缺少pvRK_2132_auth')
if errors:
print('❌ 配置错误:')
print('\n'.join(errors))
push_message('飞牛签到配置错误', '\n'.join(errors))
exit(1)
if __name__ == '__main__':
# 启动时先验证配置
validate_config()
print('🔍 配置校验通过,开始执行签到')
sign_in()