使用nodejs的wxmnode模組,開發一個微信自動監控提醒功能,做個天氣預報。

2022-06-19 12:00:30

 

這個模組是一個公眾號的模組,名字叫「幫你看著」。

原本這個公眾號是做股票監控提醒的,我也沒炒股。因為介面支援寫入任何內容,所以可以有其他的用處。比如做成天氣預報定時提醒。

我們去npmjs中看下這個模組的詳情。

可以看出,在使用之前,需要先關注一下一個用於接收提醒的公眾號,

掃碼,然後獲得生成的賬號和密碼,就能使用這個模組了。

 

直接安裝即可,而且使用方式也很簡單:

const wxm = require('wxmnode');

let name = "80010120";//公眾號生成的賬號
let pwd ="888889";//公眾號生成的密碼
let content ="a";//內容
let type ="b";//型別
let desc ="c";//描述

let result = await wxm.sendMsgToUser(name, pwd, content, type, desc);//一次性方式
//或者
wxm.init(name, pwd );
let result = await wxm.sendMsg( content, type, desc);//繫結後傳送

 

效果如下:

可以看出,要提醒的內容都被傳送到了微信中了。

 

好了,傳送到微信的功能找好了,我們在去找找獲取天氣情況的網站,然後把需要的內容抓取過來實時傳送就可以了。

 

直接百度搜「天氣」,這個網站就不錯,而且看了下里面的資料量很全。

而且,url中可以直接看所填地區的天氣。然後它的資料內容可以直接在原始碼的json資料中能找到,這樣就更方便解析了。

 

原始碼:

nodejs中引入jquery和jsdom,和loadPage。

const { loadPage } = require("../../utils/utils");
const jQuery = require("jquery");
const jsdom = require("jsdom");

const { JSDOM } = jsdom;

/**
 * 獲取百度天氣資訊
 */
module.exports = async (area = "西湖區") => {
  const content = await loadPage(
    `${"https://"}weathernew.pae.baidu.com/weathernew/pc?query=${encodeURIComponent(
      area + "天氣"
    )}&srcid=4982`
  );
  const { document } = new JSDOM(content).window;
  const window = document.defaultView;
  const $ = jQuery(window);
  const dataStr = $("script")
    .eq(0)
    .text()
    .replace("window.tplData =", "")
    .replace(";", "");
  return JSON.parse(dataStr) || {};
};

 

loadPage為獲取外部網頁的html原始碼的,可以直接使用http模組來獲取。

獲取後使用jquery的 $("script").eq(0).text().replace("window.tplData =", "").replace(";", ""); 來拿到需要的部分。

所以,誰說現在沒有jquery的使用需求呢,抓取資料不就是它的應用之一嗎。只是需求不會很多罷了。

使用JSON.parse(dataStr) 把資料轉換成json格式。

 

之後,匯入node-schedule 和 wxmnode,

把需要傳送提醒的使用者賬號密碼和地區傳送放在陣列中。當然靈活一點可以使用資料庫進行存放。

遍歷每個使用者,data為當前使用者所在地區的天氣預報資料,然後使用await wxm.sendMsg(content, type, desc) 即可傳送內容到微信中。微信中就可以收到資訊了。

另外可以使用schedule.scheduleJob 設定指定時間來觸發傳送到微信。把程式跑在雲伺服器裡就可以了。

//定時獲取百度天氣資訊
const scheduleBaiduWeather = async () => {
  //天氣資訊傳送到微信
  async function weatherToWX() {
    //每個使用者都傳送一次
    for (let item of userList) {
      const data = await getBaiduWeather(item.area);
      const { weather = {} } = data;
      const day15 = data["15_day_forecast"].info || []; //未來15天天氣

      let content = `${item.area}天氣:\n\n${weather.weather},${weather.temperature}℃,${weather.wind_direction}${weather.wind_power}\n\n${weather.bodytemp_info},${weather.precipitation_type}`;
      let type = "小海提醒";
      let desc =
        `今天全天:白天(${day15[0].weather_day}),晚上(${day15[0].weather_night}),${day15[0].temperature_night}℃ - ${day15[0].temperature_day}℃\n` +
        `明天全天:白天(${day15[1].weather_day}),晚上(${day15[1].weather_night}),${day15[1].temperature_night}℃ - ${day15[1].temperature_day}℃\n` +
        `後天全天:白天(${day15[2].weather_day}),晚上(${day15[2].weather_night}),${day15[2].temperature_night}℃ - ${day15[2].temperature_day}℃\n`;
      
        wxm.init(item.name, item.pwd); //初始化使用者
      let ret = await wxm.sendMsg(content, type, desc);
      if (ret.code !== "0000") {
        console.log("傳送天氣失敗", ret);
      }
    }
  }

  //每天6點觸發
  schedule.scheduleJob("0 0 6 * * *", async () => {
    weatherToWX();
  });
};

scheduleBaiduWeather()