sreweekly.py
SRE Weekly 抓取与文章提取脚本。单文件、无外部服务依赖,专为 n8n 定时任务设计:脚本自身只负责抓取与落盘,不发送邮件、不推送通知。
功能概览
- 通过 RSS (
https://sreweekly.com/feed/) 扫描新一期 SRE Weekly - 回溯抓取历史期刊(RSS 只暴露最近 ~10 期,
--backfill直接走站点 URL 抓任意老期) - 把每期
content:encoded原样保存为 HTML - 解析出每期的所有文章条目(标题 / 链接 / 简介 / 引用 / 作者)
- 用
trafilatura抓文章原文并转 Markdown - 用
manifest.json记录每期状态,避免重复处理 - 每篇文章生成一个独立
.md文件,含 feed 简介 + 抓取的正文
安装依赖
pip3 install feedparser trafilatura
trafilatura 仅在抓文章正文时才必需;若加 --skip-fetch 只用 feed 简介,可省略。
目录结构
默认工作目录 ~/Workspace/nexus/sreweekly/(可用 --dir 覆盖):
sreweekly/
├── manifest.json # 状态记录
├── html/<id>-<日期>.html # 每期原始 HTML(feed 版 或 backfill 站点整页)
├── pages/<id>.html # backfill 抓到的站点整页缓存
├── articles/<id>/ # 每篇文章原始 HTML 缓存 + index.json 抓取日志
│ ├── 01-<slug>.html
│ └── index.json
└── markdown/<id>/ # 每期文章的 markdown 输出
├── 01-<slug>.md
└── 02-<slug>.md
用法
# 扫描 feed,新增期落盘并登记 manifest
python3 sreweekly.py
# 只探测有无新期(供 n8n 分支判断),输出 533,532 或 NONE
python3 sreweekly.py --check
# 提取指定期文章为 markdown(默认联网抓正文)
python3 sreweekly.py --extract 533
python3 sreweekly.py --extract 433..464 # 期号区间(缺失的期告警跳过,不阻断)
python3 sreweekly.py --extract latest # 最新一期
python3 sreweekly.py --extract pending # 所有未提取的期(n8n 每日推荐)
python3 sreweekly.py --extract all # 全部(配合 --force 覆盖)
# 查看状态
python3 sreweekly.py --status
python3 sreweekly.py --issues
# 回溯抓取历史期刊(绕过 RSS 只有最近 ~10 期的限制)
python3 sreweekly.py --backfill 430..533 # 抓期号 430 到 533 之间所有未登记的期
python3 sreweekly.py --backfill 1..533 # 全站回溯(500+ 期,约 12-15 分钟)
python3 sreweekly.py --backfill 450 # 只抓单期
# 回溯完再走标准提取流程:
python3 sreweekly.py --extract pending
# 或只提取回溯的那段区间:
python3 sreweekly.py --extract 430..533
选项
| 选项 | 说明 |
|---|---|
--feed URL |
RSS 地址,默认 https://sreweekly.com/feed/ |
--dir PATH |
工作目录,默认 ~/Workspace/nexus/sreweekly/ |
--force |
重新提取已提取过的期,覆盖旧 markdown |
--skip-fetch |
不抓文章正文,只使用 feed 简介 |
--force-fetch |
忽略 articles/ / pages/ 本地缓存,重新联网抓 HTML |
--sleep 秒数 |
每次抓取间隔(默认 1.5,--backfill 也遵守此参数) |
典型 n8n 流程
- Cron 触发 →
python3 sreweekly.py --check - 判断输出:非
NONE(形如533或533,534)走后续,NONE结束 python3 sreweekly.py(扫描落盘新期)python3 sreweekly.py --extract pending(抓正文 + 生成 markdown)- 下游节点读取
markdown/<id>/*.md汇总成邮件/推送
Markdown 输出示例
每篇文章一个 .md 文件:
# 文章标题
- **期号**: SRE Weekly Issue #533(2024-05-20)
- **作者**: Jane Doe
- **链接**: https://example.com/post
## 简介
(来自 feed 的原始描述与引用)
## 正文
(trafilatura 抽取的原文 markdown;失败时显示错误信息)
Manifest 字段
manifest.json 中每期条目字段:
| 字段 | 含义 |
|---|---|
id / title / url / pub_date |
期号、标题、原文链接、发布日期 |
html_file |
落盘 HTML 相对路径 |
fetched_at / extracted_at |
抓取与提取时间戳 |
extracted |
是否已提取为 markdown |
article_count |
该期文章数 |
markdown_dir |
markdown 输出目录(相对) |
articles_fetched / articles_failed |
正文抓取成功/失败数 |
source |
数据来源标记:backfill 表示由 --backfill 从站点整页抓取(feed 抓取无此字段) |
故障排查
- feed 抓取失败或为空:检查
--feed网络可达性,或 feed 结构变更 trafilatura returned empty:某些站点反爬/JS 渲染,正文段落会写入错误提示但不影响其它文章- 重跑某期:
--extract <id> --force;重新联网抓正文再加--force-fetch - 回溯抓不到某期:脚本会打印
⚠️ #<id> 抓取失败:...并继续下一期,最后汇总失败期号;对失败期号单独--backfill <id> --force-fetch重试即可 - 回溯抓到的期日期显示当天:说明页面
<a class="updated">结构变了,extract_pub_date_from_page未命中,会 fallback 到今天——不影响提取,但排序会乱