Hexo博客每天自动生成每日早报文章

作者: 時光
来源: 時光的博客园子
原文: https://blog.shiguang666.eu.org/2024/06/20/b4d1ca345b31

一、介绍

之前一直想做的功能,今天终于有机会来实现一下,正如描述那样,计划任务每天生成一篇文章用于展示每日新闻

具体效果如下

image-20240620184437493

详情页如下所示

image-20240620185945691

二、实现

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

image-20240620202425352

直接访问该目录即可

image-20240620202608057

或者创建一个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 目录即可

image-20240620203357815

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);
        });
});

此处需要 用到两个插件 axiosmoment

安装 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 并 生成一篇新的文章,控制台会打印相应日志

image-20240621103332176

获取到的数据如下,只要有了数据,我们就能自由发挥,实现无限可能,例如挂载到侧边栏等等

image-20240620205056880

如果你只想生成一篇文章,然后把这篇文章置顶,那只需要将生成的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然后按回车键。

    image-20240620210504118

创建基本任务

  • 在任务计划程序窗口的右侧,点击 创建基本任务
  1. 填写基本任务信息

    • 输入任务的名称和描述,例如 Hexo Generate Daily

      image-20240620211411416

    • 点击 下一页

  2. 设置触发器

    • 选择 每天,然后点击 下一页

      image-20240620211511880

    • 设置开始日期和时间,以及重复间隔(例如每天),例如我设置为每天早上9点执行一次

      image-20240620211712722

    • 点击 下一页

  3. 设置操作

    • 选择 启动程序,然后点击 下一页

      image-20240620211803878

  4. 配置启动程序

    • 程序/脚本 字段中,输入 cmd,点击预览,选择cmd.exe

    • 添加参数 字段中,输入 /c "cd /d D:\path\to\your\hexo\blog && hexo g && hexo d",其中 D:\path\to\your\hexo\blog 是你的 Hexo 博客目录的路径。

    • 点击 下一页

      image-20240620212207650

  5. 完成任务创建

    • 确认所有设置,然后点击 完成
  6. 检查任务

    • 在任务计划程序库中,找到你创建的任务,确保它已启用。
  7. 启用历史记录

image-20240620215553151

这样,任务计划程序会每天在指定的时间自动执行 hexo g && hexo d 命令来生成并部署你的 Hexo 博客文件。

当然,也可以执行 hexo clean && hexo g && hexo d 清除缓存数据

注意事项

  • 确保你的 Hexo 博客目录路径正确无误。

  • 确保你的系统中已经安装了 Node.js 和 Hexo,并且 hexo 命令可以在命令行中正常运行。

  • 如果你在执行命令时需要管理员权限,可以在任务计划程序中属性设置使用最高权限运行该任务。

    image-20240620214050771

    如果保存时提示"一个或多个指定的参数无效"错误,可参考下面的文章

    解决任务计划程序出错一个或多个指定的参数无效

2.5、后续

现已将插件发布到NPM,并开源到 Github,可直接通过命令安装

npm install hexo-daily-news --save

现插件已被 Hexo官方收录,你可也在 Hexo 插件列表里查看

image-20240625182035596

posted @ 2024-06-26 14:58  時光心向阳  阅读(89)  评论(0编辑  收藏  举报