如何用Python获取Reddit子版块总帖子数并抓取全部内容?
解决方案:用PRAW+Pushshift抓取Reddit子版块全部帖子
问题说明
我正在用PRAW抓取Reddit的gaming子版块,目前只能通过固定的limit值指定抓取数量,但想获取该子版块的总帖子数,以此作为limit来抓取全部内容。尝试设置limit="None"时触发报错:
TypeError: '<' not supported between instances of 'int' and 'str'
报错原因
- PRAW的
limit参数接受的是整数或者Python内置的None(表示抓取API允许的最大数量,上限约1000条),但你传入的是字符串"None",导致代码中i < value的比较操作(整数与字符串无法直接比较)触发TypeError。 - 原代码中的
while循环属于冗余逻辑:for submission in subreddit.hot(limit=value)已经会遍历指定数量的帖子,外层while会导致重复抓取。
解决步骤
1. 修复limit="None"的错误
如果仅需抓取PRAW允许的最大数量(约1000条),只需将limit设为Python的None(不要加引号),同时去掉冗余的while循环:
# 错误写法 subreddit.hot(limit="None") # 正确写法 subreddit.hot(limit=None)
2. 用Pushshift API获取全部帖子
由于Reddit API限制,PRAW单次最多抓取约1000条帖子,要获取子版块全部内容,必须借助Pushshift API(通过psaw库实现):
- Pushshift可获取Reddit全量历史帖子数据,不受1000条限制
- 结合PRAW拉取完整的评论数据(Pushshift返回的评论信息不完整)
修改后的完整代码
import praw import pandas as pd import os from dotenv import load_dotenv, find_dotenv from psaw import PushshiftAPI load_dotenv(find_dotenv()) # 初始化数据框 df = pd.DataFrame(columns=['Title', 'Number of comments', 'Comments']) # 初始化PRAW实例 reddit_read_only = praw.Reddit( client_id=os.environ.get("client_id"), client_secret=os.environ.get("client_secret"), user_agent=os.environ.get("user_agent") ) # 初始化Pushshift API实例 ps_api = PushshiftAPI(reddit_read_only) def scrape_full_subreddit(subreddit_name): i = 0 # 用Pushshift获取子版块所有帖子,可添加time_filter参数限制时间范围,比如'year' submissions = ps_api.search_submissions(subreddit=subreddit_name) for submission in submissions: # 通过PRAW获取完整的帖子对象,用于拉取评论 full_submission = reddit_read_only.submission(id=submission.id) # 加载所有评论,limit=None表示加载全部评论 full_submission.comments.replace_more(limit=None) comments_list = [] if full_submission.num_comments != 0: for comment in full_submission.comments.list(): comments_list.append(comment.body) else: comments_list = ['No comments'] # 存入数据框 df.loc[i] = [full_submission.title, full_submission.num_comments, comments_list] i += 1 # 保存CSV文件 filename = f'Reddit_web_scrap_{subreddit_name}.csv' df.to_csv(filename, index=False) return filename if __name__ == "__main__": print('#####################################################################') print('############### Reddit Web Scrapping Started ########################') print('#####################################################################') print() filename = scrape_full_subreddit('gaming') print() print(f'Created {filename} file!') print() print('#####################################################################') print('################# Reddit Web Scrapping Ended ########################') print('#####################################################################')
注意事项
- Pushshift API有请求频率限制,抓取大量帖子时建议添加适当延时(比如
time.sleep(1)) - 部分老旧帖子可能已被Reddit删除,会导致PRAW无法获取完整数据,建议添加异常处理
- 如果只需抓取特定时间段的帖子,可在
search_submissions中添加after和before参数(传入时间戳)
内容的提问来源于stack exchange,提问作者Hardik_Zalavadiya
相关产品推荐
相关产品推荐

