去哪吃
背景
看到这个题目,你也许会想『啥意思,什么去哪吃,想去哪吃去哪吃呗』。说得好,关键是不知道去哪吃,纠结啊。于是,就想着可不可以搞一个每天定时告诉我去哪吃的小脚本,定时发个邮件告诉我去哪吃,距离、价格最好也能一并告诉我。正所谓:『行胜于言』,搞起:rofl:
其实这篇文章没啥技术含量,就是挺好玩的。:stuck_out_tongue:
准备工作
- axios:请求库
- nodemailer:用于发送邮件
| 12
 3
 4
 
 | mkdir getCatingcd getCanting
 npm init --yes
 npm i axios nodemailer
 
 | 
获取周边餐馆:v:
检索周边地点主要是调用了百度地图的Web服务API。
可参考地点检索服务服务文档。

原型区域检索API(GET请求):http://api.map.baidu.com/place/v2/search?query=银行&location=39.915,116.404&radius=2000&output=xml&ak=您的密钥。具体的请求参数也可参考地点检索服务服务文档。
这个query参数里面唯一需要自己去获取的就是经纬度(location)。这个具体的获取方法如下:
| 12
 3
 4
 
 | navigator.geolocation.getCurrentPosition(position => {console.log(position.coords.latitude);
 console.log(position.coords.longitude)
 })
 
 | 
这个要打开浏览器的定位服务。
具体代码如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | const request = require('axios');const fs = require('fs');
 const path = require('path');
 const ak = 'xxxxxxxxxxxxxxxxxxxx';
 const query = encodeURI(`query=小吃$快餐$中餐&tag=小吃&location=40.04171,116.312820086&scope=2&radius_limit=true&page_size=20&radius=500&output=json&ak=${ak}`);
 
 request.get(`http://api.map.baidu.com/place/v2/search?${query}`)
 .then(res => {
 fs.writeFileSync(path.resolve(__dirname, 'cantingList.json'), JSON.stringify(res.data, null, '\t'));
 })
 
 | 
返回的结果如下:

发送邮件:dizzy:
发送邮件主要用了nodemailer这个第三方库,使用方法可参考usage以及内置支持的服务。
| 12
 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
 
 | const nodemailer = require('nodemailer');
 const transport = nodemailer.createTransport({
 service: 'QQ',
 auth: {
 user: 'xxxxxxx@qq.com',
 
 pass: 'xxxxxxxx'
 }
 })
 
 let mailOption = {
 from: '"xxxx" <xxxxxxxx@qq.com>',
 to: ['email-list'],
 subject: '中午/晚上吃什么? 我来告诉你',
 }
 
 function send(_item) {
 transport.sendMail(Object.assign(mailOption, {
 text: `
 名称:${_item.name}
 地址:${_item.address}
 距离:${_item.detail_info.distance}米
 人均价格:${_item.detail_info.price || '暂无数据'}
 评分:${_item.detail_info.overall_rating || '暂无数据'}
 经纬度:${_item.location.lat}, ${_item.location.lng}
 电话:${_item.telephone || '暂无电话'}
 在地图中查看:${_item.detail_info.detail_url}
 `
 }), (err, info) => {
 if (err) {
 return;
 }
 console.log('Message send successfully: %s', info.messageId);
 })
 }
 
 | 
看这:eyes: qq邮箱的授权码怎么获取?
最后的代码:
| 12
 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
 
 | const request = require('axios');const nodemailer = require('nodemailer');
 const fs = require('fs');
 const path = require('path');
 const ak = 'xxxxxxxxxxxxxxx';
 const query = encodeURI(`query=小吃$快餐$中餐&tag=小吃&location=40.04171,116.312820086&scope=2&radius_limit=true&page_size=20&radius=500&output=json&ak=${ak}`)
 
 let item;
 
 const transport = nodemailer.createTransport({
 service: 'QQ',
 auth: {
 user: 'xxxxxx@qq.com',
 pass: 'xxxxxxxx'
 }
 })
 
 let mailOption = {
 from: '"name" <xxxxxx@qq.com>',
 to: ['email-list'],
 subject: '中午/晚上吃什么? 我来告诉你',
 }
 
 function send(_item) {
 transport.sendMail(Object.assign(mailOption, {
 text: `
 名称:${_item.name}
 地址:${_item.address}
 距离:${_item.detail_info.distance}米
 人均价格:${_item.detail_info.price || '暂无数据'}
 评分:${_item.detail_info.overall_rating || '暂无数据'}
 经纬度:${_item.location.lat}, ${_item.location.lng}
 电话:${_item.telephone || '暂无电话'}
 在地图中查看:${_item.detail_info.detail_url}
 `
 }), (err, info) => {
 if (err) {
 return;
 }
 console.log('Message send successfully: %s', info.messageId);
 })
 }
 
 request.get(`http://api.map.baidu.com/place/v2/search?${query}`)
 .then(res => {
 fs.writeFileSync(path.resolve(__dirname, 'cantingList.json'), JSON.stringify(res.data, null, '\t'));
 item = res.data.results[parseInt(Math.random() * 20)]
 send(item);
 })
 
 | 
定时执行 :clock11:
用的crontab,crontab -e直接编辑如下:
| 1
 | 30 11,17 * * 1-5 /usr/local/bin/node /Users/{your path}/getCanting/getCanting.js
 | 
最后
感觉挺好玩的,虽然没啥含金量,但是感觉还是有那么「yinainai」(就是一点点的意思 :dog:)收获。
好啦 就到这吧。
土遁~~~~ :wave: :wave: