为何Reddit Bot无法存储评论ID至JSON文件,重启后重复回复?
Reddit Bot 重复回复问题修复方案
问题根源
- JSON写入方式错误:使用
"a"(追加)模式写入JSON文件,每次回复后将整个answered_comments字典追加到文件末尾,导致JSON结构混乱,程序重启时无法正确解析已存储的评论ID,进而重复回复。 - JSON解析错误处理缺失:当
comment_id.json格式损坏时,仅定义了空字典data,未重置answered_comments为空,可能引发后续逻辑异常。 - 冗余数据存储:
answered_comments[comment.id] = {"ID": comment.id}属于冗余存储,字典的key已经是评论ID,无需重复存储值。
修改后的完整代码
import time import json import os import requests import praw # Reddit CLIENT_ID = 'xxx' CLIENT_SECRET = 'xxx' USERNAME = 'xxx' PASSWORD = 'xxx' USER_AGENT = 'xxx' # NASA NASA_API = 'xxxxxxxxx' NASA_HTTP = 'https://api.nasa.gov/planetary/apod' # 初始化Reddit客户端 reddit = praw.Reddit(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, username=USERNAME, password=PASSWORD, user_agent=USER_AGENT) # 指定操作的子版块 subreddit = reddit.subreddit('xxx') # 记录最新评论时间 last_comment_time = time.time() answered_comments = {} # 加载已回复的评论ID try: with open("comment_id.json", "r") as data_file: answered_comments = json.load(data_file) except FileNotFoundError: # 文件不存在时创建空文件 with open("comment_id.json", "w") as data_file: json.dump(answered_comments, data_file, indent=4) except json.decoder.JSONDecodeError: # 格式错误时重置为空字典并重新创建文件 answered_comments = {} with open("comment_id.json", "w") as data_file: json.dump(answered_comments, data_file, indent=4) # 封装保存已回复ID的函数,避免重复代码 def save_answered_comments(): with open("comment_id.json", "w") as data_file: json.dump(answered_comments, data_file, indent=4) while True: # 获取最新评论 new_comments = subreddit.comments(params={"after": last_comment_time}) for comment in new_comments: # 更新最新评论时间 if comment.created_utc > last_comment_time: last_comment_time = comment.created_utc # 处理/nasa指令 if '/nasa' in comment.body.lower(): if comment.id not in answered_comments: # 请求NASA API参数 parameters = { "api_key": NASA_API, "hd": True } response = requests.get(NASA_HTTP, params=parameters) response.raise_for_status() data = response.json() image_url = data["hdurl"] # 回复评论 comment.reply('NASA Image of the Day: ' + image_url) # 记录已回复的评论ID answered_comments[comment.id] = True # 保存到文件 save_answered_comments() # 处理/indir指令 if '/indir' in comment.body.lower(): if comment.id not in answered_comments: post = comment.parent() if post.media: video_url = post.media['reddit_video']['fallback_url'] comment.reply('Video URL: ' + video_url) else: comment.reply('Bu indirilebilecek bir video değil.') # 记录已回复的评论ID answered_comments[comment.id] = True # 保存到文件 save_answered_comments() # 每10分钟刷新一次 time.sleep(10 * 60)
关键修改说明
- 修改JSON写入模式:将追加模式
"a"改为覆盖模式"w",每次回复后完整写入answered_comments字典,保证JSON格式始终正确。 - 完善错误处理:当JSON解析失败时,重置
answered_comments为空字典并重新创建文件,避免后续逻辑异常。 - 封装保存函数:将重复的JSON写入逻辑封装成
save_answered_comments函数,减少代码冗余。 - 简化数据存储:将
answered_comments的value改为True,避免冗余存储评论ID,也可以改用集合(answered_comments = set())进一步优化空间。
内容的提问来源于stack exchange,提问作者Cihan Yalçın
相关产品推荐
相关产品推荐

