├── README.md ├── demo ├── cheerio-superagent │ └── cheerio-superagent.js ├── ejsdemo │ ├── app.js │ └── mail.ejs ├── node-schedule-demo │ └── app.js └── nodeMailDemo │ └── app.js ├── email.ejs ├── main.js └── package.json /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 写在前面 3 | 4 | 5 | 自从用邮箱注册了很多账号后,便会收到诸如以下类似的邮件,刚开始还以为是一张图片,后来仔细一看不是图片呀,好像还是HTML呀,于是好奇宝宝我Google一下,查阅多篇资料后总结出怎么用前端知识和Node做一个这样的“邮件网页”。 6 | 7 |  8 | 9 | 10 | 11 | ## 确认主题 12 | 知道怎么实现功能后,思考着我该写什么主题呢,用一个HTML模板随便给小伙伴们发个邮件炫个技?不行,作为一个很cool的程序员怎么能这么low呢,最近天气变化幅度大,温度捉摸不定,女朋友总是抱怨穿少了又冷穿多了又热,嗨呀,要不我就写个每天定时给宝宝发送天气预报的邮件,另外想起宝宝喜欢看ONE·一个这个APP上的每日更新,要不发天气预报的同时,再附赠一个“ONE的每日订阅”?机智又浪漫,开始搬砖~ 13 | 14 | ## 剧透 15 | 16 | 本来是想最后放效果图的,怕你们看到一半就没兴趣了,就在前面剧透一下我最后做出来的效果图吧~ 17 | 18 |  19 | 20 | ## 待解决的问题 21 | **1. 如何获取天气预报和ONE上的data?** 22 | 23 | 答:获取data有两种方法,第一种方法是获取天气预报和ONE的API,第二种是用node爬虫获取天气预报和ONE网页的信息。后来找了下,发现ONE并没有API接口,为了让两者统一,于是决定使用node上的一个插件叫`cheerio`,配合`superagent`能够很方便地爬取网页上的信息。 24 | 25 | **2. 如何做出HTML的这种邮件?** 26 | 27 | 答:之前学过一段时间的express这个框架,接触到模版引擎这个概念,传入data便可获得html文件,再结合node的fs模块,获取到这个html文件,便可以结合node的邮件插件发送HTML邮件啦! 28 | 29 | **3. 如何用node发送邮件?** 30 | 31 | 感谢无私的开源开发者,开发了一款发送邮件的Node插件`nodemailer`,兼容主流的Email厂商,只需要配置好邮箱账号和smtp授权码,便可以用你的邮箱账号在node脚本上发文件,很cool有没有~ 32 | 33 | **4. 如何做到每日定时发送?** 34 | 35 | 其实可以通过各种hack的方式写这么一个定时任务,但是既然node社区有这个定时的轮子,那我们直接用就好了,`node-schedule`是一个有着各种配置的定时任务发生器,可以定时每个月、每个礼拜、每天具体什么时候执行什么任务,这正符合每天早晨定时给宝宝发送邮件的需求。 36 | 37 | **一切准备就绪,开始做一次浪漫的程序员** 38 | 39 | ## 编写代码 40 | ### 网页爬虫 41 | 这里我们使用到`superagent`和`cheerio`组合来实现爬虫: 42 | 43 | - 分析网页DOM结构,如下图所示: 44 | 45 |  46 | 47 | - 用superagent来获取指定网页的所有DOM: 48 | 49 | ``` javascript 50 | superagent.get(URL).end(function(err,res){ 51 | // 52 | } 53 | ``` 54 | - 用cheerio来筛选superagent获取到的DOM,取出需要的DOM 55 | 56 | ``` javascript 57 | imgUrl:$(todayOne).find('.fp-one-imagen').attr('src'), 58 | type:$(todayOne).find('.fp-one-imagen-footer').text().replace(/(^\s*)|(\s*$)/g, ""), 59 | text:$(todayOne).find('.fp-one-cita').text().replace(/(^\s*)|(\s*$)/g, "") 60 | ``` 61 | **以下就是爬取ONE的代码,天气预报网页也是一个道理:** 62 | 63 | ``` javascript 64 | const superagent = require('superagent'); //发送网络请求获取DOM 65 | const cheerio = require('cheerio'); //能够像Jquery一样方便获取DOM节点 66 | 67 | const OneUrl = "http://wufazhuce.com/"; //ONE的web版网站 68 | 69 | superagent.get(OneUrl).end(function(err,res){ 70 | if(err){ 71 | console.log(err); 72 | } 73 | let $ = cheerio.load(res.text); 74 | let selectItem=$('#carousel-one .carousel-inner .item'); 75 | let todayOne=selectItem[0]; //获取轮播图第一个页面,也就是当天更新的内容 76 | let todayOneData={ //保存到一个json中 77 | imgUrl:$(todayOne).find('.fp-one-imagen').attr('src'), 78 | type:$(todayOne).find('.fp-one-imagen-footer').text().replace(/(^\s*)|(\s*$)/g, ""), 79 | text:$(todayOne).find('.fp-one-cita').text().replace(/(^\s*)|(\s*$)/g, "") 80 | }; 81 | console.log(todayOneData); 82 | }) 83 | ``` 84 | 85 | ### EJS模版引擎生成HTML 86 | 通过爬虫获取到了数据,那么我们就能够通过将date输入到EJS渲染出HTML,我们在目录下创建js脚本和ejs模版文件: 87 | 88 | - app.js 89 | 90 | ``` javascript 91 | const ejs = require('ejs'); //ejs模版引擎 92 | const fs = require('fs'); //文件读写 93 | const path = require('path'); //路径配置 94 | 95 | //传给EJS的数据 96 | let data={ 97 | title:'nice to meet you~' 98 | } 99 | 100 | //将目录下的mail.ejs获取到,得到一个模版 101 | const template = ejs.compile(fs.readFileSync(path.resolve(__dirname, 'mail.ejs'), 'utf8')); 102 | //将数据传入模版中,生成HTML 103 | const html = template(data); 104 | 105 | console.log(html) 106 | 107 | ``` 108 | 109 | - mail.ejs 110 | 111 | ``` javascript 112 | 113 | 114 |
115 | 116 | 117 | 118 |