Python Reddit评论关键词爬取工具的两个技术问题咨询
解决Reddit评论爬虫的两个问题:获取submission_id与拉取全部匹配评论
嘿,针对你遇到的这两个技术问题,我来一步步帮你搞定:
问题1:获取评论对应的submission_id
用PSAW拿到的评论对象里,link_id属性已经包含了对应帖子的ID,不过它的格式是t3_xxxxxx(t3是Reddit对帖子的类型标识),咱们只需要把下划线后面的部分提取出来,就是真实的submission_id了。
修改你的打印逻辑,就能直接输出submission_id:
print(f' comment {commentcount}: submission_id = {c.link_id.split("_")[1]}, content: {c.body}')
要是你需要单独存这个ID,也可以这么写:
submission_id = c.link_id.split('_')[1]
问题2:无法拉取所有匹配关键词的旧评论
你现在的代码只调用了基础的search_comments,PSAW默认是最新评论优先返回,再加上Pushshift API本身不会主动返回全量历史数据,没指定时间范围的话,大概率只会拿到最近一批结果。要拉取所有匹配的评论,你得做这几件事:
1. 指定完整的时间范围
通过before和after参数设置时间区间,覆盖你想要爬取的全部历史范围。比如从1年前到现在:
# 设置起始时间(1年前)和结束时间(当前UTC时间) start_time = int((datetime.now(timezone.utc) - relativedelta(years=1)).timestamp()) end_time = int(datetime.now(timezone.utc).timestamp()) # 带着时间范围调用API comments = api.search_comments(q='OP', subreddit='askreddit', after=start_time, before=end_time)
如果你想爬取子版块创建以来的所有评论,可以把after设为子版块创建的时间戳(比如r/askreddit创建于2008年,对应的时间戳是1201248000)。
2. 处理API的分页与结果限制
Pushshift API单次返回结果有数量上限,PSAW的生成器会自动处理分页,但偶尔会因为网络或API限流中断。你可以显式声明limit=None(默认就是None,但写出来更清晰),确保遍历完所有结果;必要时还可以加个简单的重试机制,避免中途断连。
3. 优化后的完整代码示例
from psaw import PushshiftAPI from datetime import datetime, timezone from dateutil.relativedelta import relativedelta api = PushshiftAPI() # 设置时间范围:从askreddit创建年份(2008年)到现在 start_time = 1201248000 # 对应2008-01-27的UTC时间戳 end_time = int(datetime.now(timezone.utc).timestamp()) # 调用API,指定关键词、子版块和时间范围 comments = api.search_comments( q='OP', subreddit='askreddit', after=start_time, before=end_time, limit=None ) commentcount = 0 for c in comments: commentcount += 1 # 提取并打印submission_id和评论内容 submission_id = c.link_id.split('_')[1] print(f'Comment {commentcount} | Submission ID: {submission_id}\nContent: {c.body}\n---')
为啥之前会丢失旧评论?
- PSAW默认按
created_utc降序返回,最新的评论先出来,要是你中途停止运行、没遍历完所有生成器内容,自然看不到旧评论; - 没指定时间范围时,Pushshift API可能只返回最近30天或更短时间的结果,直接漏掉了历史评论;
- Pushshift的索引偶尔会有小范围缺失,但通过指定时间范围+完整遍历生成器,能最大程度获取所有匹配的评论。
内容的提问来源于stack exchange,提问作者blake




