91 lines
3.5 KiB
Markdown
91 lines
3.5 KiB
Markdown
# SRE Weekly Digest
|
||
|
||
抓取 [SRE Weekly](https://sreweekly.com) 每期内容,把其中分享的文章逐篇导出为 Markdown,
|
||
供后续阅读/筛选/邮件分发使用。脚本由 **n8n 定时调用**,通过不同参数驱动;脚本自身**不发送邮件**。
|
||
|
||
- 脚本: `scripts/sreweekly.py`(单文件,仅依赖 `feedparser`)
|
||
- 依赖: `pip3 install feedparser`
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
sreweekly/
|
||
├── manifest.json # 每期状态:html 是否保存、文章是否已提取、文章数
|
||
├── html/<期号>-<日期>.html # 每期原始 HTML(feed 的 content:encoded 原样保存)
|
||
└── markdown/<期号>/ # 每篇文章一个 .md 文件
|
||
├── 01-<标题>.md
|
||
└── ...
|
||
```
|
||
|
||
## 命令一览
|
||
|
||
```bash
|
||
python3 scripts/sreweekly.py # 扫描 feed,新增期保存 HTML + 登记 manifest
|
||
python3 scripts/sreweekly.py --check # 检查有无新期 → 输出 NEW:533,532 或 NONE
|
||
python3 scripts/sreweekly.py --extract 533 # 提取指定期文章 → markdown/533/
|
||
python3 scripts/sreweekly.py --extract latest # 提取最新一期
|
||
python3 scripts/sreweekly.py --extract pending # 提取所有尚未提取的期(每日流程推荐)
|
||
python3 scripts/sreweekly.py --extract all # 提取全部(已提取过需加 --force 覆盖)
|
||
python3 scripts/sreweekly.py --status # 打印状态表
|
||
python3 scripts/sreweekly.py --issues # 列出所有已登记期
|
||
|
||
# 可选参数
|
||
--feed <URL> # RSS 地址(默认 https://sreweekly.com/feed/)
|
||
--dir <PATH> # 工作目录(默认本目录)
|
||
--force # 强制重新提取
|
||
```
|
||
|
||
所有命令**幂等**:重复扫描不重复入库,重复提取自动跳过已提取的期。
|
||
|
||
## n8n 每日流程(推荐 3 步)
|
||
|
||
该刊每周一更新,建议每天定时跑一次,有新期才继续:
|
||
|
||
1. **Execute Command(扫描)**
|
||
```
|
||
python3 /Users/weishen/Workspace/nexus/Hermes/xingzhi/sreweekly/scripts/sreweekly.py --dir /Users/weishen/Workspace/nexus/Hermes/xingzhi/sreweekly
|
||
```
|
||
2. **Execute Command(提取未处理期)**
|
||
```
|
||
python3 .../sreweekly.py --dir ... --extract pending
|
||
```
|
||
(或先用 `--check` 判断 `NEW:`/`NONE` 再分支,`--extract pending` 本身也天然幂等,空跑无害)
|
||
|
||
3. **后续节点(邮件)**:读取 `markdown/<新期号>/` 下的 .md 文件,
|
||
用 n8n 的 Email / 自定义 AgentMail 节点发送(示例发件收件:star-agent@agentmail.to → billyshen@163.com)。
|
||
|
||
参考输出(`--check`,可直接作为 n8n IF 条件):
|
||
```
|
||
NEW:533,532 ← 有新期
|
||
NONE ← 无更新
|
||
```
|
||
|
||
## manifest.json 示例
|
||
|
||
```json
|
||
{
|
||
"feed": "https://sreweekly.com/feed/",
|
||
"last_scanned": "2026-09-10T07:40:50",
|
||
"issues": {
|
||
"533": {
|
||
"id": "533",
|
||
"title": "SRE Weekly Issue #533",
|
||
"url": "https://sreweekly.com/sre-weekly-issue-533/",
|
||
"pub_date": "2026-09-07",
|
||
"html_file": "html/533-2026-09-07.html",
|
||
"fetched_at": "2026-09-10T07:40:50",
|
||
"extracted": true,
|
||
"article_count": 8,
|
||
"markdown_dir": "markdown/533",
|
||
"extracted_at": "2026-09-10T07:41:10"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 说明
|
||
|
||
- SRE Weekly 的 feed 已在 `content:encoded` 字段携带每期完整 HTML,无需再抓每期页面。
|
||
- 页面结构:每篇分享文章是 `<div class="sreweekly-entry">`(标题链接 + 简介 + 作者),
|
||
赞助商段落(`sreweekly-sponsor-message`)自动跳过。
|
||
- 提取后每篇 md 内容:标题、期号/日期、作者、原文链接、简介(含 blockquote 引用)。 |