使用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代码(爬虫以及计算时间部分代码)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    //引入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("发送邮件成功~");
    })

邮件模板样式代码

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!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>

gethub地址:https://github.com/huanyue2019/email.git
欢迎大家一起交流,共同进步~



本站访问量为: 次 。