修改blogwatcher-daily脚本
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
---
|
||||
name: blogwatcher-daily
|
||||
description: RSS 订阅监控 + 每日笔记生成。使用 RSSHub + feedparser 抓取 31 个订阅,自动去重并存入 SQLite,新文章追加写入 Markdown 笔记。
|
||||
version: 1.0
|
||||
description: RSS 订阅监控 + 文章导出。使用 RSSHub + feedparser 抓取 31 个订阅,自动去重并存入 SQLite;可将文章按 txt/markdown/html 三种格式导出。
|
||||
version: 1.3
|
||||
category: custom
|
||||
tags: [rss, blog, monitoring, automation]
|
||||
tags: [rss, blog, monitoring, automation, export]
|
||||
metadata:
|
||||
author: Hermes Agent
|
||||
last_updated: 2025-04-19
|
||||
last_updated: 2026-08-29
|
||||
platform: macos, ubuntu
|
||||
custom_skill_path: /Users/weishen/.hermes/skills/custom/
|
||||
installation_note: "blogwatcher-daily 脚本在 Mac mini 本地运行(依赖 feedparser)。需要 RSSHub 服务(http://192.168.3.45:1200)访问 YouTube/Bilibili 等被墙源。"
|
||||
@@ -14,7 +14,7 @@ metadata:
|
||||
|
||||
# Blogwatcher Daily
|
||||
|
||||
RSS 订阅监控 + 每日笔记生成自动化。
|
||||
RSS 订阅监控自动化,抓取后去重入库,可按 txt / markdown / html 三种格式导出。
|
||||
|
||||
## 依赖
|
||||
|
||||
@@ -22,7 +22,7 @@ RSS 订阅监控 + 每日笔记生成自动化。
|
||||
pip3 install feedparser
|
||||
```
|
||||
|
||||
> feedparser 是 Python 最成熟的 RSS 解析库,支持 RSS 1.0/2.0/Atom、任意编码、畸形 XML。
|
||||
> feedparser 是 Python 最成熟的 RSS 解析库,支持 RSS 1.0/2.0/Atom、任意编码、畸形 XML。HTML 导出使用 Python 标准库 `html.escape`,无第三方依赖。
|
||||
|
||||
## 实际抓取架构(重要)
|
||||
|
||||
@@ -48,35 +48,13 @@ curl → 目标网站
|
||||
- 已有的 RSSHub URL → 直接使用
|
||||
- 其他 → 直接访问原始 URL
|
||||
|
||||
```
|
||||
YouTube 频道 URL
|
||||
↓ 脚本自动识别并转为 RSSHub 格式
|
||||
http://192.168.3.45:1200/youtube/channel/{id}
|
||||
↓
|
||||
curl → RSSHub → YouTube
|
||||
|
||||
普通 RSS(Engadget, Slashdot 等)
|
||||
↓ 脚本直接访问(绕过 RSSHub /rss/ 路由)
|
||||
原始 RSS URL
|
||||
↓
|
||||
curl → 目标网站
|
||||
```
|
||||
|
||||
**关键发现**:RSSHub 的 `/rss/{url}` 路由不稳定(返回 RSSHub 欢迎页),
|
||||
因此普通 RSS 源直接访问,不走 RSSHub 代理。
|
||||
|
||||
脚本内部 `build_fetch_url()` 根据 URL 类型自动选择路由:
|
||||
- YouTube → RSSHub
|
||||
- 已有的 RSSHub URL → 直接使用
|
||||
- 其他 → 直接访问原始 URL
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
~/.hermes/skills/custom/blogwatcher-daily/
|
||||
├── SKILL.md # 本文件
|
||||
├── scripts/
|
||||
│ └── blogwatcher-daily.py # 主脚本
|
||||
│ └── blogwatcher-daily.py # 扫描入库 + 订阅管理 + 文章导出(单文件)
|
||||
├── subscriptions.txt # 订阅列表(name|URL)
|
||||
└── blogwatcher.db # SQLite 数据库(自动创建)
|
||||
```
|
||||
@@ -90,7 +68,7 @@ python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py
|
||||
```
|
||||
|
||||
- 扫描所有订阅,新增文章存入数据库
|
||||
- 生成今日笔记:`~/Workspace/nexus/ishenwei/blogwatcher/YYYY-MM-DD.md`
|
||||
- 控制台打印每个订阅新增文章数量及总计
|
||||
|
||||
### 添加订阅
|
||||
|
||||
@@ -115,24 +93,13 @@ python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py \
|
||||
python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py --list
|
||||
```
|
||||
|
||||
### 仅扫描(不写文件)
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py --scan-only
|
||||
```
|
||||
|
||||
### 强制回扫(`--all`)
|
||||
|
||||
```bash
|
||||
# 强制抓取每频道10篇(忽略已读状态),写入独立文件
|
||||
# 强制抓取每频道10篇(忽略已读状态)
|
||||
python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py --all
|
||||
|
||||
# 测试模式:只打印,不写文件
|
||||
python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py --scan-only --all
|
||||
```
|
||||
|
||||
- 输出文件:`~/Workspace/nexus/ishenwei/blogwatcher/all-YYYY-MM-DD.md`(**覆盖模式**,每次运行覆盖)
|
||||
- **不混入**每日报告 `YYYY-MM-DD.md`
|
||||
- 每频道最多10篇
|
||||
- 用途:历史内容回扫、测试订阅状态
|
||||
|
||||
@@ -142,6 +109,51 @@ python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py -
|
||||
python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py --mark-read
|
||||
```
|
||||
|
||||
### 导出文章(`--export`)
|
||||
|
||||
从 SQLite 里读取文章并输出到 stdout,格式通过 `--export {txt,markdown,html}` 选择:
|
||||
|
||||
```bash
|
||||
# 今天所有文章 → Markdown
|
||||
python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py --export markdown
|
||||
|
||||
# 指定日期 → HTML
|
||||
python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py \
|
||||
--export html --date 2026-08-28 > digest.html
|
||||
|
||||
# 全库最新 20 篇 → 纯文本
|
||||
python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py \
|
||||
--export txt --limit 20
|
||||
```
|
||||
|
||||
**过滤规则**(`--date` 与 `--limit` 的组合语义)
|
||||
|
||||
| 参数组合 | 行为 |
|
||||
|---------|------|
|
||||
| `--export FMT`(默认) | 今天(本地时区)的所有文章 |
|
||||
| `--export FMT --date X` | 指定日期 X 的所有文章 |
|
||||
| `--export FMT --limit N` | 忽略日期,取**全库最新 N 篇** |
|
||||
| `--export FMT --date X --limit N` | 日期 X 的最新 N 篇 |
|
||||
|
||||
**参数速查**
|
||||
|
||||
| 参数 | 说明 |
|
||||
|------|------|
|
||||
| `--export {txt,markdown,html}` | 触发导出模式并指定格式 |
|
||||
| `--date YYYY-MM-DD` | 目标日期(本地时区,默认今天) |
|
||||
| `--limit N` | 文章数上限;单独使用时忽略日期 |
|
||||
|
||||
**输出去向**
|
||||
|
||||
- 正文 → **stdout**(可直接 `> file.md` 重定向)
|
||||
- 进度 → **stderr**(`📊 N 篇文章 → FMT`)
|
||||
|
||||
**格式细节**
|
||||
|
||||
- `txt`:分频道分组,纯文本无标记,适合终端查看或管道
|
||||
- `markdown`:`## 【频道】` + `- [title](link)` + 描述引用块
|
||||
- `html`:完整 `<!DOCTYPE html>` 单文件,内嵌简洁 CSS,标题/URL/描述全部经 `html.escape` 转义(防 XSS)
|
||||
|
||||
## 添加订阅示例
|
||||
|
||||
### YouTube 频道
|
||||
@@ -182,13 +194,12 @@ python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py \
|
||||
| 配置项 | 默认值 |
|
||||
|--------|--------|
|
||||
| RSSHub 地址 | `http://192.168.3.45:1200`(可设置 `RSSHUB_URL` 环境变量覆盖) |
|
||||
| 笔记输出目录 | `~/Workspace/nexus/ishenwei/blogwatcher/` |
|
||||
| 数据库 | `~/.hermes/skills/custom/blogwatcher-daily/blogwatcher.db` |
|
||||
| 订阅列表 | `~/.hermes/skills/custom/blogwatcher-daily/subscriptions.txt` |
|
||||
|
||||
## Cron Job 设置
|
||||
|
||||
推荐每天早上 6:00 自动执行:
|
||||
推荐每天早上 6:00 自动扫描:
|
||||
|
||||
```bash
|
||||
cronjob --create \
|
||||
@@ -200,13 +211,22 @@ cronjob --create \
|
||||
|
||||
执行步骤:
|
||||
1. 加载 blogwatcher-daily 技能
|
||||
2. 运行:python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py
|
||||
3. 检查输出,确认写入的笔记文件路径
|
||||
4. 如果有新文章,简短汇总发给我"
|
||||
2. 运行扫描:python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py
|
||||
3. 汇报本次新增文章数量"
|
||||
```
|
||||
|
||||
如需**扫描 + 落盘 HTML 摘要**(例如放进 Obsidian vault 或自建 dashboard),可用原生 crontab 串起来:
|
||||
|
||||
```cron
|
||||
0 6 * * * python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py && \
|
||||
python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py \
|
||||
--export html > ~/blogwatcher/$(date +\%Y-\%m-\%d).html
|
||||
```
|
||||
|
||||
## 数据流程
|
||||
|
||||
### 扫描入库(默认命令)
|
||||
|
||||
1. **加载订阅**:从 `subscriptions.txt` 读取所有 name|URL 对
|
||||
2. **URL 路由**:`build_fetch_url()` 自动判断:
|
||||
- YouTube → 转为 `http://192.168.3.45:1200/youtube/channel/{id}`
|
||||
@@ -216,9 +236,14 @@ cronjob --create \
|
||||
4. **解析**:feedparser 提取 title、link、description、pub_date
|
||||
5. **去重**:按 link 去重,已存在则跳过
|
||||
6. **存储**:新文章存入 SQLite
|
||||
7. **输出**:**追加写入** Markdown 笔记(同一文件多次扫描不会覆盖,仅追加新链接)
|
||||
- 读取已有文件,用正则提取现有链接 → 去重
|
||||
- 新文章追加 `## 📦 新增 N 篇` 分隔块
|
||||
7. **输出**:控制台打印每个订阅新增数量与总计(不生成文件)
|
||||
|
||||
### 导出(`--export`)
|
||||
|
||||
1. **查询**:`fetch_articles()` 按 `date(fetched_at, 'localtime')` 过滤 + 可选 `LIMIT N`
|
||||
2. **分组**:`_group_by_channel()` 按 `channel_title` 分桶
|
||||
3. **格式化**:`FORMATTERS[fmt]` 分发到 `format_txt` / `format_markdown` / `format_html`
|
||||
4. **输出**:正文写 stdout,`📊 N 篇文章 → FMT` 进度写 stderr
|
||||
|
||||
## 已知问题
|
||||
|
||||
@@ -236,4 +261,5 @@ cronjob --create \
|
||||
- 每次最多取每源 10 篇(TED Talks 等除外,取 20 篇)
|
||||
- 数据库自动创建,无需手动初始化
|
||||
- OPML 文件可用 Python 解析后批量导入(参考 /wiki-ingest 流程中的 OPML 解析代码)
|
||||
- **Markdown 追加模式**:同一天多次扫描不会覆盖旧内容,仅追加新链接(去重基于 URL)
|
||||
- 导出的"今天"按**本地时区**(SQLite `date(fetched_at, 'localtime')`),不是 UTC
|
||||
- HTML 导出使用 `html.escape` 转义标题/链接/描述,可安全嵌入网页;CSS 内嵌,单文件独立可用
|
||||
|
||||
Reference in New Issue
Block a user