天气API

使用聚合网的天气API,每天免费50次

接口地址: http://apis.juhe.cn/simpleWeather/query
请求方式: GET
请求参数; city
拼接方式: http://apis.juhe.cn/simpleWeather/query?city={city}&key={key}

请求Key: 实名认证后会有

img

测试账号

微信公众平台接口测试账号,注册一个测试账号,记下appid和secret,扫码后产生的用户ID、模板ID,填入config.txt文件中

自己的公众号不记得密码了,擦,先用测试的吧

img
{{date.DATA}}
城市:{{city.DATA}}
天气:{{weather.DATA}}
实时气温:{{temperature.DATA}}
湿度:{{humioity.DATA}}
风向:{{direct.DATA}}
您已经在地球上存活了:{{live.DATA}}天
 
{{note_ch.DATA}}
{{note_en.DATA}}

配置文件

{
"appid": "appid",
"secret": "secret",
"template_id": "0sXNi6sorkdKHVKS8UuQdRARS39vaBu94YyqbmW7GtI",
"user": ["oGeX96kGhg-wEhbKEstfGe93cAiQ","oGeX96pRe_r-0PfdsJ09zzk5juHI"], 
"key": "7ccd03d19e2920224cdadd2ae2bdfd07",

"birthday": "2000-03-11",
"weather_key": "7ccd03d19e2920224cdadd2ae2bdfd07",
"region": ["保定","石家庄"], 
"note_ch": "good good learn,day day up", 
"note_en": "study hard and make progress every day!" 
}

代码

在main中读取配置文件并调用函数

if __name__ == "__main__":
    try:
        with open("config.txt", encoding="utf-8") as f:
            config = eval(f.read())
    except FileNotFoundError:
        print("推送消息失败,请检查config.txt文件是否与程序位于同一路径")
        os.system("pause")
        sys.exit(1)
    except SyntaxError:
        print("推送消息失败,请检查配置文件格式是否正确")
        os.system("pause")
        sys.exit(1)


    # 获取accessToken
    accessToken = get_access_key()
    # 接收的用户
    users = config["user"]
    # 传入地区获取天气信息
    citys = config["region"]
    note_ch = config["note_ch"]
    note_en = config["note_en"]
    #模板id
    template_id = config["template_id"]

    for usr,city in zip(users,citys):
        weather, temperature, humidity, direct = get_weather(city)
        send_msg(usr,accessToken,template_id,weather,temperature,humidity,direct,note_ch,note_en)

同时循环两个及以上列表要加zip()

for usr,city in zip(users,citys):
        weather, temperature, humidity, direct = get_weather(city)
        send_msg(usr,accessToken,template_id,weather,temperature,humidity,direct,note_ch,note_en)

这个循环考虑了多个用户,不同城市,目前存放的时候只能一一对应,后面可以将配置文件读入转化为Json,里面放一个users,每一个user对应城市、生日等等用户信息。读入程序后,赋给实体对象,这样外循环只遍历用户对象就行了,还方便增删查改。没毛病 。用户idcity。定义一个user类

class User:
    def __init__(self, id, city,birthday):
        self.id = id
        self.city = city
        self.birthday = birthday

//TODO 能不能获取用户微信上的地址,更方便

将txt文件转换为json文件

读取文件中的每一行,并将其拆分为键和值对,来创建一个Python字典对象。对于值是一个JSON字符串的情况下,我们使用 json.loads() 函数将其解析成Python对象。最后,我们可以使用 json.dump() 将字典对象写入新的JSON文件中。

import json
def txt2json():
# 读取文本文件
    with open('config.txt', 'r') as f:
        lines = f.readlines()
    
    # 将文本转换为字典对象
    data = {}
    for line in lines:
        key, val = line.strip().split(': ')
        try:
            val = json.loads(val)
        except ValueError:
            pass
        data[key] = val
    
    # 将字典对象写入JSON文件
    with open('config.json', 'w') as f:
        json.dump(data, f)

读取Json文件建立userduix

def CreateUsersByJson():
    with open('config.json', 'r') as f:
        data = json.load(f)

    users = []
    for user_data in data['users'].values():
        users.append(User(user_data['id'], user_data['city'],user_data['birthday']))
    return users

根据appidsecret获取密钥accessToken

这个在后面发消息会用到

def get_access_key():
    appid = config['appid']
    secret = config['secret']
    url = f'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}'
    response = requests.get(url).json()
    access_token = ''
    if response['expires_in'] == 7200:
        access_token = response['access_token']
        return access_token
    else:
        print("appid或secret错误")

根据城市获得天气

聚合网查询得到的json数据为:

{"reason":"查询成功!","result":{"city":"保定","realtime":{"temperature":"37","humidity":"23","info":"晴","wid":"00","direct":"西南风","power":"5级","aqi":"125"},"future":[{"date":"2023-06-16","temperature":"23\/38℃","weather":"晴","wid":{"day":"00","night":"00"},"direct":"南风"},{"date":"2023-06-17","temperature":"23\/36℃","weather":"晴转多云","wid":{"day":"00","night":"01"},"direct":"西南风转东北风"},{"date":"2023-06-18","temperature":"24\/36℃","weather":"多云转中雨","wid":{"day":"01","night":"08"},"direct":"东北风"},{"date":"2023-06-19","temperature":"19\/27℃","weather":"雷阵雨转阴","wid":{"day":"04","night":"02"},"direct":"东北风转北风"},{"date":"2023-06-20","temperature":"17\/25℃","weather":"雷阵雨转多云","wid":{"day":"04","night":"01"},"direct":"北风转东北风"}]},"error_code":0}

未来天气就算了吧,毕竟每天推送,郁闷的是当日天气没有最低最高温度,只有实时温度。。。。这个API不行

  • r = requests.get(url,headers)得到的是一个response对象,需要调用res = r.json()转换为json格式,然后就可以访问键值。
  • 函数返回天气、实时温度、湿度、风向。
def get_weather(city):
    key = config["key"]
    headers = {
        'Referer': 'http://apis.juhe.cn/simpleWeather/query',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
    }
    url = f'http://apis.juhe.cn/simpleWeather/query?city={city}&key={key}'
    r = requests.get(url,headers)
    r.encoding = "utf8"
    res = r.json()
    realtime = res['result']['realtime']
    temperature = realtime['temperature']
    humidity = realtime['humidity']
    weather = realtime['info']  #晴
    direct = realtime['direct'] #风
    return weather,temperature,humidity,direct

推送消息

strptime(要转换为datetime的字符串,输入的格式)

reques.post(sendMessage_url, data=json.dumps(data)).json()向指定的URL发送POST请求,并将发送的数据以JSON格式进行编码。将响应结果保存为json数据

json.dumps(data)将字典转换成一个Json字符串

这个不用了,太蠢了

def send_msg(user,accessToken,template_id,weather,temperature,humioity,direct, note_ch, note_en):
    sendMessage_url = f"https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={accessToken}"
    # 当前日期和星期
    week_list = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
    year = localtime().tm_year
    month = localtime().tm_mon
    day = localtime().tm_mday
    week = week_list[datetime.date(int(year), int(month), int(day)).weekday()]
    date = f'{year}年{month}月{day}日  {week}'

    # 活了多久
    birthday_date = datetime.datetime.strptime(config['birthday'], "%Y-%m-%d")
    curr_datetime = datetime.datetime.now()
    minus_datetime = curr_datetime - birthday_date
    
    data = {
        "touser": user,
        "template_id": template_id,
        "appid": config['appid'],
        "data": {
            "live": {
                "value": minus_datetime.days,
                "color": get_color()
            },
            "city": {
                "value": city,
                "color": get_color()
            },
            "weather": {
                "value": weather,
                "color": get_color()
            },
            "temperature": {
                "value": temperature,
                "color": get_color()
            },
            "humioity": {
                "value": humioity,
                "color": get_color()
            },
            "direct": {
                "value": direct,
                "color": get_color()
            },
            'note_ch': {
                "value": note_ch,
                "color": get_color()
            },
            'note_en': {
                "value": note_en,
                "color": get_color()
            }

        }
    }
    getTemp = requests.post(sendMessage_url, data=json.dumps(data)).json()

修改之后的推送消息

参数只有user,看着舒服多了

def SendMsg(user):
    city = user.city
    weather, temperature, humidity, direct = get_weather(city)
    sendMessage_url = f"https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={accessToken}"
    
    birthday_date = datetime.datetime.strptime(config['birthday'], "%Y-%m-%d")
    curr_datetime = datetime.datetime.now()
    minus_datetime = curr_datetime - birthday_date
    
    data = {
        "touser": user.id,
        "template_id": template_id,
        "appid": config['appid'],
        "data": {
            "live": {
                "value": minus_datetime.days,
                "color": get_color()
            },
            "city": {
                "value": city,
                "color": get_color()
            },
            "weather": {
                "value": weather,
                "color": get_color()
            },
            "temperature": {
                "value": temperature,
                "color": get_color()
            },
            "humioity": {
                "value": humidity,
                "color": get_color()
            },
            "direct": {
                "value": direct,
                "color": get_color()
            },
            'note_ch': {
                "value": note_ch,
                "color": get_color()
            },
            'note_en': {
                "value": note_en,
                "color": get_color()
            }
        }
    }
    getTemp = requests.post(sendMessage_url, data=json.dumps(data)).json()
    //TODO 对getTemp判断

get_color()随机选择颜色,抄的

def get_color():
    # 获取随机颜色
    get_colors = lambda n: list(map(lambda i: "#" + "%06x" % random.randint(0, 0xFFFFFF), range(n)))
    color_list = get_colors(100)
    return random.choice(color_list)

结果

测试号上可行,推送样式如图:

img

做好了才发现个人公众号不能推送模板信息。。。搞不了。。。

img