Friend-Circle-Lite:轻量友链朋友圈
2024-08-05更新:分开前端分支
2024-08-12更新:添加自部署简单教程:点击跳转
碎碎念
前两天,友链朋友圈由于版本原因导致无法继续使用,在和朋友安小歪交流之后,最终修好了,结果不到一个小时之后,友圈就推送了新的更新,但是在经过我尝试,并没有成功部署,有一些看不懂的报错,很烦,于是突发奇想,为什么我不能自己写一个呢?说干就干,在查看了很多资料和参考了原版的友链朋友圈后,去掉了一些我不需要的功能,仅保留核心功能,随机api和作者文章卡片均在前端实现,最终达到了很好的效果,爬取的也非常快。并且在探索的过程中,偶然看到了github api,突发奇想,将issue邮箱订阅集成到了项目中,最终也实现了功能。
这篇文章本来说的是回家后再写,结果byd火车半路调头了是我没想到的,一觉起来又回武汉了……没办法,只能买过两天的高铁咯,这篇也拖了很久了,干脆一起写了吧!
研发过程
项目的起因来自于友链朋友圈的版本问题,由于pip升级,导致很多的包都用不了了,只能一个个慢慢升级,虽然后面解决了,但是总感觉这样不是办法,因为代码是我的我也没办法维护,并且苦于前端bundle.js文件大小已久,于是我决定自己搞一个简易版,只保留我需要的功能,并且尽可能简化代码使文件缩小,最终而达到了我的目的。
刚开始,朋友安小歪搞了一个邮箱推送友圈更新的程序,于是开启了本次旅程,首先我想实现的就是友圈,并且为了兼容性我考虑了原版fc的通用格式1,以便于更好的过度,经过了几天的奋斗后,终于实现了基本功能。
在和朋友聊天的过程中,意外的想到了洪哥用的竹白,但是很可惜,好像并不对我开放,于是我想,能不能用GitHub action实现一个邮箱推送的功能呢?python可以发邮箱的呀!说干就干,为了他人的方便订阅,我用了issue的方式实现,如果不想订阅了可以随时删除issue,方便访客自行控制订阅,不会出现订阅了没法取消的尴尬情况……
至于邮箱推送所有的友圈文章更新,这个对于我来说作用好像并不大,于是我没有实现,但是保留了接口,后面如果需要可以实现一下嘿嘿。
项目介绍
- 爬取文章: 爬取所有友链的文章,结果放置在根目录的all.json文件中,方便读取并部署到前端。
- 邮箱推送更新(对作者推送所有友链更新): 作者可以通过邮箱订阅所有rss的更新(未来开发)。
- issue邮箱订阅(对访客实时推送最新文章邮件): 基于
GitHub issue的博客更新邮件订阅功能,游客可以通过简单的提交issue进行邮箱订阅站点更新,删除对应issue即可取消订阅。 - 自部署: 本项目支持自部署,通过较为简洁的方式实现在服务器上获取数据并返回,同时可以合并github 获取的数据,实现更高的准确率。
展示页面
欢迎在评论区提交你的站点并展示在这里!
特点介绍
- 轻量化:对比原版友链朋友圈的功能,该友圈功能简洁,去掉了设置和fastAPI的臃肿,仅保留关键内容。
- 无数据库:因为内容较少,我采用
json直接存储文章信息,减少数据库操作,提升action运行效率。 - 部署简单:原版友链朋友圈由于功能多,导致部署较为麻烦,本方案仅需简单的部署action即可使用,vercel仅用于部署前端静态页面和实时获取最新内容。
- 文件占用:对比原版
4MB的bundle.js文件大小,本项目仅需要5.50KB的fclite.min.js文件即可轻量的展示到前端。 - 前端分离: 将前后端分离,前端文件放在page分支,后端文件放在主分支
功能概览
- 文章爬取:实现友圈基本功能。
- 暗色适配:适配本站暗色主题,理论上所有类
butterfly主题均适配。 - 显示作者所有文章:点击作者头像即可弹出窗口并显示所有文章
- 随机钓鱼:通过前端实现的随机访问。
- 邮箱推送:可以向订阅者邮箱推送网站更新。
- 邮箱模板:内置简单邮箱模板,支持自定义。
- 自部署(2024-08-11添加)
- 前端单开分支(2024-09-05添加) @CCKNBC
爬取服务部署
由于为了追求简单,我并没有实现从页面直接爬取友链信息,仅仅实现了从固定json格式中获取信息,所以我们先讲解一下怎么获取这种格式的json。
json获取
下面就是该json格式的文件示例:
1 | { |
由于主题较多,这里我仅实现了hexo-theme-butterfly获取该格式的json方法,其余主题可以根据自己的友链格式针对性实现代码。
首先,在博客根目录添加文件link.js,写入以下代码:
1 | const YML = require('yamljs') |
按照需求修改其中的黑名单,该黑名单可以用于排除一些采集站之类的灌水文章,其中填写对应站点的名称,然后再在根目录执行:
1 | node link.js |
你将会在source文件中发现文件friend.json,即为对应格式文件,下面正常hexo三件套即可放置到网站根目录。
为了更加方便,可以在博客根目录添加运行脚本:
1 | @echo off |
地址改成自己的,上传时仅需双击即可完成。如果是github action,可以在hexo g脚本前添加即可完整构建,注意需要安装yaml包才可解析yml文件,请在执行前额外添加对应npm包下载命令,如下是一个示例:
如果一切正常,在你的网站根目录将会出现一个friend.json文件,这个就是我们需要的json啦!
哪怕你不需要轻量友圈,我也推荐你使用json格式生成并填入到友链朋友圈的对应配置中,首先,json文件的读取速度比网站快很多,并且不需要解析页面格式,可以更加快捷的实现爬取,其次,json文件有效文本密度大,比直接爬取友链页面更加节省流量。
action配置
前置工作
Fork 本仓库:
点击页面右上角的 Fork 按钮,将本仓库复制到你自己的GitHub账号下。配置 Secrets:
在你 Fork 的仓库中,依次进入Settings->Secrets->New repository secret,添加以下 Secrets:PAT_TOKEN: (2024-09-05更新)已弃用,无需添加。SMTP_PWD: SMTP 服务器的密码,用于发送电子邮件。
配置action权限:
在设置中,点击
action,拉到最下面,勾选Read and write permissions选项并保存,确保action有读写权限。启用 GitHub Actions:
GitHub Actions 已经配置好在仓库的.github/workflows/*.yml文件中,当到一定时间时将自动执行,也可以手动运行。
其中,每个action功能如下:friend_circle_lite.yml实现核心功能,爬取并发送邮箱;deal_subscribe_issue.yml处理固定格式的issue,打上固定标签,评论,并关闭issue;
设置issue格式:
这个我已经设置好了,你只需要进行自定义即可。
配置选项
如果需要修改爬虫设置或邮件模板等配置,需要修改仓库中的
config.yaml文件:爬虫相关配置(必选)
使用requests库实现友链文章的爬取,并将结果存储到根目录下的all.json文件中。1
2
3
4
5
6
7spider_settings:
enable: true
json_url: "https://blog.liushen.fun/friend.json"
article_count: 5
merge_result:
enable: true
merge_json_url: "https://fc.liushen.fun"enable:开启或关闭,默认开启;json_url:友链朋友圈通用爬取格式第一种,填写上面生成的json文件网络地址即可。article_count:每个作者留存文章个数,建议不要太多,五个正好合适。marge_result:是否合并多个json文件,若为true则会合并指定网络地址和本地地址的json文件,建议在自部署部分使用,如果你有多个结果需要合并也可以使用,该部分需要/all.json和/errors.json地址可访问。enable:是否启用合并功能,该功能提供与自部署的友链合并功能,可以解决服务器部分国外网站,服务器无法访问的问题marge_json_path:请填写网络地址的json文件,用于合并,不带最后的斜杠!!!
邮箱推送功能配置(可选)
暂未实现,预留用于将每天的友链文章更新推送给指定邮箱。1
2
3
4
5email_push:
enable: false
to_email: recipient@example.com
subject: "今天的 RSS 订阅更新"
body_template: "rss_template.html"暂未实现:该部分暂未实现,由于感觉用处不大,保留接口后期酌情更新。
邮箱 issue 订阅功能配置(可选)
通过 GitHub issue 实现向提取的所有邮箱推送博客更新的功能。1
2
3
4
5rss_subscribe:
enable: true
github_username: willow-god
github_repo: Friend-Circle-Lite
your_blog_url: https://blog.liushen.fun/enable:开启或关闭,默认开启,如果没有配置请关闭。github_username:github用户名,用来拼接github api地址github_repo:仓库名称,作用同上。your_blog_url:用来定时检测rss中是否有最新文章,如果有,将触发邮箱通知并更新最新的文章到对应目录下。SMTP 配置(可选)
使用配置中的相关信息实现邮件发送功能。1
2
3
4
5smtp:
email: 3162475700@qq.com
server: smtp.qq.com
port: 587
use_tls: trueemail:发件人邮箱地址server:SMTP服务器地址port:SMTP端口号use_tls:是否使用tls加密这部分讲解起来较为复杂,请自行寻找相关资料进行学习并配置。
特定RSS地址(可选)
1
2
3
4
5specific_RSS:
- name: "Redish101"
url: "https://reblog.redish101.top/api/feed"
# - name: "無名小栈"
# url: "https://blog.imsyy.top/rss.xml"name:友链名称,需要严格匹配url:该友链对应RSS地址该部分可以添加多个,如果不需要也可以置空。
测试
由于在action中请求了github api,有较为严格的限额,所以我将更新后自动执行action的触发器关掉了,防止多次重复请求,你可以自行点击并运行action,如果在Check RSS feeds部分中,获取到了文章:
并且正常提交到仓库中,则基本实现友链朋友圈功能。你可以在仓库根目录下找到all.json文件,里面即为所有的文章,程序已经按照时间顺序进行排序。
如果你还启用了邮件提醒,你可以尝试提交issue,格式如下图所示:
如果格式正确,action将自动添加tags,回复并关闭issue,可以尝试删除rss_subscribe文件夹下的last_articles.json中文件内容,使下次对比有新文章出现,触发邮件通知。
模板修改(可选)
为了美观,我编写了一个简单的邮件模板,样式如下:
你可以尝试修改email_template.html文件以达到你想要的效果,这里不再详细解释。
前端部署
静态网站部署
现在我们所需要的内容都在all.json中,为了及时的获取到文件内容并且获得良好的网络体验,我们可以选择vercel或者zeabur,将其部署为静态网站,注意,一定要部署到page分支上!
vercel部署完成后,检查对应页面,如果页面中没有数据,且/all.json路径无法访问可能是部署到main分支了,可以通过setting-git-Production Branch,填写为page并重新进行部署即可zeabur可以在部署时直接选择分支:CloudFlare Page也可以在构建时即选择对应的分支,这里不再细讲。
在仓库更新后,vercel或者zeabur也会同步更新,这样就达到了定时更新的效果。本项目提供了一个简单的前端展示页面,地址如下:
这样,我们就可以通过地址https://fc.liushen.fun/all.json访问到你的文章内容,并且因为文件非常小,访问体验也非常不错,并且不会因为频繁请求不同api而过量使用vercel提供的edge requests次数。
部署到页面
下面在你的页面md文件中直接放置以下内容:
1 | <div id="friend-circle-lite-root"></div> |
注意其中的private_api_url尾部需要/防止拼接路径时出现错误。
hexo三联后,即可查看效果,本站部署的页面你可以通过顶部导航栏直接进入查看效果。
自部署
如果你有一台境内服务器,你也可以通过以下操作将其部署到你的服务器上,以提高网站爬取的准确率。操作如下:
前置工作
确保你的服务器有定时任务 crontab 功能包,一般是linux自带,如果你没有宝塔等可以管理定时任务的面板工具,可能需要你自行了解定时工具并导入,本教程提供了简单的介绍。
首先克隆仓库并进入对应路径:
1 | git clone https://github.com/willow-god/Friend-Circle-Lite.git |
由于不存在issue,所以不支持邮箱推送(主要是懒得分类写了,要不然还得从secret中获取密码的功能剥离QAQ),请将除第一部分抓取以外的功能均设置为false
下载服务相关包,其中 requirements-server.txt 是部署API服务所用包, requirements.txt 是抓取服务所用包,请均下载一遍。
1 | pip install -r ./requirements.txt |
部署API
如果环境配置完毕,你可以进入目录路径后直接运行deploy.sh脚本启动API服务:
1 | chmod +x ./deploy.sh |
其中的注释应该是较为详细的,如果部署成功你可以使用以下命令进行测试,如果获取到了首页html内容则成功:
1 | curl 127.0.0.1:1223 |
这个端口号可以修改,在server.py最后一行修改数字即可,如果你想删除该API服务,可以使用ps找到对应进程并使用Kill命令杀死进程:
1 | ps aux | grep python |
合并数据
你是不是以为github数据没用了?并不是!因为有很多站长是使用的GitHub page等服务部署的,由于网络原因,这种服务可能无法被你的境内服务器抓取,此时你就需要合并两个的爬取数据。修改第一个配置中的以下部分:
1 | merge_result: |
其中地址项不要添加最后的斜杠,这样就会在本地爬取结束后合并远程的数据,以做到更高的准确率!
定时抓取
由于原生的crontab可能较为复杂,如果有兴趣可以查看./deploy.sh文件中,屏蔽掉的部分,这里我不会细讲,这里我主要讲解宝塔面板添加定时任务,这样可以最大程度减少内存占用,其他面板服务类似:
点击宝塔右侧的定时任务后,点击添加,按照上图配置,并在命令中输入:
1 | cd /www/wwwroot/Friend-Circle-Lite |
具体地址可以按照自己的需要进行修改,这样我们就可以做到定时修改文件内容了!然后请求api就是从本地文件中返回所有内容的过程,和爬取是分开的,所以并不影响!
效果展示
如果你对效果不满意,本项目还提供未压缩的css源码,在项目的main文件夹中,你可以自行修改并托管。


























