| name | newsbox |
| description | 使用 newsbox CLI 与 Python SDK 采集 AI 内容信源、读取 raw.db、二次加工成日报/摘要/筛选结果。涵盖信源管理(add / list / probe / test / edit / remove / seed)、日常运行(fetch / read / stats / clean)、故障处理(doctor / status / state / logs / restart)、关停(teardown)四类场景以及拿到数据后用 jq 或 SDK 做二次加工的写法。触发:用户提到「采集」「抓信源」「拉 RSS」「newsbox」「~/.newsbox/raw.db」「想看最近抓到的内容」「按昨天的采集结果写日报」「某个信源加进来」「信源没拉到东西排查一下」「docker-compose.yml 不存在」等场景,即使没明说工具名也应触发。不适用于:搭建 RSS 阅读器/订阅客户端、单篇博客网页转 markdown、通用内容阅读器——这些是别的工具的活。 Use when this capability is needed. |
| metadata | {"author":"a809384377"} |
newsbox — 工具说明书
newsbox 是「采集层」CLI + SDK:从 RSS / 网页采集 AI 信源 → 落进 ~/.newsbox/raw.db(业务投影是 articles_raw 表;另有 source_state 表记每个信源的最近抓取/失败状态,你通过 state 命令读,不需要自己直查)。它只采集,不做内容筛选 / 打分 / 摘要 / 日报(这些是消费方/agent 自己干)。
你(agent)通常做两类事:
- 运维这个工具:加信源、跑抓取、排故障
- 消费它的产出:通过 CLI/SDK 拿到文章 → 用 LLM 二次加工
下面 5 类场景按需查。命令都支持 --help 看完整参数。
数据怎么进、怎么出
上游(RSS / 网页 / RSSHub 转译的 X / Reddit)
│ newsbox fetch
▼
~/.newsbox/raw.db (articles_raw 表)
│ CLI: newsbox read --json ← 你查数据走这里
│ SDK: newsbox.sdk.read_raw() ← 在 Python 里走这里
▼
你的二次加工(LLM 摘要 / 筛选 / 写日报)
重要:不要直接 sqlite3 ~/.newsbox/raw.db "SELECT ..." 写 SQL —— 表结构会演进(已删过死字段、未来还会改),直接查 raw.db 的代码会随之坏。统一走 read --json(shell 环境)或 sdk.read_raw()(Python 环境),这两条是稳定契约。
场景 1:信源管理
加 / 看 / 改 / 删信源。信源清单存在 ~/.newsbox/sources.yaml,CLI 自动管理,不要手编 yaml。
加信源
newsbox sources add https://example.com/blog
newsbox sources add https://example.com/blog \
--tier=kol \
--domain=ai \
--id=example_blog
newsbox sources add https://example.com/blog --type=rss --tier=kol --domain=ai --id=example_blog
newsbox sources add --from-file=urls.txt
参数说明:
--tier: official_first_party / kol / secondary(信源权重,影响消费方打分)
--domain: ai 是默认;未来可能 finance 等(多领域设计)
--id: 信源唯一 id,建议小写下划线(如 simon_willison_blog)
--type: rss / web / twikit(一般不传,靠 probe 自动判定;探测不准时手动覆盖)
X (Twitter) 账号特殊:录 X 账号 URL(https://x.com/<handle> / https://twitter.com/<handle>)会被 probe 自动识别为 twikit 类型,url 字段自动归一化为裸 handle(dotey 而非完整 URL)。例:
newsbox sources add https://x.com/dotey --tier=kol --id=x_dotey
首次配置 X 信源前需生成 ~/.newsbox/twikit_cookies.json(含 auth_token + ct0),步骤见 docs/twikit-setup.md §1。
录入前先侦察
newsbox sources probe https://example.com/blog
newsbox sources probe --from-file=urls.txt
侦察用来判断「这个 url 能不能采、采到啥」,再决定要不要 add。
看信源
newsbox sources list
newsbox sources list --enabled-only
newsbox sources list --type=web --tier=kol
newsbox sources show <id>
newsbox sources export --out=backup.yaml
改 / 删
newsbox sources edit <id> --tier=official_first_party
newsbox sources rename <old_id> <new_id>
newsbox sources disable <id>
newsbox sources enable <id>
newsbox sources remove <id> --yes
newsbox sources test <id>
兜底:清单丢失时重铺种子
newsbox sources seed
newsbox sources seed --force
sources.yaml 不在或被你清空时用;正常路径不需要。
场景 2:日常运行
抓数据
newsbox fetch
newsbox fetch --since=7d
newsbox fetch --since=24h
newsbox fetch --source=rss
newsbox fetch --source=anthropic_news
newsbox fetch --concurrency=4
注意:信源更新频率天然不固定(Anthropic 一周 1-2 次很正常),--since=24h 看不到新内容 ≠ 出问题,把窗口拉到 7d 或 30d 再判断。
看数据
newsbox read
newsbox read --since=24h --json
newsbox read --since=7d --source-types=rss --domain=ai --tier=official_first_party --json
newsbox read --since=7d --source-id=anthropic_news --json
newsbox read --since=24h --limit=20 --json
newsbox read --since=24h --limit=0 --json
newsbox read --since=90d --limit=0 --yes
read 字段:id / source_type / source_id / source_tier / external_id / url / title / body / published_at / fetched_at / domain_tags / content_hash。
调用量阈值机制(重要):read 命令在执行前 COUNT(*) 预估返回行数,超过 10000 条时 stderr 打 warn 并 typer.confirm 软阻断,引导切到 SDK。四态行为:
- 交互 tty + 无
--yes + 无 --json → stderr warn + confirm 拒绝则 abort
--json 模式 → 隐含 --yes,warn 仍走 stderr,stdout 仍是干净 NDJSON(agent 管道安全)
--yes flag → stderr warn,跳过 confirm 直接执行(agent 显式覆盖)
- 非 tty + 无
--yes + 无 --json → abort + 引导文案(必须显式传其一)
阈值可在 ~/.newsbox/config.yaml 加 thresholds.cli_read_warn: <N> 覆盖默认 10000。超阈值场景优先考虑切 SDK(流式游标,无 JSON 序列化往返)—— 详见 docs/sdk-usage.md。
看统计
newsbox stats
newsbox stats --top=20
newsbox stats --json
清旧数据
newsbox clean --before=30d
newsbox clean --before=30d --yes
newsbox clean --before=30d --yes --no-vacuum
默认 dry-run 是为了防误删;想真动手必须显式 --yes。删完默认自动 VACUUM 回收磁盘。
场景 3:拿到数据后二次加工
核心场景:你抓到一批文章后要让 LLM 摘要 / 筛选 / 写日报,怎么用最稳?
路径 A:shell + jq(agent 在 bash 里跑)
newsbox read --since=7d --domain=ai --tier=official_first_party --json \
| jq -r '.title + "\t" + .url'
newsbox read --since=7d --source-id=anthropic_news --json \
| jq -r '.title'
newsbox read --since=24h --json > today.ndjson
输出是 NDJSON(每行一个 JSON 对象),不是 JSON 数组,所以用 jq 不需要 .[]。
路径 B:Python SDK(你在 Python 环境里)
from datetime import datetime, timedelta, timezone
from newsbox import sdk
since = datetime.now(timezone.utc) - timedelta(days=7)
for art in sdk.read_raw(domain="ai", since=since, source_types=["rss"]):
print(art.source_id, art.title, art.url)
read_raw() 签名:
read_raw(
domain: str = "ai",
since: datetime | None = None,
source_types: list[str] | None = None,
limit: int | None = None,
db_path: Path | None = None,
) -> Iterator[ArticleRaw]
按 (fetched_at ASC, id ASC) 排序输出。db_path 默认 ~/.newsbox/raw.db。
何时用哪种?
- 写日报 / 一次性筛选 → shell + jq 简单粗暴(一次性
read --json 子进程开销可忽略)
- 批量处理几千篇文章给 LLM 的长流水线 → Python SDK 流式游标(避免在循环里反复起 CLI 子进程,每次都重新启 Python 解释器 + 重新打开 sqlite)
content_hash 字段的用法
不同 url 但同内容(搬运 / 转载)有同样的 content_hash(基于 title + 正文前 500 字 sha256)。你可以:
- 按
content_hash 分组识别热门转载内容("被 N 家媒体转发"作为热度信号)
- 按
content_hash 去重(消费方自己决定,collector 不替你去重)
场景 4:故障处理
系统不对劲先跑 doctor
newsbox doctor
全面诊断:Docker 起没?X token 填了?数据库通吗?随机抽样信源能否抓到?
看运行状态
newsbox status
newsbox state
newsbox logs --tail=50
重启 RSSHub
newsbox restart
常见报错
docker-compose.yml 不存在 —— v0.5.1 起 compose 文件存在 home 目录,老版本升级会撞这条。修:
newsbox setup
某信源 fetched=0 —— 不一定是 bug。按顺序判断,不要先下 adapter bug 结论:
newsbox sources test <id> --limit=5 试拉一次(不入库),看能不能抓到内容
newsbox state 看连续失败次数;也可只看一类:newsbox state --source-type=rss
- 信源更新频率天然不固定,把窗口拉大单独跑:
newsbox fetch --source=<id> --since=30d
- 抓到内容但入库 0 条 → 多半是去重命中(同一信源相同 external_id 不重复入)
- 扩大窗口仍异常 → 看
newsbox logs --tail=100 与 adapter 真实样本,再下 bug 结论(不要凭"页面看着有内容"就判 adapter 错)
X / Twitter 信源失败 —— v1.0.2 起 X 走 twikit(cookie-based),不再依赖 .env 的 TWITTER_AUTH_TOKEN。newsbox doctor 看 [Twikit] panel:
twikit cookies 文件不存在 → 按 docs/twikit-setup.md §1 生成 ~/.newsbox/twikit_cookies.json
缺少 auth_token / ct0 字段 → 重新从浏览器 devtools 复制填入
- fetch 时报
TwikitAuthError(401) → auth_token 失效,重新复制(一般数月才失效一次)
- 报
TwikitRateLimitError(429) → X 限流,几小时后再试
- 报
TwikitUserUnavailableError → 账号不存在/被封,检查 url 字段拼写
完整失败矩阵见 docs/twikit-setup.md §3。
场景 5:装机与关停
首次装机
pipx install newsbox
newsbox setup
关停
newsbox teardown
数据保留是设计取舍:误删的恢复成本远高于"占点磁盘"。重装时 setup 自动接续。
配置
newsbox config init
newsbox config show
~/.newsbox/ 是运行时数据目录(不在项目里):
sources.yaml — 信源清单(顶层 rss / web / twikit 三类)
config.yaml — CLI / 抓取参数配置(含 thresholds.cli_read_warn 覆盖 read 阈值默认 10000)
.env — TWITTER_AUTH_TOKEN(容器内 RSSHub 兜底;X 主路径已走 twikit)
twikit_cookies.json — X 浏览器 cookies(v1.0.2+,auth_token + ct0;setup 生成同名 .example.json 模板)
raw.db — SQLite 采集库
docker-compose.yml — RSSHub + Redis 容器配置(v0.5.1 起)
logs/newsbox.log — 日志
给 agent 的几条经验法则
- 看到
--help 优先用 —— 命令参数会演进,--help 是单一真相源
- 机器读输出永远加
--json —— rich Table 是给人看的,正则切割会脆。信息查询类(list / show / state / status / doctor / stats)输出整块 JSON;流式列表(read / sources list)输出 NDJSON(每行一条,不是 JSON 数组)
- 错误路径走
{ok: false, message, details} schema —— 操作类命令(setup / fetch / clean / sources add / remove 等)--json 模式下成功 {ok: true, ...}、失败 {ok: false, message, ...},便于 jq -e .ok 判断
--since 默认 24h,但信源更新频率不一定每天有更新 —— 找不到内容前先把窗口拉大再判断
read 大窗口注意阈值软阻断 —— 默认 >10000 条时会 stderr warn + confirm 阻断;agent 调用要么加 --yes 显式覆盖、要么加 --json 隐含跳过;非 tty 环境必须显式传其中之一否则 abort
- 批量加信源用
--from-file= —— 别在循环里调 add,CLI 启动开销叠加
- 要做内容判断 / 写日报 / 摘要 —— 那是你的活,collector 只给你原料
Source: a809384377/newsbox — distributed by TomeVault.