node.js爱心邮件
一.用的软件是VsCode:下载地址:https://code.visualstudio.com/
二.用的是node.js完成:下载地址:http://nodejs.cn/download/
无脑下一步安装即可,如果还是不会,可以进入该网址查看:https://www.runoob.com/nodejs/nodejs-install-setup.html
node.js需要配置环境变量:这我就不多说了,自己百度。
三.创建项目
随便创建一个文件夹,右键使用vscode打开
1.在资源管理器下边空白处右键打开终端输入:npm init -y 初始化项目
2.如果没安装:npm命令的可以进入该网站查看:https://www.runoob.com/nodejs/nodejs-npm.html
该网站中还有node.js的一个常用web框架模块 express 的npm安装方法,在这里我们就不用他的框架了。
我们只需要导入5个依赖即可。
3.下载依赖包:
art-template:模板引擎
cheerio:解析html
node-schedule:定时任务
nodemailer:发送电子邮件
superagent:http请求
npm命令:npm i art-template cheerio node-schedule nodemailer superagent
4.新建一个html文件
1 <!DOCTYPE html> 2 3 <html lang="en"> 4 5 <head> 6 7 <meta charset="UTF-8"> 8 9 <title>mail</title> 10 11 12 </head> 13 14 <body style="margin: 0px;padding: 0px;"> 15 <div style="text-align: center"> 16 <p>今天是我们在一起的第 17 <span> 18 {{dayData.count}} 19 </span> 20 天 21 </p> 22 <img style="background: cornflowerblue" src="{{mojiData.icon}}" alt="天气图标"> 23 <h3> 24 天气: 25 <span> 26 {{mojiData.weather}} 27 </span> 28 </h3> 29 <p> 30 温度: 31 <span> 32 {{mojiData.temperature}} 33 </span> 34 </p> 35 <p> 36 提示: 37 <span> 38 {{mojiData.hint}} 39 </span> 40 </p> 41 <p> 42 ONE · 一个 43 </p> 44 <P> 45 {{ dayData.format }} 46 </P> 47 <div style="border: 1px solid red"> 48 <img src="{{one.image}}" alt="图片" width="100%"> 49 </div> 50 <p> 51 {{one.text}} 52 </p> 53 </div> 54 55 56 57 </body>
最终邮件显示就是这样的:
5.该页面上显示的所有变化信息都是通过抓取墨迹天气和one一个网站的数据
墨迹天气网址:https://tianqi.moji.com/weather/china/hebei/zhangjiakou
one一个网址:http://wufazhuce.com/
抓取数据是靠要抓取信息在网页中的选择器抓取的。
注:在测试期间可在终端运行代码查看:命令:node js文件名
6.新建ji文件
6.1.计算认识的天数:可以打开:console.log(dayData);和调用方法进行测试,其他方法一样.
1 //1.0计算爱人认识的天数 2 function getDayDate(){ 3 4 return new Promise((resolve,reject) =>{ 5 //现在的时间 6 const today = new Date(); 7 //认识的时间 8 const meet = new Date('2019-06-1'); 9 //计算像是到几天的天数 10 //时间戳转换成天在向上取整 11 const count = Math.ceil((today - meet) / 1000 / 60 / 60 / 24); 12 //日期的格式化 13 const format = today.getFullYear() + '/' + (today.getMonth() + 1) + '/' + today.getDate(); 14 15 const dayData = { 16 count, 17 format 18 } 19 20 // console.log(dayData); 21 resolve(dayData); 22 }) 23 24 } 25 // getDayDate();
6.2.抓取墨迹天气数据
1 //2.0 引入superagent 包,用于服务器发送http请求 2 const request = require('superagent'); 3 4 //引入cheerio 包 用于把字符串解析成html 5 const cheerio = require('cheerio'); 6 7 //请求墨迹天气获取数据 8 function getMojiData(){ 9 10 return new Promise((resolve,reject) =>{ 11 request.get('https://tianqi.moji.com/weather/china/hebei/zhangjiakou').end((err,res)=>{ 12 if(err) return console.log("数据请求失败,请检查路径"); 13 //console.log(res.text); 14 //把字符串转换城html,并可用 jQuery核心选择器湖区内容 15 const $ = cheerio.load(res.text); 16 //图标 17 const icon = $('.wea_weather span img').attr('src'); 18 //天气 19 const weather = $('.wea_weather b').text(); 20 //温度 21 const temperature = $('.wea_weather em').text(); 22 //提示 23 const hint = $('.wea_tips em').text(); 24 25 const mojiData = { 26 icon, 27 weather, 28 temperature, 29 hint 30 } 31 // console.log(mojiData); 32 resolve(mojiData); 33 34 }) 35 }) 36 37 } 38 // getMojiData();
6.3.抓取one页面数据
1 //3.0 请求one页面抓取数据 2 function getOne(){ 3 4 return new Promise((resolve,reject) =>{ 5 request.get('http://wufazhuce.com/').end((err,res)=>{ 6 if(err) return console.log("数据请求失败,请检查路径"); 7 //把返回值中的页面解析成html 8 const $ = cheerio.load(res.text); 9 //抓取图片 10 const image = $('.carousel-inner>.item>img, .carousel-inner>.item>a>img').eq(0).attr('src'); 11 //抓取文本 12 const text = $('.fp-one .fp-one-cita-wrapper .fp-one-cita a').eq(0).text(); 13 14 const one = { 15 image, 16 text 17 } 18 19 // console.log(one); 20 resolve(one); 21 22 }) 23 }) 24 25 26 } 27 28 // getOne();
6.4.通过模板引擎引起替换html数据
1 //4.0 2 //引入模板引擎 3 const template = require('art-template'); 4 //导入 path 模块路径 5 const path = require('path'); 6 7 //通过模板引起替换 heml 的数据 8 async function renderTemplate(){ 9 //获取 日期 10 const dayData = await getDayDate(); 11 //获取 墨迹天气数据 12 const mojiData = await getMojiData(); 13 //获取 one数据 14 const one = await getOne(); 15 16 // console.log(dayData); 17 // console.log(mojiData); 18 // console.log(one); 19 20 //所有数据都获取成功时,进行模板引擎数据的替换 21 return new Promise((resolve,reject)=>{ 22 const html = template(path.join(__dirname,'./love.html'),{ 23 dayData, 24 mojiData, 25 one 26 }); 27 resolve(html); 28 }); 29 } 30 31 // renderTemplate();
6.5.发送邮件:测试完之后可以进入邮箱查看一下哟!
1 //5.0 2 //导入邮箱依赖 3 const nodemailer = require("nodemailer"); 4 //发送邮件 5 async function sendNodeMain(){ 6 7 //html页面内容 8 const html = await renderTemplate(); 9 console.log(html); 10 //使用默认smtp传输,创建可重用邮箱对象 11 let transporter = nodemailer.createTransport({ 12 host: "smtp.qq.com", 13 port: 465, 14 secure: true, // true for 465, false for other ports 15 auth: { 16 user: "577808444@qq.com", // generated ethereal user 17 pass: "pmznunfrpgzqbdcg" // generated ethereal password 18 } 19 }); 20 21 // 使用定义的传输对象发送邮件 22 let mailOptions = { 23 from: '"帅气的小哥哥" <577808444@qq.com>', // 发件人 24 to: "315391975@qq.com", // 收件人邮箱列表 25 subject: "爱的邮件", // 标题 26 html: html // html 内容 27 }; 28 29 transporter.sendMail(mailOptions,(error,info = {})=>{ 30 if(error){ 31 console.log(error); 32 sendNodeMain();//再次发送 33 } 34 console.log("邮件发送成功",info.messageId); 35 console.log("静等下一次发送"); 36 }); 37 } 38 39 // sendNodeMain();
6.6.定时发送邮件
1 //6.0 2 //定时每天发送邮件 每天8时13分14秒 3 //导入node-schedule包 4 const schedule = require('node-schedule'); 5 6 const j = schedule.scheduleJob('14 13 08 * * *', function(){ 7 sendNodeMain(); 8 console.log('邮件已发送'); 9 });
好了,这就搞定了。