- 首先初始化项目
npm init -y
- 首先安装本次所需要用到的所有的依赖包。
npm install superagent cheerio art-template node-schedule nodemailer pm2 pm2-windows-service
- 第三方依赖包的简单介绍
项目依赖包
依赖包名称 | 功能描述 | npm 项目地址 |
---|---|---|
superagent | HTTP请求 | 查看npm项目地址 |
cheerio | 解析HTML | 查看npm项目地址 |
art-template | 模版引擎 | 查看npm项目地址 |
nodemailer | 发送电子邮件 | 查看npm项目地址 |
node-schedule | 定时任务 | 查看npm项目地址 |
pm2 | 后台运行脚本 | 查看npm项目地址 |
pm2-windows-service / pm2-windows-startup | 开机自启动 |
开始编码
-
首先来看一下效果图
效果图 -
然后再看一下实际的模板
模板
所以只需要将模板上对应的数据对应的填入进去即可
- 日期,就以编码的时间为开始时间,随后求出当次发送的时间,计算得出。
/**
* 计算认识的天数
*/
function getDayDate() {
return new Promise( (resolve, reject) => {
// 获取 当前时间
let current = new Date()
// 获取认识时间
let known = new Date('2019-5-10')
// 获取认识的时间
let res = Math.ceil((current - known) / 1000 / 60 / 60 / 24)
const format = current.getFullYear() + ' / ' + (current.getMonth() + 1).toString().padStart(2, '0') + ' / ' + (current.getDate()).toString().padStart(2, '0')
const data = {
countDay: res,
currentTime: format
}
resolve(data)
})
}
- 随后是天气的获取 利用 superagent 和 cheerio 来进行数据爬取,爬取的网站为墨迹天气 选择自己对应的城市
function getWeatherData(url){
return new Promise( (resolve, reject) => {
superagent.get(url).end( (err, res) => {
if (err) {
console.error('请求失败,请检查url')
return
}
const $ = cheerio.load(res.text)
// 图标
const icon = $('.wea_weather span img').attr('src')
// 天气
const weather = $('.wea_weather b').text()
// 温度
const temperature = $('.wea_weather em').text()
// 提示
const tips = $('.wea_tips em').text()
const weatherData = {
icon,
weather,
temperature,
tips
}
resolve(weatherData)
})
})
}
// getWeatherData('https://tianqi.moji.com/weather/china/sichuan/meishan')
- 最后是图文数据的爬取,爬取one首页的第一张轮播图片 和 下面的 文字
function getOneData() {
return new Promise( (resolve, reject) => {
superagent.get('http://wufazhuce.com/').end( (err, res) => {
if (err) {
console.error('One获取失败')
return
}
// 解析加载 模板
const $ = cheerio.load(res.text)
// 获取图片链接
const imgUrl = $('.carousel-inner>.item>img, .carousel-inner>.item>a>img').eq(0).attr('src')
// 获取文本
const text = $('.fp-one .fp-one-cita-wrapper .fp-one-cita a ').eq(0).text()
const oneData = {
imgUrl,
text
}
resolve(oneData)
})
})
}
- 随后将获取到的 数据 对模板进行渲染
async function renderTemplate() {
// 获取数据
const dayDate = await getDayDate();
const weatherData = await getWeatherData('https://tianqi.moji.com/weather/china/sichuan/meishan');
const oneData = await getOneData();
// console.log(dayDate)
// console.log(weatherData)
// console.log(oneData)
// 加载模板
return new Promise( (resolve, reject) => {
const html = template(path.join(__dirname, './love.html'), {
dayDate,
weatherData,
oneData
})
resolve(html)
})
}
应为这些都是异步操作,所有使用到 async
- 模板生成完毕后 就可以用当前模板发送邮件
async function sendNodeMail() {
// HTML 页面内容
const html = await renderTemplate()
// console.log(html);
// 使用默认SMTP传输,创建可重用邮箱对象
let transporter = nodemailer.createTransport({
host: "smtp.qq.com",
port: 465,
secure: true, // 开启加密协议,需要使用 465 端口号
auth: {
user: "*******@qq.com", // 用cls户名
pass: "********" // 授权密码
}
});
// 设置电子邮件数据
let mailOptions = {
from: '"Aeolus" <**********@qq.com>', // 发件人邮箱
to: "*********@qq.com", // 收件人列表,多个逗号隔开
subject: "see you again!", // 标题
html: html // html 内容
};
transporter.sendMail(mailOptions, (error, info = {}) => {
if (error) {
console.log(error);
sendNodeMail(); // 再次发送
}
console.log("邮件发送成功", info.messageId);
console.log("静等下一次发送");
});
}
邮箱端口号这里对邮箱的设置,需要开启邮箱的 IMAP/SMTP服务,拿到对应的授权码,使用对应的邮箱端口号
- 到这一步基本功能已经实现,接下里可以开启定时服务,使用
node-schedule
// 6.1 创建定时器任务
schedule.scheduleJob("0 59 23 * * *", function() {
// 时间到了,执行发送邮件的任务
sendNodeMail();
console.log("定时任务的邮件发送成功");
});
第一个参数事件字符串'* * * * * *' 分别代表,秒、 分、 时、 天、 月、年 *代表每一次
- 接下来运行既可以开启定时任务,但是这样就出现了一个问题,我们这个脚本必须要一直后台运行,才能在到达指定时间点后,发送我们指定的邮件。那么你每次开机都需要去 启动这个脚本,这是非常烦的事。这时候就可以使用另外一个非常 强大的库来帮我们托管任务
pm2
- 全局安装pm2
npm install pm2 -g
- 启动当前任务
pm2 start main.js
这样就可以后台托管这个项目 可以打开 cmd 输入
$ pm2 list
查看当前所有pm2 托管的任务
-
随后还需要做最后一件事件,那么就是每次开机,让pm2自动启动先前托管的任务
- 报存当前状态
$ pm2 save
- 设置开机自启动脚本
$ pm2 startup
- 报存当前状态
-
如果是window用户需要使用其他库来生成
> npm install pm2-windows-startup -g
> pm2-startup install
至此即可!
网友评论