fatelessdev/siphon
GitHub: fatelessdev/siphon
基于 cookie 认证的 Twitter/X 时间线采集引擎,通过 GitHub Actions 定时调度,将推文数据规范化存储至 PostgreSQL,专为下游消费场景设计。
Stars: 0 | Forks: 0
# Siphon
Twitter/X 采集引擎。通过身份验证,从你的时间线抓取、解析推文,并将其存储到 PostgreSQL 中。
**MVP 状态:** 只读模式,通过 GitHub Actions 定时调度,专为下游消费者设计。
## 功能介绍
Siphon 作为 GitHub Actions 的定时任务(每小时执行一次)运行,具体功能如下:
1. 使用你的 cookies 对 Twitter/X 进行身份验证
2. 获取“为你推荐”信息流和“关注”信息流
3. 采用防御性且对模式具备弹性的解析方式处理推文
4. 规范化文本(Unicode NFKC、HTML 解码、智能引号)
5. 将精简的推文数据 upsert(插入或更新)到 PostgreSQL 中
6. 记录每次运行的完整可观测性数据(解析统计、错误、隐蔽状态)
## 架构
```
GitHub Actions (cron) → Siphon CLI → GraphQL Engine → Parser → PostgreSQL
↓
Downstream (Sigil, etc.)
```
- **单一引擎,双重身份验证模式:** 对所有请求使用带有 Chrome TLS 模拟的 curl_cffi
- **隐蔽性:** 逼真的浏览器请求头,x-client-transaction-id(允许软失败),仿人类的随机延迟
- **解析器:** 处理 TimelineTimelineItem、TimelineTimelineModule、TweetWithVisibilityResults、tombstones(已删除推文提示)、转发、引用、note_tweet(长推文)、articles(文章),并丢弃推广/广告内容
- **存储:** PostgreSQL,包含精简的推文数据和已建立索引的规范化文本
## 快速开始
### 1. Fork/克隆并安装
```
cd siphon
pip install -e ".[dev]"
```
### 2. 设置环境变量
```
cp .env.example .env
# 使用你的 Twitter cookies 和 DATABASE_URL 编辑 .env
```
### 3. 运行数据库迁移
```
python -m siphon db migrate
```
### 4. 验证身份验证
```
python -m siphon healthcheck-auth
```
### 5. 运行抓取
```
python -m siphon scrape following --count 30
python -m siphon scrape home --count 50
```
### 6. 设置 GitHub Actions
1. 添加仓库密钥:
- `TWITTER_AUTH_TOKEN` — 你的 auth_token cookie
- `TWITTER_CT0` — 你的 ct0 cookie
- `TWITTER_COOKIE_STRING` — 可选的完整浏览器 Cookie 请求头,匹配 `twitter-cli` 的 browser-cookie 模式
- `DATABASE_URL` — 你的 PostgreSQL 连接字符串(使用 Neon 直连,而非连接池模式)
2. 工作流会通过 cron 自动每小时运行一次
3. 可在 Actions 标签页手动触发
## 命令
| 命令 | 描述 |
|---------|-------------|
| `python -m siphon scrape scheduled` | 运行默认的定时抓取(“为你推荐”+“关注”) |
| `python -m siphon scrape for-you --count 30` | 抓取“为你推荐”信息流 |
| `python -m siphon scrape following --count 30` | 抓取“关注”信息流 |
| `python -m siphon scrape home --count 50` | 抓取主页时间线 |
| `python -m siphon db migrate` | 应用数据库迁移 |
| `python -m siphon healthcheck-auth` | 验证 Twitter 凭证 |
## 数据库模式
### tweets
存储解析后的推文数据,支持全文搜索和紧凑的上下文。
| 字段 | 类型 | 描述 |
|-------|------|-------------|
| id | BIGINT | 推文雪花 ID(主键) |
| author_id | BIGINT | 稳定的用户 ID,用于后续的关注/资料抓取操作 |
| author_handle | VARCHAR | @用户名 |
| text | TEXT | 规范化的文本,已建立全文搜索索引 |
| reply_to_tweet_id/reply_to_author_handle/reply_to_text | mixed | 可用时提供的紧凑回复上下文 |
| quoted_tweet_id/quoted_author_handle/quoted_text | mixed | 可用时提供的紧凑引用上下文 |
| urls/media_urls | JSONB | 展开的链接和媒体引用 |
| scraped_at | TIMESTAMPTZ | 该推文的采集时间 |
### scrape_runs
跟踪每次抓取的执行情况以提供可观测性。
### scrape_locks
通过咨询锁和基于租约的锁防止重复运行。
## 下游集成
Siphon 负责写入推文。Sigil 负责读取推文。它们的边界就是数据库。
Sigil 可以查询未处理的推文:
```
SELECT * FROM tweets
WHERE scraped_at > NOW() - INTERVAL '24 hours'
ORDER BY scraped_at ASC
LIMIT 100;
```
Siphon 并不了解 Sigil 的提示词、评分或分析逻辑。
## MVP 非目标
- 无写入操作(发帖、点赞、转发等)
- 无 FastAPI 服务器 / 常驻服务
- 无 Docker 部署要求
- 无多账号轮换
- 无代理系统
- 无公开资料抓取 / 游客模式
- 无关键字搜索
- 无文章提取(框架已存在,但未接入)
## 隐蔽技术栈
| 层级 | 状态 |
|-------|--------|
| curl_cffi Chrome TLS 模拟 | 启用 |
| 逼真的浏览器 sec-ch-ua 请求头 | 启用 |
| x-client-transaction-id | 软失败(不可用时降级) |
| 仿人类随机延迟 (±20%) | 启用 |
| 日志机密信息脱敏 | 启用 |
| 保守的速率限制 | 启用(遇到 429 状态码时停止) |
## 许可证
私有仓库 — 禁止重新分发。
标签:curl_cffi, GitHub Actions, GraphQL, PostgreSQL, Python, TLS指纹模拟, Twitter, X, 代码示例, 匿名抓取, 反检测, 命令控制, 定时任务, 开源, 数据分析, 数据库迁移, 数据摄取, 数据泄露, 数据采集, 无后门, 测试用例, 社会化媒体, 网络调试, 自动化, 自动笔记, 舆情监控, 逆向工具