Hexo博客每天自动生成每日早报文章
作者: 時光
来源: 時光的博客园子
原文: https://blog.shiguang666.eu.org/2024/06/20/b4d1ca345b31
一、介绍
之前一直想做的功能,今天终于有机会来实现一下,正如描述那样,计划任务每天生成一篇文章用于展示每日新闻
具体效果如下
详情页如下所示
二、实现
2.1、 仅固定单页面访问
需要使用到 ALAPI 的 每日60秒早报 接口,可免费调用
注册登录后在 个人管理 => 个人中心 => 获取token
如果只想生成一个固定的静态页面访问,可以直接使用以下代码,替换自己的token即可
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>每日早报</title>
</head>
<body>
<div style="text-align: center;"> <img src="https://v2.alapi.cn/api/zaobao?token=xxxxxxxxxxx&format=image"
alt="每日早报" width="100%"> </div>
</body>
</html>
将代码保存到一个html文件内,存放博客主目录source
文件夹即可
例如我保存到 source\api\60s.html
直接访问该目录即可
或者创建一个page页面,例如
hexo new page "daily-news-detail"
然后修改 source\daily-news-detail\index.md
文件,打开源码模式,粘贴以下代码,替换token
内容
---
title: 每日早报
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>每日早报</title>
</head>
<body>
<div style="text-align: center;"> <img src="https://v2.alapi.cn/api/zaobao?token=xxxxxxxxxxx&format=image"
alt="每日早报" width="100%"> </div>
</body>
</html>
直接访问刚才生成的 daily-news-detail
目录即可
2.2、 每天生成新的文章
由于 Front Matter
是静态的,不能直接在 Markdown 文件中动态引用 JSON 文件的内容。所以如果想仅生成一篇文章每天动态加载文章标题及封面也需要使用下面的方法。
在 主题目录scripts
文件夹下创建一个新的JavaScript文件,例如 fetch-daily-news.js
,我使用的主题是 Butterfly
,具体目录为 themes\butterfly\scripts
,替换代码中的token
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const moment = require('moment');
// 设置 moment 的语言环境为中文
moment.locale('zh-cn');
hexo.on('ready', () => {
const apiUrl = 'https://v2.alapi.cn/api/zaobao';
const token = 'xxxxxxxxxxx'; // 替换为你的token
axios.get(apiUrl, {
params: {
token: token
}
})
.then(response => {
const data = response.data;
if (data.code === 200) {
let newsData = data.data;
// 执行历史数据 Start
// const oldDataFileName = "daily_news_2024-06-20.json" // 修改需要执行的数据文件名称
// const oldDataPath = path.join(__dirname, '../../../source/_data/'+oldDataFileName);
// console.log("Daily news oldDataPath is :",oldDataPath);
// const oldData = JSON.parse(fs.readFileSync(oldDataPath, 'utf8'));
// newsData = oldData;
// 执行历史数据 End
// 使用 newsData.date 转换为星期几
const postDate = newsData.date;
const postDayOfWeek = moment(postDate).format('dddd');
const filePath = path.join(__dirname, '../../../source/_data/daily_news_'+postDate+'.json');
console.log('Daily news save data filePath is :', filePath);
// 生成json文件
fs.writeFileSync(filePath, JSON.stringify(newsData, null, 2));
// 生成 Markdown 文件
// const postDayOfWeek = moment().format('dddd'); // 获取中文的星期几
const postTitle = `【每日早报】-${postDate} - ${postDayOfWeek}`;
const postContent = `---
title: ${postTitle}
date: ${postDate} 00:00:00
tags:
- 每日早报
categories:
- 每日早报
series: 每日早报
cover: ${newsData.head_image}
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>每日早报</title>
</head>
<body>
<div style="text-align: center;"> <img src="`+newsData.image+`"
alt="每日早报" width="100%"> </div>
</body>
</html>`;
const postFilePath = path.join(__dirname, '../../../source/_posts', `${postTitle}.md`);
fs.writeFileSync(postFilePath, postContent);
console.log('Daily news post generated successfully:', postFilePath);
} else {
console.error('Failed to fetch daily news:', data.msg);
}
})
.catch(error => {
console.error('Error fetching daily news:', error);
});
});
此处需要 用到两个插件 axios
和 moment
安装 axios
npm install axios
安装 moment
npm install moment
调用接口生成的数据会保存在博客主目录 /source/_data/daily_news_xxxx-xx-xx.json
,如果没有_data
目录可以手动创建一下,防止因找不到目录文件保存失败。
注意根据实际情况调整文件的存放路径
const postFilePath = path.join(__dirname, '../../../source/_posts', `${postTitle}.md`);
文章的标题,目录,标签,系列文章分类等也可自行调整
tags:
- 每日早报
categories:
- 每日早报
series: 每日早报
为了确保 Hexo 能够正确加载 _data
目录下的数据文件。可以在 _config.yml
文件中添加以下配置,确保 _data
目录被正确加载
data_dir: source/_data
执行 hexo g
重新生成html文件时会保存 daily_news_xxxx-xx-xx.json
并 生成一篇新的文章,控制台会打印相应日志
获取到的数据如下,只要有了数据,我们就能自由发挥,实现无限可能,例如挂载到侧边栏等等
如果你只想生成一篇文章,然后把这篇文章置顶,那只需要将生成的markdown文件名固定就可以了,例如
const postFilePath = path.join(__dirname, '../../../source/_posts', `每日早报.md`);
这样每次执行 hexo g
时重新生成的文件会覆盖原来的文件
如果想要执行历史数据,只需将执行历史数据部分取消注释,修改数据文件名称就可以了
// 执行历史数据 Start
// const oldDataFileName = "daily_news_2024-06-20.json" // 修改需要执行的数据文件名称
// const oldDataPath = path.join(__dirname, '../../../source/_data/'+oldDataFileName);
// console.log("Daily news oldDataPath is :",oldDataPath);
// const oldData = JSON.parse(fs.readFileSync(oldDataPath, 'utf8'));
// newsData = oldData;
// 执行历史数据 End
2.4、通过计划任务自动生成并部署博客文件
每天都需手动执行命令生成文件不够优雅,我们可以创建计划任务,每天自动执行命令生成文件
在 Windows 上,你可以使用任务计划程序(Task Scheduler)来设置一个计划任务,以便每天自动执行 hexo g
命令来生成文件。以下是详细步骤:
打开任务计划程序
-
按
Win + S
打开搜索栏,输入任务计划程序
,或者Win + R
打开运行输入框输入taskschd.msc
然后按回车键。
创建基本任务
- 在任务计划程序窗口的右侧,点击
创建基本任务
。
-
填写基本任务信息:
-
输入任务的名称和描述,例如
Hexo Generate Daily
。 -
点击
下一页
。
-
-
设置触发器:
-
选择
每天
,然后点击下一页
。 -
设置开始日期和时间,以及重复间隔(例如每天),例如我设置为每天早上9点执行一次
-
点击
下一页
。
-
-
设置操作:
-
选择
启动程序
,然后点击下一页
。
-
-
配置启动程序:
-
在
程序/脚本
字段中,输入cmd
,点击预览,选择cmd.exe
-
在
添加参数
字段中,输入/c "cd /d D:\path\to\your\hexo\blog && hexo g && hexo d"
,其中D:\path\to\your\hexo\blog
是你的 Hexo 博客目录的路径。 -
点击
下一页
。
-
-
完成任务创建:
- 确认所有设置,然后点击
完成
。
- 确认所有设置,然后点击
-
检查任务:
- 在任务计划程序库中,找到你创建的任务,确保它已启用。
-
启用历史记录
这样,任务计划程序会每天在指定的时间自动执行 hexo g && hexo d
命令来生成并部署你的 Hexo 博客文件。
当然,也可以执行 hexo clean && hexo g && hexo d
清除缓存数据
注意事项
-
确保你的 Hexo 博客目录路径正确无误。
-
确保你的系统中已经安装了 Node.js 和 Hexo,并且
hexo
命令可以在命令行中正常运行。 -
如果你在执行命令时需要管理员权限,可以在任务计划程序中属性设置使用最高权限运行该任务。
如果保存时提示"一个或多个指定的参数无效"错误,可参考下面的文章
2.5、后续
现已将插件发布到NPM,并开源到 Github,可直接通过命令安装
npm install hexo-daily-news --save