借助Github Action实现友圈动态自动获取——小十友圈RSS聚合工具
目录
回归博客内容创作也有几月有余,这期间认识了很多独立博客站长,也重新联系上了一些老朋友。友链作为独立博客的宝贵财富,在快节奏的今天,能够保留这种传统意义上的网友社交形式,显得格外有意义。
这次回归以来,我发现了很多友链展示的新形式,其中通过RSS自动获取并展示好友动态就是其中之一。市面上已有一些成熟的工具,最初我使用的是 Rock-Candy-Tea/hexo-circle-of-friends 这个开源项目。但该项目功能较为复杂,而我只需要核心的RSS聚合功能,通过定时更新data.json文件,再配合前端代码解析展示朋友动态。
对我来说,需求其实很简单:通过友链页面上的网站链接以及自定义的一些链接,自动获取相关动态并生成到json文件中。因此,我开发了一个轻量级但功能完整的RSS聚合工具:小十友圈RSS聚合工具,并利用GitHub Actions实现了全自动化运行,现已在GitHub上开源。
项目地址: https://github.com/Jiosanity/xiaoten-rss.git
概述
小十友圈RSS聚合工具 是一个轻量级但功能完整的RSS聚合工具,它能够自动从友链页面抓取友链信息,发现并验证RSS源,聚合最新文章,生成标准化的JSON数据文件。通过GitHub Actions,定时自动运行,确保数据的实时性。
主要实现方式
模块化设计
小十友圈RSS聚合工具采用高度模块化的设计,确保各组件职责单一且易于维护:
FriendRSSAggregator (主控制器)
├── ConfigParser (配置解析器)
├── SiteFilter (站点过滤器)
├── LinkPageScraper (友链爬取器)
├── RSSFetcher (RSS获取器)
├── DataAggregator (数据聚合器)
└── CacheManager (缓存管理器)
数据处理流程
- 配置加载 → 读取YAML配置文件
- 友链发现 → 从友链页面爬取 + 手动配置合并
- 站点过滤 → 黑白名单机制去噪
- RSS探测 → 多级回退的Feed URL发现
- 内容获取 → 解析RSS/Atom源
- 数据聚合 → 时间排序、去重、格式化
- 结果输出 → 生成标准JSON文件
核心技术实现
1. 友链获取方式
系统支持两种友链获取方式:
自动爬取:
class LinkPageScraper:
def scrape(self, url: str) -> List[Dict[str, str]]:
# 使用CSS选择器从友链页面提取结构化数据
author_elements = soup.select(self.rules.get('author')[0].get('selector'))
# 提取名称、URL、头像信息
手动配置:
SETTINGS_FRIENDS_LINKS:
list:
- ["小十博客", "https://www.xiaoten.com/", "https://www.xiaoten.com/avatar.png"]
- ["王叨叨", "https://wangdaodao.com/", "https://cdn.xiaoten.com/friends/wangdaodao.png", "feed"]
2. 自动探测RSS源
RSS发现采用优先级策略,特别针对没有明确rss源后缀的链接,参照中文博客常见的WordPress、Typecho、Hugo等系统rss源后缀进行尝试:
def find_feed_url(self, base_url: str, custom_suffix: Optional[str] = None) -> Optional[str]:
# 1. 检查缓存
cached_url = self.cache.get_cached_feed_url(base_url)
if cached_url and self._check_feed_url(cached_url):
return cached_url
# 2. 尝试自定义后缀(如果提供)
if custom_suffix:
feed_url = urljoin(base_url_normalized, custom_suffix)
if self._check_feed_url(feed_url):
return feed_url
# 3. 尝试常见Feed后缀
for suffix in self.feed_suffixes:
feed_url = urljoin(base_url_normalized, suffix)
if self._check_feed_url(feed_url):
return feed_url
return None
3. 时间处理
针对中文博客圈常见的时间格式问题,系统实现了智能时间解析:
def get_entry_time(entry, field_priority=['published_parsed', 'updated_parsed', 'created_parsed']):
"""智能时间获取,按优先级尝试不同时间字段"""
for field in field_priority:
if hasattr(entry, field) and getattr(entry, field):
try:
return datetime(*getattr(entry, field)[:6])
except Exception:
continue
return datetime.now()
# 应用时间获取逻辑
pub_time = get_entry_time(entry, ['published_parsed', 'updated_parsed'])
update_time = get_entry_time(entry, ['updated_parsed', 'published_parsed'])
这样确保了:
- 优先使用RSS源提供的准确更新时间
- 在缺少更新时间时回退到发布时间
- 最终保证时间的合理性和准确性
- 特别处理中文博客常见的时间格式问题
4. 智能缓存与去重机制
class CacheManager:
def get_article_id(self, article: dict) -> str:
"""基于标题和发布时间生成唯一文章ID"""
key = f"{article.get('title', '')}{article.get('pub_date', '')}".encode('utf-8')
return hashlib.md5(key).hexdigest()
def is_article_seen(self, article: dict) -> bool:
"""检查文章是否已处理,避免重复"""
return self.get_article_id(article) in self.cache['article_ids']
配置文件详解
小十友圈RSS聚合工具通过setting.yaml来自定义工具运转模式:
核心配置示例
# 友链页面爬取规则:
link_page_rules:
{
author: [{ selector: ".cf-friends a", attr: "text" }], # 名称选择器
link: [{ selector: ".cf-friends a", attr: "href" }], # 链接选择器
avatar: [{ selector: ".cf-friends img", attr: "src" }], # 头像选择器
}
# 站点过滤机制:使用正则表达式定义屏蔽规则
BLOCK_SITE:
- "https://q.chyfh.com/"
- "https?://mout.me"
BLOCK_SITE_REVERSE: false # false为黑名单模式,true为白名单模式
# 数据处理策略
MAX_POSTS_NUM: 0 # 每站点最大文章数,0表示不限制
OUTDATE_CLEAN: 180 # 文章过期清理天数,180天前的文章自动过滤
GitHub Actions自动化部署
通过GitHub Actions实现完全自动化运行,确保数据实时更新:
# .github/workflows/aggregate-rss.yml
name: 聚合RSS订阅
on:
schedule:
- cron: '0 */6 * * *' # 每6小时运行一次
workflow_dispatch: # 支持手动触发
jobs:
aggregate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: 设置Python环境
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: 安装依赖
run: pip install -r requirements.txt
- name: 运行小十友圈RSS聚合工具
run: python main.py
- name: 提交更新
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add data.json
git diff --staged --quiet || git commit -m "更新小十友圈数据"
git push
输出数据格式
小十友圈RSS聚合工具生成标准化的JSON数据,便于前端直接使用:
{
"updated_at": "2025-01-15T10:30:00.123456",
"total_sites": 18,
"total_posts": 156,
"sites": [
{
"name": "小十博客",
"url": "https://www.xiaoten.com/",
"avatar": "https://www.xiaoten.com/avatar.png",
"feed_url": "https://www.xiaoten.com/feed",
"posts": [
{
"title": "文章标题",
"link": "https://www.xiaoten.com/post/123",
"description": "文章摘要内容...",
"pub_date": "2025-01-15T08:00:00",
"updated_at": "2025-01-15T09:30:00",
"author": "作者名",
"site_name": "小十博客",
"site_url": "https://www.xiaoten.com/",
"avatar": "https://www.xiaoten.com/avatar.png"
}
]
}
],
"all_posts": [...],
"failed_sites": [
{
"name": "示例站点",
"url": "https://example.com/",
"feed_url": "https://example.com/feed",
"reason": "HTTP 404"
}
]
}
后续使用
- 前端集成:生成的
data.json可直接被静态站点调用 - 通知扩展:可集成Webhook实现更新通知
- 数据备份:重要数据建议定期备份到其他存储
- 主题适配:根据自己博客主题调整输出格式
欢迎Star:如果你觉得这个项目对你有帮助,请给项目一个Star支持!
© 转载需附带本文链接,依据 CC BY-NC-SA 4.0 发布。