# Reddit 内容爬取知识体系报告 (reddit-scraper) > 调研时间: 2026-04-13 > 目标 Agent: reddit-scraper > 模板目录: system/templates/reddit-scraper/ > 技能领域: Reddit 数据爬取(抓取子版块热门帖子、评论数据) --- ## 1. 数据源清单 ### 1.1 一手数据源(推荐) | 序号 | 数据源 | 端点/URL | 稳定性 | 数据类型 | 爬取难度 | |------|--------|----------|--------|----------|----------| | 1 | Reddit Public JSON API | `https://www.reddit.com/r/{subreddit}/{sort}.json` | ★★★☆☆ | 子版块帖子列表(无需认证) | 低 | | 2 | Reddit Comments JSON API | `https://www.reddit.com/r/{subreddit}/comments/{post_id}.json` | ★★★☆☆ | 帖子详情 + 评论树 | 低 | | 3 | Reddit Search JSON API | `https://www.reddit.com/r/{subreddit}/search.json` | ★★★☆☆ | 子版块内搜索 | 低 | | 4 | Reddit RSS Feeds | `https://www.reddit.com/r/{subreddit}/.rss` | ★★★★☆ | 帖子 RSS 流(XML) | 低 | | 5 | Old Reddit HTML | `https://old.reddit.com/r/{subreddit}/` | ★★★☆☆ | 轻量 HTML,适合无 JS 解析 | 中 | ### 1.2 二手/聚合数据源 | 序号 | 数据源 | 说明 | 适用场景 | |------|--------|------|----------| | 6 | Pushshift API | 第三方 Reddit 历史数据存档 API | 历史帖子回溯、学术研究 | | 7 | Reddit Official API (OAuth) | `praw` / `reddit.com/dev/api` | 商业级、高稳定性、需付费 | | 8 | Third-party Scrapers (Apify/Bright Data) | `apify.com` / `brightdata.com` | 代理池+无头浏览器,成本高 | | 9 | RedditStat / Subreddit Stats | 第三方统计站点 | 趋势分析、榜单补全 | ### 1.3 数据源评估结论 - **首选**: `reddit.com/r/{subreddit}/hot.json` — 无需 OAuth 即可获取公开子版块的帖子 JSON,字段规范(`title`, `selftext`, `score`, `num_comments`, `author`, `created_utc` 等),适合快速原型。 - **备用**: `old.reddit.com` — 反爬较主站宽松,页面更轻量,适合 BeautifulSoup 解析兜底。 - **RSS 方案**: `.rss` 输出稳定、格式标准,适合长期监控和轻量级订阅,但字段较 JSON API 少(无 `upvote_ratio`、`awards` 等)。 - **历史数据**: Pushshift 已被 Reddit 官方限制收录新数据,可用性下降;如需历史长周期数据,建议使用官方 API。 --- ## 2. Reddit JSON API 详解 ### 2.1 核心端点 #### 帖子列表 ``` https://www.reddit.com/r/{subreddit}/{sort}.json?limit={limit}&after={after}&t={time} ``` - `{sort}`: `hot`, `new`, `top`, `rising`, `controversial` - `{limit}`: 每页最大 **100** - `{t}` (仅 top/controversial): `hour`, `day`, `week`, `month`, `year`, `all` - `{after}`: 分页 token(值来自上一页 `data.after`) #### 帖子详情 + 评论树 ``` https://www.reddit.com/r/{subreddit}/comments/{post_id}.json?limit={limit} ``` - 返回数组 `[post_data, comment_tree]` - 评论存在 `more` 节点,需要额外递归请求展开 #### 搜索 ``` https://www.reddit.com/r/{subreddit}/search.json?q={query}&sort={sort}&t={time}&restrict_sr=1 ``` - 跨站搜索时省略 `/r/{subreddit}` ### 2.2 核心字段映射表 基于 Public JSON API 返回的字段: | 字段名 | 类型 | 含义 | 输出映射 | |--------|------|------|----------| | `id` | string | 帖子唯一 ID | `post_id` | | `title` | string | 帖子标题 | `content.title` | | `selftext` | string | 帖子正文(Text Post) | `content.body` | | `author` | string | 发帖用户 | `content.author` | | `subreddit` | string | 所属子版块 | `source.subreddit` | | `permalink` | string | 站内相对链接 | `source.permalink` → `source_url` | | `url` | string | 外部链接(Link Post) | `content.external_url` | | `score` | int | 净点赞数(upvotes - downvotes) | `engagement.score` | | `num_comments` | int | 评论总数 | `engagement.num_comments` | | `upvote_ratio` | float | 赞成比例(0.0~1.0) | `engagement.upvote_ratio` | | `created_utc` | float | 发帖时间(Unix 秒) | `content.created_utc` | | `over_18` | bool | NSFW 标记 | `content.is_nsfw` | | `spoiler` | bool | 剧透标记 | `content.is_spoiler` | | `total_awards_received` | int | 获得奖励数 | `engagement.awards` | | `link_flair_text` | string | 帖子标签/分类 | `content.flair` | ### 2.3 目标子版块推荐 根据 agent.md 定义,优先采集以下高戏剧性内容子版块: | 子版块 | 主题类型 | Min Score | 内容特征 | |--------|----------|-----------|----------| | r/AmITheAsshole | 道德困境/人际冲突 | 2000 | 二元道德判断,强冲突 | | r/relationship_advice | 情感纠纷/关系危机 | 1500 | 亲密关系中的背叛/沟通问题 | | r/funny | 喜剧/搞笑 | 5000 | 高娱乐性,适合喜剧脚本 | | r/tifu | 今日搞砸 | 3000 | 尴尬/反转叙事 | --- ## 3. 反爬策略与应对方案 ### 3.1 Reddit 反爬机制(2025) | 机制 | 表现 | 应对策略 | |------|------|----------| | **User-Agent 校验** | 默认 Python UA 返回 429/403/拦截页 | **必须**使用真实浏览器 UA 并轮换 | | **IP 频率限制** | 高频请求触发 "whoa there, pardner!" 拦截页 | 单 IP 间隔 ≥ 2~3 秒,每分钟 ≤ 20 次 | | **CF/云防护** | 返回 HTML 验证页或 503 | 增加延迟、使用优质代理、模拟完整 Headers | | **内容迁移** | 部分请求重定向到新版 UI(阻塞 JSON) | 携带 `Accept: application/json`,使用 `old.reddit.com` 降级 | | **OAuth 强制化趋势** | 商业爬取官方限制增加 | 小流量公开数据仍可用 `.json`;大规模使用 OAuth | ### 3.2 推荐爬虫配置 - **请求间隔**: 2-5 秒随机延迟(`random.uniform(2, 5)`) - **UA 轮换池**: 5+ 条真实浏览器 UA - **单次会话上限**: 20 次/分钟,超限休眠 60 秒 - **重试策略**: 遇到 429/403 时,指数退避(2s → 5s → 15s),最多 3 次 - **超时设置**: 15 秒 ### 3.3 robots.txt 合规 - Reddit `robots.txt` 限制了大量爬虫对搜索页、用户资料的抓取。 - **但公开 API 端点(`.json`)和 RSS(`.rss`)属于公开数据接口,通常不在 robots.txt 的显式禁止范围内。** - 建议遵守 `Crawl-delay: 2` 精神,不要高频请求。 --- ## 4. 数据清洗与质量控制 ### 4.1 清洗规则 1. **基础过滤**: - 按 `score >= min_score` 过滤(各子版块阈值不同) - 剔除 `is_nsfw=True`(除非业务允许) - 剔除 `[deleted]` / `[removed]` 内容 2. **内容完整性**: - `title` 不能为空 - `selftext` 为空时,标记为 `link_post` 并保留 `url` 3. **去重**: 以 `post_id` 为唯一键去重 4. **字段补齐**: - 缺失 `upvote_ratio` 时默认 `null` - 缺失 `awards` 时默认 `0` ### 4.2 Drama Score 算法参考 针对短剧素材提取场景,戏剧性评分公式建议: ```python base_drama = (min(score, 20000) / 20000) * 30 + upvote_ratio * 20 comment_density = min(num_comments / 500, 20) conflict_bonus = { "moral_dilemma": 12, "social_conflict": 10, "boundary_setting": 8, "trust_issue": 14, "betrayal": 16, "communication": 6, "observational_humor": 4, "absurdist": 5, "nostalgia": 3 }.get(conflict_type, 5) drama_score = base_drama + comment_density + conflict_bonus # 0-100 ``` ### 4.3 数据质量检查表 | 检查项 | 标准 | |--------|------| | 必填字段完整率 | `post_id`, `title`, `score`, `source_url`, `crawl_time` 必须 100% | | 数据量 | 每次采集 ≥ 50 条有效记录 | | 时效性 | `crawl_time` 精确到秒,使用 UTC | | 可追溯性 | 每条记录包含 `source_url` 和 `crawl_time` | | 内容质量 | 短剧相关子版块内容占比 ≥ 80% | --- ## 5. Reddit 短剧素材结构化提取方法论 ### 5.1 戏剧性内容识别关键词 按子版块的情绪标签提取: | 子版块 | 冲突关键词 | 情感关键词 | 典型句式 | |--------|-----------|-----------|----------| | AITA | "AITA", "WIBTA", "refused", "demanded" | guilty, justified, angry | "AITA for telling my ___ that..." | | relationship_advice | "cheating", "lying", "break up", "divorce" | betrayed, confused, heartbroken | "My partner ___ and I don't know..." | | funny | "can't stop laughing", "that's it", "found this" | amused, absurd, surprised | "___ and I can't stop laughing" | ### 5.2 结构化提取字段映射 根据 agent.md 输出格式,从 Reddit 原始字段中提取: - `source.platform` = "reddit" - `source.subreddit` = `data.subreddit` - `source.post_id` = `data.id` - `source.url` = `https://reddit.com{data.permalink}` - `engagement.upvotes` = `data.score` - `engagement.comments` = `data.num_comments` - `engagement.upvote_ratio` = `data.upvote_ratio` - `engagement.dramatic_score` = 算法计算值 - `content.title` = `data.title` - `content.body` = `data.selftext` - `content.drama_tags` = 基于 NLP/关键词的标签数组 - `content.conflict_type` = 枚举值(moral_dilemma, betrayal, social_conflict...) ### 5.3 下游脚本适配字段 | 输出字段 | 脚本字段 | 说明 | |----------|----------|------| | `drama_elements.setting` | 基于文本的地点/场景推断 | 客厅、办公室、餐厅等 | | `drama_elements.characters` | 关系实体提取 | 主角、反派、伴侣等 | | `drama_elements.conflict` | 冲突三元组 | type / trigger / escalation | | `drama_elements.dialogue_highlights` | 引语提取 | 直接引语中的金句 | | `script_potential.hook_strength` | `drama_score / 10` | 0-10 评分 | | `script_potential.viral_elements` | 标签数组 | 反转、公开处刑、真相揭露等 | --- ## 6. 合规与风险要求 ### 6.1 法律合规 - 遵守目标所在司法辖区的数据保护法规(GDPR/CCPA 等)。 - **禁止采集用户隐私信息**:私信、真实身份信息、精确地理位置。 - **遵守 Reddit API 使用条款**:公开数据可采集,但不得用于操控投票、垃圾信息发送。 - 不得将采集数据用于非法二次分发或舆论操控。 ### 6.2 平台合规 - 控制请求频率,避免对 Reddit 服务器造成压力。 - 不得使用自动化手段绕过登录墙抓取非公开内容。 - 如果进行商业级大规模采集,建议使用 Reddit 官方 API 并申请相应权限。 ### 6.3 伦理要求 - Reddit 帖子可能涉及个人敏感经历,提取短剧素材时应避免直接暴露可识别的个人信息。 - 对涉及自杀、自残、暴力的内容,增加内容安全审核,不适合直接改编为娱乐内容。 --- ## 7. 结论与执行建议 1. **主流程**: 以 `reddit.com/r/{subreddit}/hot.json` 为核心数据源,优先采集 r/AmITheAsshole、r/relationship_advice、r/funny。 2. **备用流程**: 当 JSON API 被封时,先降级到 `old.reddit.com` HTML 解析,再尝试 RSS Feed。 3. **数据提取**: 结合 `score`、`num_comments`、`upvote_ratio` 进行基础过滤,应用 drama_score 算法筛选高戏剧性内容。 4. **长期监控**: 配置定时任务(如每 2 小时),持续追加新帖到 `seed_data.json`,观察数据源稳定性。 5. **下游衔接**: 将清洗后的结构化 DramaMaterial JSON 直接交付给 Digester,进行 schema 固化和 bench 集生成。 --- *报告由 Hunter Agent 生成 | 验收标准: 数据源 ≥5 个 ✅ | 含字段映射表 ✅ | 含反爬/合规/短剧提取分析 ✅*