如何实现从subreddit仅下载不重复的唯一图片/媒体资源
重复下载问题的解决方法
你当前脚本出现重复下载的核心原因有两点:
subreddit.top(limit=10)默认拉取全时段热门榜单,该榜单内容更新频率极低,每次运行拉取的前10条内容重合度极高- 脚本没有记录历史下载内容的逻辑,运行时不会判断资源是否已经下载过,只要拉到就会重复写入
具体实现方案
要稳定每次拿到10个不重复的媒体资源,只需要加一层本地去重逻辑,同时调整拉取逻辑不要固定截断前10条即可:
- 本地维护一个纯文本文件
downloaded_ids.txt,用来持久化存储所有已经下载过的帖子ID,脚本启动时先把历史ID读入内存存为集合做快速去重判断 - 遍历subreddit内容时,跳过ID已经存在于集合中的帖子,每成功下载一个新资源,就把对应ID写入记录文件,直到累计下载满10个新资源就终止运行
- 补全原代码缺失的praw实例初始化逻辑,同时加个简单的资源格式判断,跳过非图片直链的帖子避免下载到无效的跳转页面
修改后的可运行代码如下:
import praw import requests import os # 初始化praw实例,替换成你自己申请的reddit API参数即可 reddit = praw.Reddit( client_id="你的client_id", client_secret="你的client_secret", user_agent="meme_crawler/1.0 by /u/你的reddit用户名" ) # 加载历史已下载ID集合 downloaded_ids = set() if os.path.exists("downloaded_ids.txt"): with open("downloaded_ids.txt", "r", encoding="utf-8") as f: for line in f: downloaded_ids.add(line.strip()) subreddit = reddit.subreddit("memes") download_count = 0 # 可将top替换为hot/new对应不同排序规则,time_filter可选day/week/month/year调整榜单时间范围 for submission in subreddit.top(time_filter="week", limit=None): # 已下载内容直接跳过 if submission.id in downloaded_ids: continue # 过滤非图片直链,跳过画廊、视频、第三方跳转链接 if not submission.url.endswith((".jpg", ".png", ".gif")): continue # 下载资源 try: img_data = requests.get(submission.url, timeout=10).content # 用帖子ID+原文件名存储,避免不同帖子同名文件互相覆盖 filename = f"{submission.id}_{submission.url.split('/')[-1]}" with open(filename, "wb") as handler: handler.write(img_data) # 记录本次下载的帖子ID downloaded_ids.add(submission.id) with open("downloaded_ids.txt", "a", encoding="utf-8") as f: f.write(f"{submission.id}\n") download_count += 1 print(f"已下载第{download_count}个资源:{submission.url}") # 凑够10个新资源直接终止运行 if download_count >= 10: break except Exception as e: print(f"下载{submission.url}失败,自动跳过:{str(e)}") continue
补充说明:如果想要更高的新内容占比,可以把
subreddit.top换成subreddit.new拉取最新发布的帖子,或者把time_filter参数调整为day拉取日榜内容,内容重复率会更低。
内容的提问来源于stack exchange,提问作者jettzeong
相关产品推荐
相关产品推荐

