1.购买服务器阿里云:服务器购买地址https://t.aliyun.com/U/Bg6shY若失效,可用地址
阿里云:
服务器购买地址
https://t.aliyun.com/U/Bg6shY若失效,可用地址
https://www.aliyun.com/daily-act/ecs/activity_selection?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.代码如下
#!/usr/bin/env python3# -*- coding: utf-8 -*-import requestsimport jsonimport osimport sysfrom datetime import datetimeimport urllib3# 禁用SSL警告urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)# 状态文件路径STATUS_FILE = "status/status_lkong.json"def load_today_status():"""加载今日签到状态"""if not os.path.exists(STATUS_FILE):return Falsetry:with open(STATUS_FILE, 'r', encoding='utf-8') as f:data = f.read().strip()if not data:return Falsestatus = json.loads(data)# 检查是否是今天的记录today = datetime.now().strftime('%Y-%m-%d')if status.get('date') == today and status.get('success'):print(f" 今日({today})已成功签到,跳过本次运行")return Trueexcept Exception as e:print(f" 读取状态文件失败: {e}")return Falsedef save_today_status(success, message=""):"""保存今日签到状态"""today = datetime.now().strftime('%Y-%m-%d')status = {'date': today,'success': success,'message': message,'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')}try:with open(STATUS_FILE, 'w', encoding='utf-8') as f:f.write(json.dumps(status, ensure_ascii=False, indent=2))print(f" 状态已保存: {status}")except Exception as e:print(f" 保存状态失败: {e}")def lkong_punch():"""龙空论坛签到主函数"""cookie = os.environ.get('LKONG_COOKIE')if not cookie:error_msg = " 错误: 未找到LKONG_COOKIE环境变量"print(error_msg)print("设置LKONG_COOKIE")save_today_status(False, error_msg)return Falseurl = "https://api/api"# 从环境变量读取请求体(可选,提供默认值)request_body_str = os.environ.get('LKONG_REQUEST_BODY')if request_body_str:try:request_body = json.loads(request_body_str)except json.JSONDecodeError:print(" LKONG_REQUEST_BODY格式错误,使用默认请求体")request_body = {"operationName": "DoPunch","variables": {},"query": "mutation DoPunch { punch { uid punchday isPunch punchhighestday punchallday __typename } }"}else:request_body = {"operationName": "DoPunch","variables": {},"query": "mutation DoPunch { punch { uid punchday isPunch punchhighestday punchallday __typename } }"}headers = {"Cookie": cookie,"Content-Type": "application/json","Accept": "*/*","Origin": "https://www.lkong.com","Referer": "https://www.lkong.com/","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36","Sec-Fetch-Site": "same-site","Sec-Fetch-Mode": "cors","Sec-Fetch-Dest": "empty"}print("=" * 60)print(f" 龙空论坛自动签到 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")print("=" * 60)print(f" 目标地址: {url}")print(f" Cookie长度: {len(cookie)} 字符")try:response = requests.post(url,json=request_body,headers=headers,timeout=30,verify=False,allow_redirects=True)print(f" HTTP状态码: {response.status_code}")if response.status_code == 200:try:data = response.json()print(f" 响应数据: {json.dumps(data, ensure_ascii=False, indent=2)}")# 解析签到数据if data.get("data") and data["data"].get("punch"):punch_data = data["data"]["punch"]is_punch = punch_data.get("isPunch", False)punch_day = punch_data.get("punchday", 0)highest_day = punch_data.get("punchhighestday", 0)all_day = punch_data.get("punchallday", 0)if is_punch:success_msg = f"签到成功!已连签{punch_day}天"print(f" {success_msg}")print(f" 连续签到: {punch_day} 天")print(f" 最高连签: {highest_day} 天")print(f" 总签到数: {all_day} 天")save_today_status(True, success_msg)return Trueelse:# isPunch为false可能表示今天已经签到过了msg = f"签到状态未知 (isPunch=false), 连签{punch_day}天"print(f" {msg}")# 也记录为成功,因为可能已经签到过了save_today_status(True, msg)return Trueelif data.get("errors"):# GraphQL错误error_msg = f"GraphQL错误: {data['errors']}"print(f" {error_msg}")save_today_status(False, error_msg)return Falseelse:error_msg = f"响应格式异常: {data}"print(f" {error_msg}")save_today_status(False, error_msg)return Falseexcept json.JSONDecodeError as e:error_msg = f"JSON解析失败: {response.text[:200]}"print(f" {error_msg}")save_today_status(False, error_msg)return Falseelse:error_msg = f"HTTP {response.status_code}: {response.text[:200]}"print(f" {error_msg}")save_today_status(False, error_msg)return Falseexcept requests.exceptions.Timeout:error_msg = "请求超时"print(f" {error_msg}")save_today_status(False, error_msg)return Falseexcept requests.exceptions.ConnectionError as e:error_msg = f"网络连接失败: {str(e)[:100]}"print(f" {error_msg}")save_today_status(False, error_msg)return Falseexcept Exception as e:error_msg = f"未知错误: {type(e).__name__} - {str(e)[:100]}"print(f" {error_msg}")import tracebacktraceback.print_exc()save_today_status(False, error_msg)return Falsedef main():"""主函数"""# 检查今日是否已成功签到if load_today_status():print(" 今日已完成签到,无需重复运行")sys.exit(0) # 退出码0表示成功# 执行签到success = lkong_punch()print("=" * 60)if success:print(" 签到任务完成")sys.exit(0)else:print(" 签到任务失败")sys.exit(1) # 退出码1表示失败if __name__ == "__main__":main()
该脚本为龙空论坛自动签到(打卡)脚本。
主要作用
从环境变量中读取:
LKONG_COOKIE:登录用的 Cookie;LKONG_REQUEST_BODY(可选):自定义 GraphQL 请求体。在本地维护一个状态文件
status/status_lkong.json,记录每天的签到结果,避免同一天重复签到。调用
https://api.com/api的 GraphQL 接口执行DoPunch签到操作。解析返回中的签到数据(是否成功、连续签到天数、最高连签、总签到天数),打印结果并写入状态文件。
通过进程退出码(0/1)判断任务成功或失败。
可以理解为:"每天定时用 Cookie 帮你去龙空网站按一下签到按钮,并记账今天是否已经完成"。
主要方法
1. load_today_status()
作用:判断今天是否已经签到成功过。
从
status/status_lkong.json读取前一次签到状态;如果文件存在、日期是今天,并且
success == True:打印 "今日已成功签到,跳过本次运行";
返回
True(表示可以直接退出,不用再调签到接口)。否则返回
False,表示需要执行一次签到请求。
作用就是:控制"一天只签到一次",防止多次重复跑。
2. save_today_status(success, message="")
作用:把本次运行的签到结果写入状态文件。
组装状态内容:包括
date:今天日期;success:本次是否视为成功;message:提示信息;timestamp:保存时间。写入到
status/status_lkong.json,方便下次运行时用load_today_status()读取判断。
作用就是:给脚本加一个"签到结果记账本"。
3. lkong_punch()
作用:龙空论坛签到的核心逻辑。
主要流程:
从环境变量读取:
LKONG_COOKIE(必填,缺失则直接失败并写入状态);LKONG_REQUEST_BODY(可选,不填则使用内置的DoPunchGraphQL 请求体)。组织请求头(带 Cookie、UA、Origin、Referer 等)和请求体。
向
https://api.com/api发起 POST 请求:把状态码 + 截断的响应内容作为错误信息,保存为失败。
尝试解析 JSON;
正常情况是 GraphQL 返回结构:
data -> punch:如果返回里有
errors字段:其他异常结构:当作响应异常处理。
认为"状态不太确定,可能已经签过",但也按成功写入(避免死循环重签);
认为签到成功,打印"已连签 X 天"等信息;
调用
save_today_status(True, success_msg)记录成功;isPunch:是否已打卡;punchday:当前连续签到天数;punchhighestday:历史最高连签;punchallday:累计签到总天数;读取:
如果
isPunch == True:如果
isPunch == False:当作 GraphQL 错误处理,保存失败状态。
如果 HTTP 状态码是 200:
如果 HTTP 状态码不是 200:
捕获各种异常:
超时、网络错误、其他异常,都打印具体原因并写入失败状态。
总结:这个函数负责用 Cookie 调用龙空的打卡接口,并基于返回结果判定签到是否成功,然后记录状态。
4. main()
作用:脚本总入口,控制整体执行流程和退出码。
第一步:先调用
load_today_status():如果返回
True:说明今天已经成功签到,打印"今日已完成签到,无需重复运行",然后sys.exit(0);否则:
True→ 打印"签到任务完成",sys.exit(0);False→ 打印"签到任务失败",sys.exit(1),方便任务标红。调用
lkong_punch()执行签到;根据返回值:
注意:
本文部分变量已做脱敏处理,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。技术层面需要提供帮助,可以通过打赏的方式进行探讨。
没有评论:
发表评论