knowhow_v1.md
11.1 KB
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 清洗规则
- 基础过滤:
- 按
score >= min_score过滤(各子版块阈值不同) - 剔除
is_nsfw=True(除非业务允许) - 剔除
[deleted]/[removed]内容
- 按
- 内容完整性:
title不能为空selftext为空时,标记为link_post并保留url
- 去重: 以
post_id为唯一键去重 - 字段补齐:
- 缺失
upvote_ratio时默认null - 缺失
awards时默认0
- 缺失
4.2 Drama Score 算法参考
针对短剧素材提取场景,戏剧性评分公式建议:
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.subredditsource.post_id=data.idsource.url=https://reddit.com{data.permalink}engagement.upvotes=data.scoreengagement.comments=data.num_commentsengagement.upvote_ratio=data.upvote_ratioengagement.dramatic_score= 算法计算值content.title=data.titlecontent.body=data.selftextcontent.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. 结论与执行建议
- 主流程: 以
reddit.com/r/{subreddit}/hot.json为核心数据源,优先采集 r/AmITheAsshole、r/relationship_advice、r/funny。 - 备用流程: 当 JSON API 被封时,先降级到
old.reddit.comHTML 解析,再尝试 RSS Feed。 - 数据提取: 结合
score、num_comments、upvote_ratio进行基础过滤,应用 drama_score 算法筛选高戏剧性内容。 - 长期监控: 配置定时任务(如每 2 小时),持续追加新帖到
seed_data.json,观察数据源稳定性。 - 下游衔接: 将清洗后的结构化 DramaMaterial JSON 直接交付给 Digester,进行 schema 固化和 bench 集生成。
报告由 Hunter Agent 生成 | 验收标准: 数据源 ≥5 个 ✅ | 含字段映射表 ✅ | 含反爬/合规/短剧提取分析 ✅