用微信公众号给女朋友自定义推送天气与课表

发布于:2023-01-04 ⋅ 阅读:(282) ⋅ 点赞:(0)

22.9.18更新
已经更新最新版,最新版比较详细,而且分为python和JavaScript版本
请移步 获取公众号推送 2.0 加强版!

22.10.16更新
我已经做出来更优秀的直接在聊天列表中推送的了!
请移步 企业微信推送 超强版!

如何优雅地获取公众号专属推送

样例图片

目录

前言

我们学校自从更新了选课系统之后,就没有自动的课表推送了。同时,我也想给自己的女朋友做一个推送天气和气温的小东西,以便于她能方便地查看天气进行每天的规划。

于是,这个专属的公众号推送来了。

技术选型

  1. 编程语言:python(3.0版本以上)
  2. 包管理工具:pip3
  3. 代码编辑器:pycharm
  4. 所用包:request/datetime/date
  5. 服务器:腾讯云轻量应用服务器
  6. 服务器自动化运行语言:Shell

产品逻辑

由于是在微信公众号下进行操作,依赖微信的生态进行。所以要先去看看微信官方文档。同时,选定编程语言根据官方文档可知,微信公众号可实现信息模板的发送,但是只有测试号可以(够用,但是我至今没找到如何部署到自己的公众号而非测试号)

微信公众号发文逻辑

  1. 申请测试号:
    申请测试号

  2. 记录appId及appSecret

  3. 由本地向微信服务器发送appID及appSecret获取access_token

  4. 确定自己所要发送的信息,并在公众号测试号中设定对应信息模板,并获取模板ID,以下是我的模板。

 今天是{{date.DATA}} 
 城市:{{city.DATA}} 
 天气:{{weather.DATA}} 
 最低气温: {{min_temperature.DATA}} 
 最高气温: {{max_temperature.DATA}} 
 今天是我们恋爱的第{{love_day.DATA}}天 
 距离墨墨的生日还有{{birthday.DATA}}天 
 --------课表-------- 
 8-10 {{firstClass.DATA}} 
 10-12 {{secondClass.DATA}} 
 2-4 {{thirdClass.DATA}} 
 4-6 {{fourthClass.DATA}} 
 7-10 {{fifthClass.DATA}}
  1. 让你的用户扫码,得到该用户openid
    获取用户openid

  2. 对自己所要发送的信息进行包装,并携带access_token发送给微信服务器,之后,你的公众号就会给特定用户发送信息。

  3. 将做好的项目放到自己的服务器上,并用设置定时任务,用Shell命令每天7.30定时执行文件。为什么要用到服务器,因为服务器是一直开机的,而我的电脑不会。

代码思路

这个代码相对来说比较简单,我只用了三个文件,分别是

  • config.py :配置文件
  • main.py :主要运行文件
  • cityinfo.py:城市信息文件(用来请求对应城市的天气)

main.py中主要为get_access_token get_weather send_message三个函数,他们的内容根据他们的名字一看就懂,分别是获取assess_token 获取天气信息 发送信息

你如何修改我的代码

为了提高代码的复用性,拿到代码的同学只用修改config.py中的配置信息,即把我的配置改成你的配置就行。

不过需要注意的是,我的classes数组是7x5的数组,不要出现索引过界等问题。

源代码

由于代码对这篇文章来说有点多,这里只放main.py的代码。

更多代码已经上传到我的gitee仓库并已经开源

https://gitee.com/dongshengye/wxPost

以下是main.py的代码

from time import time, localtime
import cityinfo
import config
from requests import get, post
from datetime import datetime, date


def get_access_token():
    # appId
    app_id = config.app_id
    # appSecret
    app_secret = config.app_secret
    post_url = ("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}"
                .format(app_id, app_secret))
    print(get(post_url).json())
    access_token = get(post_url).json()['access_token']
    # print(access_token)
    return access_token


def get_weather(province, city):
    # 城市id
    city_id = cityinfo.cityInfo[province][city]["AREAID"]
    # city_id = 101280101
    # 毫秒级时间戳
    t = (int(round(time() * 1000)))
    headers = {
        "Referer": "http://www.weather.com.cn/weather1d/{}.shtml".format(city_id),
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                      'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }
    url = "http://d1.weather.com.cn/dingzhi/{}.html?_={}".format(city_id, t)
    response = get(url, headers=headers)
    response.encoding = "utf-8"
    response_data = response.text.split(";")[0].split("=")[-1]
    response_json = eval(response_data)
    print(response_json)
    weatherinfo = response_json["weatherinfo"]
    # 天气
    weather = weatherinfo["weather"]
    # 最高气温
    temp = weatherinfo["temp"]
    # 最低气温
    tempn = weatherinfo["tempn"]
    return weather, temp, tempn


def send_message(to_user, access_token, city_name, weather, max_temperature, min_temperature):
    url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={}".format(access_token)
    week_list = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
    year = localtime().tm_year
    month = localtime().tm_mon
    day = localtime().tm_mday
    today = datetime.date(datetime(year=year, month=month, day=day))

    week = week_list[today.weekday()]
    theClass = classes[today.weekday()]
    # 获取在一起的日子的日期格式
    love_year = int(config.love_date.split("-")[0])
    love_month = int(config.love_date.split("-")[1])
    love_day = int(config.love_date.split("-")[2])
    love_date = date(love_year, love_month, love_day)
    # 获取在一起的日期差
    love_days = str(today.__sub__(love_date)).split(" ")[0]
    # 获取生日的月和日
    birthday_month = int(config.birthday.split("-")[1])
    birthday_day = int(config.birthday.split("-")[2])
    # 今年生日
    year_date = date(year, birthday_month, birthday_day)
    # 计算生日年份,如果还没过,按当年减,如果过了需要+1
    if today > year_date:
        birth_date = date((year + 1), birthday_month, birthday_day)
        birth_day = str(birth_date.__sub__(today)).split(" ")[0]
    elif today == year_date:
        birth_day = 0
    else:
        birth_date = year_date
        birth_day = str(birth_date.__sub__(today)).split(" ")[0]
    data = {
        "touser": to_user,
        "template_id": config.template_id,
        "url": "http://weixin.qq.com/download",
        "topcolor": "#FF0000",
        "data": {
            "date": {
                "value": "{} {}".format(today, week),
                "color": "#00FFFF"
            },
            "city": {
                "value": city_name,
                "color": "#808A87"
            },
            "weather": {
                "value": weather,
                "color": "#ED9121"
            },
            "min_temperature": {
                "value": min_temperature,
                "color": "#00FF00"
            },
            "max_temperature": {
                "value": max_temperature,
                "color": "#FF6100"
            },
            "love_day": {
                "value": love_days,
                "color": "#87CEEB"
            },
            "birthday": {
                "value": birth_day,
                "color": "#FF8000"
            },
            "firstClass": {
                "value": theClass[0],
                "color": "#FF8000"
            },
            "secondClass": {
                "value": theClass[1],
                "color": "#FF8000"
            },
            "thirdClass": {
                "value": theClass[2],
                "color": "#FF8000"
            },
            "fourthClass": {
                "value": theClass[3],
                "color": "#FF8000"
            },
            "fifthClass": {
                "value": theClass[4],
                "color": "#FF8000"
            }
        }
    }
    headers = {
        'Content-Type': 'application/json',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                      'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }
    response = post(url, headers=headers, json=data)
    print(response.text)


if __name__ == '__main__':
    # 获取accessToken
    accessToken = get_access_token()
    print('token', accessToken)
    # 接收的用户
    user = config.user
    # 传入省份和市获取天气信息
    province, city = config.province, config.city
    classes = config.classes
    weather, max_temperature, min_temperature = get_weather(province, city)
    # 公众号推送消息
    send_message(user, accessToken, city, weather, max_temperature, min_temperature)

写在最后

用一些小小的项目来支撑自己的兴趣,我个人认为还是很有必要的。即可以有实际的应用,也可以让自己更有动力,何乐而不为呢~


网站公告

今日签到

点亮在社区的每一天
去签到