😮使用GitHub api提取到数据,实现提取函数以及对比更新函数

This commit is contained in:
柳神 2024-07-02 21:48:56 +08:00
parent 9479a6e5a0
commit cdac25869c
12 changed files with 264 additions and 3 deletions

View File

@ -4,3 +4,20 @@ spider_settings:
json_url: "https://blog.qyliu.top/friend.json" # 请填写对应格式json的地址仅支持网络地址 json_url: "https://blog.qyliu.top/friend.json" # 请填写对应格式json的地址仅支持网络地址
article_count: 5 # 请填写每个博客需要获取的最大文章数量 article_count: 5 # 请填写每个博客需要获取的最大文章数量
# 邮箱推送功能配置
email_push:
enabled: true # 是否启用邮箱推送功能
to_email: recipient@example.com # 收件人邮箱地址
subject: "今天的 RSS 订阅更新" # 邮件主题
body_template: "rss_template.html" # 邮件正文的 HTML 模板文件
# SMTP 配置
smtp:
email: your_email@example.com # 发件人邮箱地址
server: smtp.example.com # SMTP 服务器地址
port: 587 # SMTP 端口号
use_tls: true # 是否使用 TLS 加密
username: your_smtp_username # SMTP 用户名
password: your_smtp_password # SMTP 密码

View File

@ -0,0 +1,44 @@
{
"articles": [
{
"title": "东软软件园实习日记",
"author": "",
"link": "https://blog.qyliu.top/posts/13e6e155/",
"published": "2024-07-01 08:39",
"summary": "大学生累成狗,今天我终于理解了为什么这么说,好不容易结束了为期七天的实训课程,又要写实验报告加小组作业,好不容易完成了小组作业,这不,十五天实习又来了!烦!并且还要天天写学习日志?我直接当作日记写好不好!",
"content": "大学生累成狗,今天我终于理解了为什么这么说,好不容易结束了为期七天的实训课程,又要写实验报告加小组作业,好不容易完成了小组作业,这不,十五天实习又来了!烦!并且还要天天写学习日志?我直接当作日记写好不好!"
},
{
"title": "Github Action实现友链状态检测",
"author": "",
"link": "https://blog.qyliu.top/posts/c2262998/",
"published": "2024-06-23 17:00",
"summary": "随着友情链接数量的增加人工检测变得繁琐我最初尝试通过爬取数据进行检测但数据更新滞后。在群友安小歪的启发下我采用了GitHub Action自动运行检测脚本比较有效实现了友链有效性的自动化监测同时将数据展示在了友情链接页面中除此之外原有的摸鱼页面也被我整合到了友链朋友圈页面中。",
"content": "随着友情链接数量的增加人工检测变得繁琐我最初尝试通过爬取数据进行检测但数据更新滞后。在群友安小歪的启发下我采用了GitHub Action自动运行检测脚本比较有效实现了友链有效性的自动化监测同时将数据展示在了友情链接页面中除此之外原有的摸鱼页面也被我整合到了友链朋友圈页面中。"
},
{
"title": "安全跳转页面·插件版",
"author": "",
"link": "https://blog.qyliu.top/posts/1dfd1f41/",
"published": "2024-06-16 17:00",
"summary": "经过两个月的努力我终于找到了完美的外链跳转解决方案初始版本使用外置JS存在诸多bug如图片灯箱、友链和站内跳转链接等问题。经过一段时间的学习和代码调整我取得了阶段性进展现在能够实现各种所需功能。最近我在hexo-external-link插件的基础上进行了底层重构最终实现了真正的插件版外链替换不再依赖JS功能更加完善且使用更加方便",
"content": "经过两个月的努力我终于找到了完美的外链跳转解决方案初始版本使用外置JS存在诸多bug如图片灯箱、友链和站内跳转链接等问题。经过一段时间的学习和代码调整我取得了阶段性进展现在能够实现各种所需功能。最近我在hexo-external-link插件的基础上进行了底层重构最终实现了真正的插件版外链替换不再依赖JS功能更加完善且使用更加方便"
},
{
"title": "Alist宝塔部署及其美化",
"author": "",
"link": "https://blog.qyliu.top/posts/a84f5e47/",
"published": "2024-06-04 11:24",
"summary": "Alist 是一个轻量级的目录列表程序,可以用于管理文件索引。将 Alist 部署在宝塔面板中,并进行美化,可以提升用户体验。在本教程中,将介绍我的部署经过,并给出相应的美化代码。",
"content": "Alist 是一个轻量级的目录列表程序,可以用于管理文件索引。将 Alist 部署在宝塔面板中,并进行美化,可以提升用户体验。在本教程中,将介绍我的部署经过,并给出相应的美化代码。"
},
{
"title": "计算机网络期末总复习",
"author": "",
"link": "https://blog.qyliu.top/posts/8dfa25e1/",
"published": "2024-05-30 16:48",
"summary": "应该注意到标题的改变了吧本来是一章节一章节的复习奈何我突然发现老师画的重点和考研的重点并不是很符合没办法咯于是我决定将计算机网络考研复习部分的内容暂时搁置后面逐步更新反正一定是会更新的因为408必考呀然后将期末复习内容先整理出来按照老师的考点进行复习。",
"content": "应该注意到标题的改变了吧本来是一章节一章节的复习奈何我突然发现老师画的重点和考研的重点并不是很符合没办法咯于是我决定将计算机网络考研复习部分的内容暂时搁置后面逐步更新反正一定是会更新的因为408必考呀然后将期末复习内容先整理出来按照老师的考点进行复习。"
}
]
}

View File

@ -195,6 +195,66 @@
"print(f\"feedparser 版本: {feedparser.__version__}\")\n" "print(f\"feedparser 版本: {feedparser.__version__}\")\n"
] ]
}, },
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# 将系统路径设置为../\n",
"import sys\n",
"sys.path.append(\"../\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"emails\": [\n",
" \"3162475700@qq.com\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"from rss_subscribe.push_article_update import extract_emails_from_issues\n",
"import json\n",
"\n",
"api_url = \"https://api.github.com/repos/willow-god/Friend-Circle-Lite/issues\"\n",
"emails = extract_emails_from_issues(api_url)\n",
"print(json.dumps(emails, indent=2))"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"从 https://blog.qyliu.top/ 获取到 5 篇文章,其中 0 篇为新文章\n",
"None\n"
]
}
],
"source": [
"from rss_subscribe.push_article_update import get_latest_articles_from_link\n",
"import json\n",
"\n",
"url = \"https://blog.qyliu.top/\"\n",
"articles = get_latest_articles_from_link(url, last_articles_path=\"../rss_subscribe/last_articles.json\")\n",
"print(articles)"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,

View File

View File

View File

Binary file not shown.

View File

@ -0,0 +1,44 @@
{
"articles": [
{
"title": "东软软件园实习日记",
"author": "",
"link": "https://blog.qyliu.top/posts/13e6e155/",
"published": "2024-07-01 08:39",
"summary": "大学生累成狗,今天我终于理解了为什么这么说,好不容易结束了为期七天的实训课程,又要写实验报告加小组作业,好不容易完成了小组作业,这不,十五天实习又来了!烦!并且还要天天写学习日志?我直接当作日记写好不好!",
"content": "大学生累成狗,今天我终于理解了为什么这么说,好不容易结束了为期七天的实训课程,又要写实验报告加小组作业,好不容易完成了小组作业,这不,十五天实习又来了!烦!并且还要天天写学习日志?我直接当作日记写好不好!"
},
{
"title": "Github Action实现友链状态检测",
"author": "",
"link": "https://blog.qyliu.top/posts/c2262998/",
"published": "2024-06-23 17:00",
"summary": "随着友情链接数量的增加人工检测变得繁琐我最初尝试通过爬取数据进行检测但数据更新滞后。在群友安小歪的启发下我采用了GitHub Action自动运行检测脚本比较有效实现了友链有效性的自动化监测同时将数据展示在了友情链接页面中除此之外原有的摸鱼页面也被我整合到了友链朋友圈页面中。",
"content": "随着友情链接数量的增加人工检测变得繁琐我最初尝试通过爬取数据进行检测但数据更新滞后。在群友安小歪的启发下我采用了GitHub Action自动运行检测脚本比较有效实现了友链有效性的自动化监测同时将数据展示在了友情链接页面中除此之外原有的摸鱼页面也被我整合到了友链朋友圈页面中。"
},
{
"title": "安全跳转页面·插件版",
"author": "",
"link": "https://blog.qyliu.top/posts/1dfd1f41/",
"published": "2024-06-16 17:00",
"summary": "经过两个月的努力我终于找到了完美的外链跳转解决方案初始版本使用外置JS存在诸多bug如图片灯箱、友链和站内跳转链接等问题。经过一段时间的学习和代码调整我取得了阶段性进展现在能够实现各种所需功能。最近我在hexo-external-link插件的基础上进行了底层重构最终实现了真正的插件版外链替换不再依赖JS功能更加完善且使用更加方便",
"content": "经过两个月的努力我终于找到了完美的外链跳转解决方案初始版本使用外置JS存在诸多bug如图片灯箱、友链和站内跳转链接等问题。经过一段时间的学习和代码调整我取得了阶段性进展现在能够实现各种所需功能。最近我在hexo-external-link插件的基础上进行了底层重构最终实现了真正的插件版外链替换不再依赖JS功能更加完善且使用更加方便"
},
{
"title": "Alist宝塔部署及其美化",
"author": "",
"link": "https://blog.qyliu.top/posts/a84f5e47/",
"published": "2024-06-04 11:24",
"summary": "Alist 是一个轻量级的目录列表程序,可以用于管理文件索引。将 Alist 部署在宝塔面板中,并进行美化,可以提升用户体验。在本教程中,将介绍我的部署经过,并给出相应的美化代码。",
"content": "Alist 是一个轻量级的目录列表程序,可以用于管理文件索引。将 Alist 部署在宝塔面板中,并进行美化,可以提升用户体验。在本教程中,将介绍我的部署经过,并给出相应的美化代码。"
},
{
"title": "计算机网络期末总复习",
"author": "",
"link": "https://blog.qyliu.top/posts/8dfa25e1/",
"published": "2024-05-30 16:48",
"summary": "应该注意到标题的改变了吧本来是一章节一章节的复习奈何我突然发现老师画的重点和考研的重点并不是很符合没办法咯于是我决定将计算机网络考研复习部分的内容暂时搁置后面逐步更新反正一定是会更新的因为408必考呀然后将期末复习内容先整理出来按照老师的考点进行复习。",
"content": "应该注意到标题的改变了吧本来是一章节一章节的复习奈何我突然发现老师画的重点和考研的重点并不是很符合没办法咯于是我决定将计算机网络考研复习部分的内容暂时搁置后面逐步更新反正一定是会更新的因为408必考呀然后将期末复习内容先整理出来按照老师的考点进行复习。"
}
]
}

View File

@ -0,0 +1,96 @@
import requests
import re
from friend_circle_lite.get_info import check_feed, parse_feed
import json
import os
# 标准化的请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36'
}
def extract_emails_from_issues(api_url):
"""
从GitHub issues API中提取以[e-mail]开头的title中的邮箱地址
参数
api_url (str): GitHub issues API的URL
返回
dict: 包含所有提取的邮箱地址的字典
{
"emails": [
"3162475700@qq.com"
]
}
"""
try:
response = requests.get(api_url, headers=headers)
response.raise_for_status()
issues = response.json()
except Exception as e:
print(f"无法获取该链接:{api_url}\n出现的问题为:{e}")
return None
email_pattern = re.compile(r'^\[e-mail\](.+)$')
emails = []
for issue in issues:
title = issue.get("title", "")
match = email_pattern.match(title)
if match:
email = match.group(1).strip()
emails.append(email)
return {"emails": emails}
def get_latest_articles_from_link(url, count=5, last_articles_path="./rss_subscribe/last_articles.json"):
"""
从指定链接获取最新的文章数据并与本地存储的上次的文章数据进行对比
参数
url (str): 用于获取文章数据的链接
count (int): 获取文章数的最大数如果小于则全部获取如果文章数大于则只取前 count 篇文章
返回
list: 更新的文章列表如果没有更新的文章则返回 None
"""
# 本地存储上次文章数据的文件
local_file = last_articles_path
# 检查和解析 feed
session = requests.Session()
feed_type, feed_url = check_feed(url, session)
if feed_type == 'none':
print(f"无法访问 {url} 的 feed")
return None
# 获取最新的文章数据
latest_data = parse_feed(feed_url, session ,count)
latest_articles = latest_data['articles']
# 读取本地存储的上次的文章数据
if os.path.exists(local_file):
with open(local_file, 'r', encoding='utf-8') as file:
last_data = json.load(file)
else:
last_data = {'articles': []}
last_articles = last_data['articles']
# 找到更新的文章
updated_articles = []
last_titles = {article['link'] for article in last_articles}
for article in latest_articles:
if article['link'] not in last_titles:
updated_articles.append(article)
print(f"{url} 获取到 {len(latest_articles)} 篇文章,其中 {len(updated_articles)} 篇为新文章")
# 更新本地存储的文章数据
with open(local_file, 'w', encoding='utf-8') as file:
json.dump({'articles': latest_articles}, file, ensure_ascii=False, indent=4)
# 如果有更新的文章,返回这些文章,否则返回 None
return updated_articles if updated_articles else None