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.代码如下
"""任务名称name: 二重螺旋·皎皎角 每日签到定时规则cron: 0 3 0 * * ?"""import timeimport tracebackimport requestsfrom Utility.common import common_util as utilfrom Utility.common.common_util import SPException# 用于给不同API的请求头Content-Length赋值CONTENT_LENGTH_NUM = {"forum/list" : "78", "forum/like" : "146", "shareTask" : "10", "getPostDetail" : "58", "TaskProcess" : "10", "signIn" : "10", "signInGame" : "38", "signin/show" : "10", "user/mineV2" : "6"}# 获取一个随机生成的UUID,在本次运行期间使用,用于给请求头的devCode赋值UUID = util.get_uuid(4, True, False)# 从环境变量获取CookieACCOUNT = util.get_os_env("dnabbs")[0]def get_dnabbs_userid() -> str:"""API:user/mineV2获取皎皎角社区账号的UID,用于获取社区每日任务完成情况:return: 皎皎角社区账号的UID"""url = "https://dnabbs-api.yingxiong.com/user/mineV2"data = {'type': "1" # 未知用途}response = get_response(url, data, CONTENT_LENGTH_NUM["user/mineV2"])if response["code"] == 200:return response["data"]["mine"]["userId"]elif response["code"] == 220:raise SPException("Cookie失效", "Cookie失效,请更新环境变量dnabbs的值!")elif response["code"] == 500:raise SPException("失败", f"请求被拒绝,请重新尝试或检查日志!错误信息:{response['msg']}")else:raise SPException("失败",f"请求出现异常或被拒绝!Code {response['code']} - {response['msg']}")def get_dnabbs_taskprocess(userId: str) -> tuple[int, ...]:"""API:encourage/level/getTaskProcess获取皎皎角社区用户的社区每日任何和一次性任务完成情况::param userId: 皎皎角社区账号的UID:return: 返回每日任务还差几次完成,like 每日点赞5次帖子、read 每日阅读3次帖子、share 每日分享1次帖子、comment 每日回复他人帖子5次、bbs_sign 社区签到情况"""bbs_sign = like = read = share = comment = 0url = "https://dnabbs-api.yingxiong.com/encourage/level/getTaskProcess"data = {'gameId': "268", # 对应游戏ID 268=二重螺旋'userId': userId # 用户ID}response = get_response(url, data, CONTENT_LENGTH_NUM["TaskProcess"])if response["code"] == 200:data = response["data"]["dailyTask"]for i in range(len(data)):if data[i]['remark'] == "完成5次点赞":like = data[i]['times'] - data[i]['completeTimes']if data[i]['remark'] == "浏览3篇帖子":read = data[i]['times'] - data[i]['completeTimes']if data[i]['remark'] == "分享1篇内容":share = data[i]['times'] - data[i]['completeTimes']if data[i]['remark'] == "回复他人帖子5次":comment = data[i]['times'] - data[i]['completeTimes']if data[i]['remark'] == "签到":bbs_sign = data[i]['times'] - data[i]['completeTimes']return int(read), int(like), int(share), int(bbs_sign), int(comment)elif response["code"] == 220:raise SPException("Cookie失效", "Cookie失效,请更新环境变量dnabbs的值!")elif response["code"] == 500:raise SPException("失败", f"请求被拒绝,请重新尝试或检查日志!错误信息:{response['msg']}")else:raise SPException("失败",f"请求出现异常或被拒绝!Code {response['code']} - {response['msg']}")def get_dnabbs_new_formlist() -> tuple[str, str]:"""API:forum/list获取皎皎角社区用户水区分版下最新发布的帖子列表用于获取帖子ID进行点赞和浏览的每日任务获取最新发布的用户水区是确保每天获取的第一页帖子列表一定是新帖子,防止对已经浏览/点赞过的帖子再次处理导致任务进度不增加但目前其任务进度使用重复浏览、点赞取消后再点赞的方式,也会计入完成次数:return: 返回帖子ID和帖子作者ID"""url = "https://dnabbs-api.yingxiong.com/forum/list"data = {'forumId': "47", # 皎皎角社区板块ID,46 全部 | 47 水仙平原 | 48 官方 | 49 活动 | 50 攻略'gameId': "268", # 对应游戏ID 268=二重螺旋'pageIndex': "1", # 页码'pageSize': "20", # 一页内容数量'searchType': "1", # 排序规则,1 最新发布 | 2 最新回复 | 4 精华'timeType': "0", # 未知用途'topicId': "", # 话题ID}response = get_response(url, data, CONTENT_LENGTH_NUM["forum/list"])if response["code"] == 200:data = response["data"]["postList"][0]return data["postId"], data["userId"]elif response["code"] == 220:raise SPException("Cookie失效", "Cookie失效,请更新环境变量dnabbs的值!")elif response["code"] == 500:raise SPException("失败", f"请求被拒绝,请重新尝试或检查日志!错误信息:{response['msg']}")else:raise SPException("失败", f"请求出现异常或被拒绝!Code {response['code']} - {response['msg']}")def get_post_detail(postId: str) -> bool:"""API:forum/getPostDetail浏览帖子详情的API,用于完成每日浏览任务:param postId: 帖子ID:return: 返回布尔值,True为帖子被删除需要重新执行一遍,False为正常处理"""url = "https://dnabbs-api.yingxiong.com/forum/getPostDetail"data = {'isOnlyPublisher': "1", # 是否为付费专享帖子'postId': postId, # 帖子ID'showOrderType': "1" # 未知用途}response = get_response(url, data, CONTENT_LENGTH_NUM["getPostDetail"])if response["code"] == 200:return Falseelif response["code"] == 220:raise SPException("Cookie失效", "Cookie失效,请更新环境变量dnabbs的值!")elif response["code"] == 501:return True # 这篇帖子被删除,返回False令程序从获取新的帖子ID步骤从新开始执行elif response["code"] == 500:raise SPException("失败", f"请求被拒绝,请重新尝试或检查日志!错误信息:{response['msg']}")else:raise SPException("失败", f"请求出现异常或被拒绝!Code {response['code']} - {response['msg']}")def do_like(postId: str, toUserId: str) -> bool:"""API:forum/like进行点赞的API,用于完成每日点赞任务为了防止传入的帖子本身是已经点过赞的,导致第一次点赞无效因此第一次点赞前会先调用取消点赞API确保帖子是没有点赞的状态:param postId: 帖子ID:param toUserId: 帖子作者ID:return: 返回布尔值,True为帖子被删除需要重新执行一遍,False为正常处理"""url = "https://dnabbs-api.yingxiong.com/forum/like"data = {'forumId': "47", # 皎皎角社区板块ID'gameId': "268", # 对应游戏ID 268=二重螺旋'likeType': "1", # 未知用途'operateType': "1", # 1为点赞,2为取消点赞'postCommentId': "", # 未知用途'postCommentReplyId': "", # 未知用途'postId': postId, # 帖子ID'postType': "3", # 未知用途'toUserId': toUserId # 帖子作者ID}response = get_response(url, data, CONTENT_LENGTH_NUM["forum/like"])if response["code"] == 200:return Falseelif response["code"] == 220:raise SPException("Cookie失效", "Cookie失效,请更新环境变量dnabbs的值!")elif response["code"] == 501:return True # 这篇帖子被删除,返回False令程序从获取新的帖子ID步骤从新开始执行elif response["code"] == 500:raise SPException("失败", f"请求被拒绝,请重新尝试或检查日志!错误信息:{response['msg']}")else:raise SPException("失败", f"请求出现异常或被拒绝!Code {response['code']} - {response['msg']}")def do_unlike(postId: str, toUserId: str) -> bool:"""API:forum/like进行取消点赞的API与点赞API相同,唯一区别是传入的operateType参数值从1改为2:param postId: 帖子ID:param toUserId: 帖子作者ID:return: 返回布尔值,True为帖子被删除需要重新执行一遍,False为正常处理"""url = "https://dnabbs-api.yingxiong.com/forum/like"data = {'forumId': "47", # 皎皎角社区板块ID'gameId': "268", # 对应游戏ID 268=二重螺旋'likeType': "1", # 未知用途'operateType': "2", # 1为点赞,2为取消点赞'postCommentId': "", # 未知用途'postCommentReplyId': "", # 未知用途'postId': postId, # 帖子ID'postType': "3", # 未知用途'toUserId': toUserId # 帖子作者ID}response = get_response(url, data, CONTENT_LENGTH_NUM["forum/like"])if response["code"] == 200:return Falseelif response["code"] == 220:raise SPException("Cookie失效", "Cookie失效,请更新环境变量dnabbs的值!")elif response["code"] == 501:return True # 这篇帖子被删除,返回False令程序从获取新的帖子ID步骤从新开始执行elif response["code"] == 500:raise SPException("失败", f"请求被拒绝,请重新尝试或检查日志!错误信息:{response['msg']}")else:raise SPException("失败", f"请求出现异常或被拒绝!Code {response['code']} - {response['msg']}")def do_share() -> bool:"""API:encourage/level/shareTask进行分享任务进度提交的API:return: 返回布尔值,True为帖子被删除需要重新执行一遍,False为正常处理"""url = "https://dnabbs-api.yingxiong.com/encourage/level/shareTask"data = {'gameId': "268" # 对应游戏ID 268=二重螺旋}response = get_response(url, data, CONTENT_LENGTH_NUM["shareTask"])if response["code"] == 200:return Falseelif response["code"] == 220:raise SPException("Cookie失效", "Cookie失效,请更新环境变量dnabbs的值!")elif response["code"] == 501:return True # 这篇帖子被删除,返回False令程序从获取新的帖子ID步骤从新开始执行elif response["code"] == 500:raise SPException("失败", f"请求被拒绝,请重新尝试或检查日志!错误信息:{response['msg']}")else:raise SPException("失败", f"请求出现异常或被拒绝!Code {response['code']} - {response['msg']}")def do_signin_bbs() -> str:"""API:user/signIn进行皎皎角社区签到的API:return: message: 社区签到执行相关的文本日志"""message = ""url = "https://dnabbs-api.yingxiong.com/user/signIn"data = {'gameId': "268" # 对应游戏ID 268=二重螺旋}response = get_response(url, data, CONTENT_LENGTH_NUM["signIn"])if response["code"] == 200:response_data = response["data"]response_award = response_data["gainVoList"]message += f"皎皎角社区签到成功:当前连续签到 {response_data['continuitySignInDay']} 天,累计签到 {response_data['totalSignInDay']} 天。今天的签到奖励是"for i in range(len(response_award)):if response_award[i]["gainTyp"] == 1:message += f"「皎皎积分」*{response_award[i]['gainValue']}"elif response_award[i]["gainTyp"] == 2:message += f"「社区经验」*{response_award[i]['gainValue']}"else:message += f"「未知奖励」*{response_award[i]['gainValue']}"if i + 1 < len(response_award):message += "、"else:message += "。"return messageelif response["code"] == 220:raise SPException("Cookie失效", "Cookie失效,请更新环境变量dnabbs的值!")elif response["code"] == 10000:# 重复签到情况message += "皎皎角社区今天已经签到过了,无需签到。"return messageelif response["code"] == 500:raise SPException("失败", f"请求被拒绝,请重新尝试或检查日志!错误信息:{response['msg']}")else:raise SPException("失败", f"请求出现异常或被拒绝!Code {response['code']} - {response['msg']}")def get_signin_game_awards_list() -> tuple[int, str, str, str]:"""API:encourage/signin/show返回当前月份游戏签到的奖励详情列表,与当前月份用户已经签到天数、可使用补签次数等信息:return game_sign: 今天是否已经签到,0为签到过,1为未签到:return periodId: 当前月份的ID序号,用于执行签到时传递参数;在返回中"dayAward"项内的每一组数据,都有一个"periodId"项:return dayAwardId: 今天的签到奖励对应的奖励ID,用于执行签到时传递参数;在返回中"dayAward"项内的每一组数据,都有一个"id"项:return award: 今天的游戏签到奖励"""url = "https://dnabbs-api.yingxiong.com/encourage/signin/show"data = {'gameId': "268" # 对应游戏ID 268=二重螺旋}response = get_response(url, data, CONTENT_LENGTH_NUM["signin/show"])if response["code"] == 200:# 确定今天游戏是否签到,true为签到过,false为没有签到if response["data"]["todaySignin"]:game_sign = 0signin_time = response["data"]["signinTime"] # 获取当月签到天数,今天已经签过到了,因此直接以此签到天数获取今天签到奖励内容else:game_sign = 1signin_time = response["data"]["signinTime"] + 1 # 获取当月签到天数,今天未签到,因此需要+1天,获取今天签到后的天数,以此来获取对应的dayAwardId和签到奖励内容award_list = response["data"]["dayAward"] # 当月奖励详情列表for i in range(len(award_list)):if award_list[i]["dayInPeriod"] == signin_time:periodId = award_list[i]["periodId"]dayAwardId = award_list[i]["id"]award = f"「{award_list[i]['awardName']}」*{award_list[i]['awardNum']}"break # 找到当天的奖励了,直接中断for循环return game_sign, periodId, dayAwardId, awardelif response["code"] == 220:raise SPException("Cookie失效", "Cookie失效,请更新环境变量dnabbs的值!")elif response["code"] == 500:raise SPException("失败", f"请求被拒绝,请重新尝试或检查日志!错误信息:{response['msg']}")else:raise SPException("失败", f"请求出现异常或被拒绝!Code {response['code']} - {response['msg']}")def do_signin_game(periodId: str, dayAwardId: str, award: str) -> str:"""API:encourage/signin/signin进行二重螺旋游戏签到的API,需提前在皎皎角APP的签到页面绑定游戏角色:param periodId: 当前月份的ID序号,用于执行签到时传递参数:param dayAwardId: 今天的签到奖励对应的奖励ID,用于执行签到时传递参数:param award: 今天的游戏签到奖励:return message: 游戏签到执行相关的文本日志"""message = ""url = "https://dnabbs-api.yingxiong.com/encourage/signin/signin"data = {'signinType': "1", # 未知用途'periodId': periodId, # 可能是游戏签到月份的ID序号,在encourage/signin/show API的返回中"dayAward"项内的每一组数据,都有一个"periodId"项'dayAwardId': dayAwardId # 签到奖励列表对应天数的ID,在encourage/signin/show API的返回中"dayAward"项内的每一组数据,都有一个"id"项}response = get_response(url, data, CONTENT_LENGTH_NUM["signInGame"])if response["code"] == 200:message += f"二重螺旋游戏签到成功:当月已签到 {response['data']['signinTimeNow']} 天,今天的游戏签到奖励是{award}。"return messageelif response["code"] == 220:raise SPException("Cookie失效", "Cookie失效,请更新环境变量dnabbs的值!")elif response["code"] == 10000:# 重复签到,或periodId/dayAwardId不正确导致签到失败,填写正确的id重复签到也会返回同样的参数错误信息,所以无法确定具体是哪个情况message += f"二重螺旋游戏签到失败,或者今天已经签到过了,今天的游戏签到奖励是 {award}。"return messageelif response["code"] == 500:raise SPException("失败", f"请求被拒绝,请重新尝试或检查日志!错误信息:{response['msg']}")else:raise SPException("失败", f"请求出现异常或被拒绝!Code {response['code']} - {response['msg']}")def get_response(url: str, data: dict[str, str], content_length: str) -> any:"""返回处理为json的response:param url: 请求的url:param data: 请求的data:param content_length: 请求的content_length:return: 返回处理为json的response"""headers = {'User-Agent': "DoubleHelix/2 CFNetwork/3860.100.1 Darwin/25.0.0",'Host': "dnabbs-api.yingxiong.com",'version': "1.1.1",'lan': "en",'channel': "appstore",'Accept': "*/*",'devCode': UUID,'source': "ios",'Accept-Language': "zh-CN,zh-Hans;q=0.9",'Accept-Encoding': "gzip, deflate",'Ip': "192.168.3.101",'Content-Length': content_length,'Connection': "keep-alive",'Content-Type': "application/x-www-form-urlencoded; charset=utf-8",'model': "iPhone15,4",'osVersion': "26.0.1",'token': ACCOUNT}response = requests.post(url, data=data, headers=headers).json()return responseif __name__ == "__main__":"""关于:社区每日任务 回复帖子5次此任务必须回复5个不同的帖子才会计数,且经测试,疑似每个帖子都只有一次计数机会,即非同一天回复同一个帖子时,此任务也不会计数由于以上种种限制,导致无法直接对官方水贴回复5次来完成任务,随机水贴回复其他玩家帖子可能出现不可预料的情况,因此放弃自动处理此任务"""util.send_log(0, "二重螺旋·皎皎角 每日签到 - 开始执行")notify_content = "" # 储存用于推送通知正文的消息内容if ACCOUNT is None:util.send_log(2, "缺少环境变量,请添加以下环境变量后再使用:dnabbs")util.send_notify("【缺少环境变量】二重螺旋·签到", "缺少环境变量,请添加以下环境变量后再使用:dnabbs(皎皎角账号Cookie)")else:try:restart_flag = True # 是否需要重新运行,默认为True用于启动第一次循环执行attempt = 0 # 最多重复执行3次while restart_flag and attempt < 3:if attempt > 0:util.send_log(1, f"社区交互任务执行出现意外的状况,开始重新执行,第{attempt + 2}次尝试中……")notify_content += f"社区交互任务执行出现意外的状况,开始重新执行,第{attempt + 2}次尝试中……\n\n"restart_flag = False # 循环开始将重新运行开关关闭attempt += 1 # 每次运行令运行次数计数+1,超出3次后不论是否成功都不再尝试# 获取用户皎皎角账号UIDuserId = get_dnabbs_userid()util.send_log(0, f"已获取用户皎皎角账号UID:{userId}。")notify_content += f"已获取用户皎皎角账号UID:{userId}。\n\n"time.sleep(2)# 获取用户今日任务完成情况,返回还需要进行多少次浏览帖子、点赞、社区签到、游戏签到、回复他人帖子次数的操作read, like, share, bbs_sign, comment = get_dnabbs_taskprocess(userId)time.sleep(2)# 直接使用获取本月游戏签到奖励列表API,其中也会有今天是否签到的data,实际有专门获取今天是否进行社区和游戏签到的API haveSignInNew,但直接使用此API可以同时获取到今天签到必须的表单值和签到奖励内容更方便game_sign, periodId, dayAwardId, award = get_signin_game_awards_list()util.send_log(0, f"今日任务完成情况:点赞{' 已完成'if like == 0elsef'还需 {like} 次'}、浏览{' 已完成'if read == 0elsef'还需 {read} 次'}、分享{' 已完成'if share == 0elsef'还需 {share} 次'}、回复他人帖子{' 已完成'if comment == 0elsef'还需 {comment} 次'}、社区签到 {'已完成'if bbs_sign == 0else'未完成'}、游戏签到 {'已完成'if game_sign == 0else'未完成'}。")notify_content += f"今日任务完成情况:点赞{' 已完成'if like == 0elsef'还需 {like} 次'}、浏览{' 已完成'if read == 0elsef'还需 {read} 次'}、分享{' 已完成'if share == 0elsef'还需 {share} 次'}、回复他人帖子{' 已完成'if comment == 0elsef'还需 {comment} 次'}、社区签到 {'已完成'if bbs_sign == 0else'未完成'}、游戏签到 {'已完成'if game_sign == 0else'未完成'}。\n\n"time.sleep(2)# 如果需要浏览/点赞/分享,则获取帖子列表,返回1组帖子的id和发帖人idif read > 0 or like > 0 or share > 0:postId, postUserId = get_dnabbs_new_formlist()util.send_log(0, "已获取最新帖子列表,开始执行……")time.sleep(2)# 如果需要点赞次数不为0,则执行点赞if like > 0:for i in range(like):restart_flag = do_unlike(postId, postUserId) # 先取消点赞,防止这个帖子本身就被用户点过赞了导致第一次点赞不计入任务完成数中if restart_flag:util.send_log(1, f"执行第{i+1}次取消点赞操作时出现意外错误,可能是操作的帖子被删除了,重新开始社区交互任务执行流程……")break # 访问API返回非致命的错误,跳出循环并重新执行获取新的帖子ID,此处用于中止当前for循环else:util.send_log(0, f"执行第{i + 1}次取消点赞操作完成……")time.sleep(1)restart_flag = do_like(postId, postUserId) # 执行点赞if restart_flag:util.send_log(1,f"执行第{i + 1}次点赞操作时出现意外错误,可能是操作的帖子被删除了,重新开始社区交互任务执行流程……")break # 访问API返回非致命的错误,跳出循环并重新执行获取新的帖子ID,此处用于中止当前for循环else:util.send_log(0, f"执行第{i + 1}次点赞操作完成……")time.sleep(1)util.send_log(0, f"点赞任务完成,执行了{like}次点赞帖子操作;")notify_content += f"点赞任务完成,执行了{like}次点赞帖子操作;\n\n"else:util.send_log(0, "点赞任务已完成,不需要进行操作;")notify_content += "点赞任务已完成,不需要进行操作;\n\n"if restart_flag:continue # 访问API返回非致命的错误,跳出循环并重新执行获取新的帖子ID,此处用于中断后续代码运行并开始新的循环# 如果需要浏览次数不为0,则执行浏览if read > 0:for i in range(read):restart_flag = get_post_detail(postId)if restart_flag:util.send_log(1,f"执行第{i + 1}次浏览帖子操作时出现意外错误,可能是操作的帖子被删除了,重新开始社区交互任务执行流程……")break # 访问API返回非致命的错误,跳出循环并重新执行获取新的帖子ID,此处用于中止当前for循环else:util.send_log(0, f"执行第{i + 1}次浏览帖子操作完成……")time.sleep(3)util.send_log(0, f"浏览任务完成,执行了{read}次浏览帖子操作;")notify_content += f"浏览任务完成,执行了{read}次浏览帖子操作;\n\n"else:util.send_log(0, "浏览任务已完成,不需要进行操作;")notify_content += "浏览任务已完成,不需要进行操作;\n\n"if restart_flag:continue # 访问API返回非致命的错误,跳出循环并重新执行获取新的帖子ID,此处用于中断后续代码运行并开始新的循环# 如果需要分享次数不为0,则执行分享帖子if share > 0:for i in range(share):restart_flag = do_share()if restart_flag:util.send_log(1, f"执行第{i + 1}次同步分享帖子任务进度操作时出现意外错误,重新开始社区交互任务执行流程……")break # 访问API返回非致命的错误,跳出循环并重新执行获取新的帖子ID,此处用于中止当前for循环else:util.send_log(0, f"执行第{i + 1}次同步分享帖子任务进度操作完成……")time.sleep(3)util.send_log(0, f"分享任务完成,执行了{share}次分享帖子操作;")notify_content += f"分享任务完成,执行了{share}次分享帖子操作;\n\n"else:util.send_log(0, "分享任务已完成,不需要进行操作;")notify_content += "分享任务已完成,不需要进行操作;\n\n"else:util.send_log(0, "今日社区交互任务均已完成,不需要进行操作;")notify_content += "今日社区交互任务均已完成,不需要进行操作;\n\n"if attempt == 2 and restart_flag:util.send_log(2, "社区交互任务执行出现意外的状况,已重复尝试3次仍未成功,放弃此部分任务的执行!")notify_content += "社区交互任务执行出现意外的状况,已重复尝试3次仍未成功,放弃此部分任务的执行!\n\n"# 如果需要社区签到,则执行签到if bbs_sign == 1:message_bbs_sign = do_signin_bbs()util.send_log(0, message_bbs_sign)notify_content += f"{message_bbs_sign}\n\n"time.sleep(5)else:util.send_log(0, "社区签到已完成,不需要进行操作;")notify_content += "社区签到已完成,不需要进行操作;\n\n"# 如果需要游戏签到,则执行签到if game_sign == 1:message_game_sign = do_signin_game(periodId, dayAwardId, award)util.send_log(0, message_game_sign)notify_content += f"{message_game_sign}\n\n"time.sleep(5)else:util.send_log(0, "游戏签到已完成,不需要进行操作;")notify_content += f"游戏签到已完成,不需要进行操作。今天的游戏签到奖励是 {award};\n\n"# 全部完成,最终推送util.send_log(0, "二重螺旋·皎皎角 每日签到 - 执行完成")util.send_notify("二重螺旋·签到:已完成", notify_content)except SPException as e:# 主动抛出的异常,用于在出现非访问失败的问题时中断后续函数执行util.send_log(2, e.content)util.send_notify(f"【{e.title}】二重螺旋·签到", e.content)except requests.RequestException as e:# API访问失败的异常中断util.send_log(3, f"API请求失败 - {e}")util.send_notify("【失败】二重螺旋·签到", f"API请求失败,请查看日志!\n\n错误信息:{e}")except Exception as e:# 其他所有异常util.send_log(3, f"程序运行报错 - {e}")util.send_log(3, f"{traceback.format_exc()}")util.send_notify("【程序报错】二重螺旋·签到", f"程序运行报错,请查看日志!\n\n错误信息:{e}")
这是一个用于 二重螺旋·皎皎角"社区 + 游戏签到 的自动化脚本(定时任务:cron 0 3 0 * * ?)。它会:
从环境变量
dnabbs读取 皎皎角账号 Cookie/Token调用皎皎角官方 API:
查询 当前用户 UID
查询 每日任务进度(点赞/浏览/分享/社区签到/回复等)
通过"最新帖子"完成 点赞、浏览、分享 等日常交互任务(回复任务因限制放弃自动处理)
执行 社区签到
查询 游戏签到奖励列表 并执行 游戏签到
最后汇总日志并用
util.send_notify()推送执行结果
主要方法
1)请求与基础能力
get_response(url, data, content_length)统一封装
requests.post()请求。构造一套"模拟 iOS 客户端"的请求头(
User-Agent/devCode/model/osVersion/token等)。token使用环境变量dnabbs的值;devCode使用随机 UUID。返回接口 JSON 响应。
2)账号与任务进度
get_dnabbs_userid()调用
user/mineV2获取当前账号的 userId(UID)。对
220(Cookie 失效)/500(拒绝)等状态码进行异常抛出。get_dnabbs_taskprocess(userId)点赞 5 次、浏览 3 篇、分享 1 次、回复 5 次、签到
调用
encourage/level/getTaskProcess获取每日任务完成进度。从返回的
dailyTask里按remark识别任务:返回:
read, like, share, bbs_sign, comment(都是"还差多少次/是否未完成")
3)帖子来源与社区交互任务
get_dnabbs_new_formlist()调用
forum/list拉取"水区(forumId=47)最新发布"的帖子列表。取第 1 条帖子的
postId与作者userId,用于后续点赞/浏览任务。用"最新发布"是为了减少重复操作导致任务不计数的风险(脚本也支持重复浏览/取消点赞再点赞来刷次数)。
get_post_detail(postId)调用
forum/getPostDetail,用于 计入"浏览帖子"任务次数。返回
True表示帖子可能已删除(501),需要重新获取新帖子并重跑交互流程;False表示正常。do_unlike(postId, toUserId)调用
forum/like,operateType=2执行 取消点赞。这样能确保后续点赞时一定从"未点赞状态"开始,避免首次点赞不计数。
返回
True表示帖子异常/删除需要重跑;否则False。do_like(postId, toUserId)调用
forum/like,operateType=1执行 点赞。返回值逻辑同上:用于触发"帖子删除"等非致命错误时的重跑机制。
do_share()调用
encourage/level/shareTask上报 分享任务进度(不是实际分享动作,更像"提交任务完成")。返回
True/False用于是否需要重跑交互流程。
4)社区签到与游戏签到
do_signin_bbs()调用
user/signIn执行 皎皎角社区签到。成功时拼接文本:连续签到天数、累计签到天数、奖励列表(皎皎积分/社区经验等)。
10000表示今天已签过,返回对应提示文案。get_signin_game_awards_list()periodId(月份/周期标识)dayAwardId(当天奖励条目 ID)award(拼好的奖励文本)今天是否已游戏签到(
todaySignin)当月签到天数(
signinTime)当月每日奖励列表
dayAward调用
encourage/signin/show获取:计算"今天对应的 dayInPeriod",找到匹配项后取出:
返回:
game_sign, periodId, dayAwardId, awarddo_signin_game(periodId, dayAwardId, award)调用
encourage/signin/signin执行 二重螺旋游戏签到(要求 APP 里已绑定角色)。成功则返回"当月签到天数 + 今日奖励"的文本。
10000视为"重复签到或参数不正确",脚本用同一句话兜底提示。
主流程
读取
dnabbs→ 取 UID → 查任务进度 → 查游戏签到奖励/是否已签若需要点赞/浏览/分享:取最新帖子 → 取消赞/点赞循环、浏览循环、分享循环
若接口返回
501(帖子被删)→restart_flag=True→ 整段交互最多重试 3 次若社区未签:执行
do_signin_bbs()若游戏未签:执行
do_signin_game()汇总并通知;异常用
SPException / RequestException / Exception分层处理并推送错误原因
注意:
本文部分变量已做脱敏处理,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。技术层面需要提供帮助,可以通过打赏的方式进行探讨。
没有评论:
发表评论