node爬取墨迹天气数据发送定时邮件

  使用vscode通过node.js爬取墨迹天气网站的数据,然后通过邮件每天定时给特定的一个或者多个邮箱发送具有特定html样式的163邮件。

实现爬取功能准备工作:

  1. 官网下载node.js

  2. 打开vs code建好项目,在终端输入npm init -y初始化项目;在vs code终端输入npm install superagent cheerio art-template node-schedule nodemailer安装需要的各种依赖包。

  3. 还需要一个163邮箱以及邮箱客户端授权密码。然后就OK可以开始撸代码啦~

main.js代码(爬虫以及计算时间部分代码)
//引入superagent包,用于服务器发送http请求;
const request = require('superagent');
//导入cheerio包,把字符串解析成html。
const cheerio = require('cheerio');
//导入模板引擎,
const template = require('art-template');
//导入path模块处理路径
const path = require('path');
//导入Nodemailer包
const nodemailer = require("nodemailer");
//导入定时模块包
var schedule = require('node-schedule');


//计算放暑假的天数
function getDayData() {
    return new Promise((resolve, reject) => {
        //现在的时间
        const today = new Date();
        //暑假开始的时间
        const meet = new Date('2019-7-20');
        //计算暑假到今天的天数
        const count = Math.ceil((today - meet) / 1000 / 60 / 60 / 24);
        //今天日期格式化
        const format = today.getFullYear() + " / " + (today.getMonth() + 1) + " / " + today.getDate();
        const dayData = {
                count,
                format
            }
            // console.log(dayData);
        resolve(dayData);
    })

}
// getDayData();
//请求墨迹天气的数据
function getMojiData() {

    return new Promise((resolve, reject) => {
        request.get('https://tianqi.moji.com/weather/china/henan/xinyang').end((err, res) => {
            if (err) return console.log("数据请求失败~");
            // console.log(res.text);
            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();
            console.log(temperature);
            //提示
            const tips = $('.wea_tips em').text();

            const MojiData = {
                    icon,
                    weather,
                    temperature,
                    tips
                }
                // console.log(mojiData);
            resolve(MojiData);
        })
    })
}
// getMojiData();
//请求one页面抓取数据
function getOneData() {
    return new Promise((resolve, reject) => {
        request.get('http://wufazhuce.com/').end((err, res) => {
            if (err) return console.log("数据请求失败~");
            const $ = cheerio.load(res.text);
            // 爬取图片
            const img = $('.carousel-inner>.item>a>img').eq(2).attr('src');
            //爬取文字
            const text = $('.fp-one .fp-one-cita-wrapper .fp-one-cita a').eq(2).text();

            const OneData = {
                    img,
                    text
                }
                // console.log(OneData);
            resolve(OneData);
        })
    })
}
// getOneData();

// 通过模板引擎替换html的数据
async function renderTemplate() {
    //获取 日期
    const dayData = await getDayData();
    //获取 墨迹天气数据
    const MojiData = await getMojiData();
    //获取one网页数据
    const OneData = await getOneData();

    // console.log(dayData);
    // console.log(MojiData);
    // console.log(OneData);
    //当所有数据都获取成功的时候,进行模板引擎数据的替换
    return new Promise((resolve, reject) => {
        const html = template(path.join(__dirname, "./email.html"), {
            dayData,
            MojiData,
            OneData
        });
        resolve(html);
    })


}
// renderTemplate();
async function sendNodeMail() {
    const html = await renderTemplate();
    // const html = "<h1>哈哈哈啊</h1>";
    console.log(html);

    // create reusable transporter object using the default SMTP transport
    let transporter = nodemailer.createTransport({
        host: "smtp.163.com",
        port: 465,
        secure: true, // true for 465, false for other ports
        auth: {
            user: "XXXXX@163.com(你的邮箱)", // generated ethereal user用户名
            pass: "XXXXX(你的邮箱客户端授权密码)" // generated ethereal password
        }
    });

    // send mail with defined transport object
    let mailOptions = {
        from: '"缓月" <XXXXX@163.com", // list of receivers收件人列表
        subject: "测试邮件~", // Subject line
        html: html // html body
    };

    transporter.sendMail(mailOptions, (error, info = {}) => {
        if (error) {
            console.log(error);
            sendNodeMail(); //再次发送
        }
        console.log("邮件发送成功", info.messageId);
        console.log("静等下一次发送~");
    })
}
var j = schedule.scheduleJob("00 26 15 * *", function() {
    sendNodeMail();
    console.log("发送邮件成功~");
})
邮件模板样式代码

这个是你写的邮件的样式,可以理解为一个模板,即你每天发送邮件的固定样式(可以根据自己的喜好进行更改~).

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>邮件</title>
</head>

<body style="margin: 0;padding:0;">
    <div style="width:100%;margin:0 auto;padding: 20px;text-align: center;">
        <span style="font-size: 26px;font-weight:600;">今天是放暑假的第</span>
        <span style="color: chocolate;font-size:36px;font-weight:bold;">{{ dayData.count }}</span>
        <span style="font-size: 26px;font-weight:600;"></span>
    </div>
    <p style="text-align:center;">小可耐,今天也要加油喔~</p>

    <div style="width: 100%;margin:0 auto;color:lightsteelblue;text-align:center;">
        <img src="{{ MojiData.icon }}" alt="天气icon" style="" />
        <b style="display:block;color:#333;font-size:24px;margin:15px 0;">天气:{{ MojiData.weather }}</b>
        <span style="display:block;color:#333;font-size:22px;margin:15px 0;">温度:{{ MojiData.temperature }}</span>
        <span>Tips:{{MojiData.tips}}</span>
    </div>

    <div style="text-align:center;margin: 35px 0;">
        <span style="display:block;margin-top:55px;color:#676767;font-size:15px;">
             ONE·一个
        </span>
        <span style="display:block;margin-top:25px;color:#9d9d9d;font-size:22px;">{{ dayData.format }}</span>
        <img src="{{ OneData.img }}" style="width:100%;margin-top:10px;" alt="今日图片" />
        <div style="margin: 10px auto;margin-top:10px;">
            {{ OneData.text }}
        </div>
    </div>
</body>

</html>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值