公众号每日自动发早/晚安消息(python实现)
前言
最近给女朋友的早安公众号制作在短视频平台爆火,虽然网上的教程有很多但都很零散,可能按着做着就出错或者某个地方对应不上,因此本文章就详细地从头教到尾。全部代码在 我的gitee仓库可自行下载
一、微信公众号测试号申请
测试号要先在微信公众平台进行申请注册,申请完毕都能得到自己的测试号信息如下:
测试号二维码让需要发送信息的对象扫并关注,就可以得到其微信号。
模板消息的配置,可以自行复制粘贴,每一个对应一个模板消息。
# 发送早安消息模板内容(给女朋友)
{{content.DATA}}
{{date.DATA}}
{{city.DATA}}
{{weather.DATA}}
{{min_temperature.DATA}}
{{max_temperature.DATA}}
{{love_day.DATA}}
{{birthday.DATA}}
# 发送早安消息模板内容(给普通用户)
{{content.DATA}}
{{date.DATA}}
{{city.DATA}}
{{weather.DATA}}
{{min_temperature.DATA}}
{{max_temperature.DATA}}
# 发送晚安消息模板内容(给女朋友)
{{content.DATA}}
{{like.DATA}}
# 发送晚安消息模板内容(给普通用户)
{{content.DATA}}
这样微信测试号的配置就完成了
二、文件的配置
1.config.py
config.py是信息配置文件。app_id和app_secret是自己的测试号信息;早安或者晚安模板消息填写对应模板id就行;user是一个储存发送对象的字典,其中userid是测试二维码下列表的用户微信号;kind是消息分类发送的标志,分为baby和user两种类型,对应女朋友和普通用户;province和city分别对应发送对象的省/市和城市,详情见cityinfo.py文件。 birthday和love_day是生日时间和在一起的开始时间。
# 公众号配置
# 公众号appId
app_id = ""
# 公众号appSecret
app_secret = ""
# 早安模板消息id
template_id = {"id_forUser": "",
"id_forBaby": ""}
# 晚安模板消息id
template_id_n = {"id_forUser": "",
"id_forBaby": ""}
# 用户信息配置 userid:微信用户id kind:用户类型(baby/user) province:省 city:区
# birthday:用户生日 yyyy-m-d 如2000-1-3 、2000-11-23 不填就填None
# love_day:恋爱时间起始点 yyyy-m-d 如2000-1-3 、2000-11-23 不填就填None
user = [{"userid": "", "kind": "user", "province": "",
"city": "", "birthday": "None", "love_date": "None"},
{"userid": "", "kind": "baby", "province": "",
"city": "", "birthday": "2002-9-25", "love_date": "2018-8-8"},
]
2.getApi.py
getApi.py是用于获得接口数据的文件,列如获得天气预报、心灵鸡汤等。其中早安心语和晚安心语需要自行去 天行数据 注册申请(每个接口每日免费一百次访问),获得自己的key填写代码位置即可。
# 通过api获取json数据
from time import time
from requests import get
import cityinfo
import config
import http.client
import urllib
import json
# 获得微信的access_token
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))
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"]
# 毫秒级时间戳
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
# 每日早安心语 天行数据:https://www.tianapi.com/apiview/143(免费)
# 需要填写自己的key
def getEvDayZaoAn():
conn = http.client.HTTPSConnection('api.tianapi.com') # 接口域名
# --------------------------------这里填写----------------------------------------
params = urllib.parse.urlencode({'key': 'your key'})
headers = {'Content-type': 'application/x-www-form-urlencoded'}
conn.request('POST', '/zaoan/index', params, headers)
res = conn.getresponse()
data = res.read()
# 获得json数据
data_json = data.decode('utf-8')
# json数据>>>python dict 数据
data_python = json.loads(data_json)
# print(data_python)
# python dict数据>>>需要的list数据
newList = data_python.get('newslist')
# list数据>>>dict数据
newList_dict = newList[0]
# 每日早安
content = newList_dict.get('content')
return content
# print(content)
# 每日晚安心语 天行数据:https://www.tianapi.com/apiview/142(免费)
# 需要填写自己的key
def getEvDayWanAn():
conn = http.client.HTTPSConnection('api.tianapi.com') # 接口域名
# --------------------------------这里填写----------------------------------------
params = urllib.parse.urlencode({'key': ''})
headers = {'Content-type': 'application/x-www-form-urlencoded'}
conn.request('POST', '/wanan/index', params, headers)
res = conn.getresponse()
data = res.read()
# 获得json数据
data_json = data.decode('utf-8')
# json数据>>>python dict 数据
data_python = json.loads(data_json)
# print(data_python)
# python dict数据>>>需要的list数据
newList = data_python.get('newslist')
# list数据>>>dict数据
newList_dict = newList[0]
# 每日晚安
content = newList_dict.get('content')
return content
# print(content)
三、其他文件(可直接使用)
1.sayGoodMoring.py/sayGoodNight.py( 运行文件)
# 发早安消息的主运行文件
import config
import getApi
import getJson
import getSomeDay
import sendMessage
if __name__ == '__main__':
access_token = getApi.get_access_token()
# 接收的所有用户信息
user = config.user
for i in range(len(user)):
# 单个用户信息列表
user_dict = user[i]
# 用户id
touser = user_dict.get("userid")
# 用户类别
kind = user_dict.get("kind")
# 传入省份和市获取天气信息
province, city = user_dict.get("province"), user_dict.get("city")
weather, max_temperature, min_temperature = getApi.get_weather(province, city)
# 获得时间
today, week = getSomeDay.getTime()
# birthday
birth_day = getSomeDay.getbirthDay(user_dict.get("birthday"), kind)
# love_day
love_day = getSomeDay.getlove_day(user_dict.get("love_date"), kind)
# 数据列表
data_list = [touser, today, week, weather, birth_day, love_day, city, kind, max_temperature, min_temperature]
data = getJson.getmoring_json(data_list)
sendMessage.send_message(access_token, data)
# 发晚安消息的主运行文件
import config
import getApi
import getJson
import sendMessage
if __name__ == '__main__':
access_token = getApi.get_access_token()
# 接收的所有用户信息
user = config.user
for i in range(len(user)):
# 单个用户信息列表
user_dict = user[i]
# 用户id
touser = user_dict.get("userid")
# 用户类别
kind = user_dict.get("kind")
data = getJson.getNight_json(touser, kind)
sendMessage.send_message(access_token, data)
2.getJson.py
getJson.py主要用于配置公众号信息发送时的样式,比如字体颜色等。
import config
import getApi
# 早安的json数据
def getmoring_json(data_list):
# 数据整合
to_user = data_list[0]
day = data_list[1]
wek = data_list[2]
wea = data_list[3]
birthday = data_list[4]
lovedays = data_list[5]
city_name = data_list[6]
type = data_list[7]
max = data_list[8]
min = data_list[9]
content = getApi.getEvDayZaoAn()
data_baby = {
"touser": to_user,
"template_id": config.template_id.get("id_forBaby"),
"url": "https://m.tianqi.com/",# 可以不填
"topcolor": "#FF0000",
"data": {
"content":
{
"value": content,
"color": "#000000"
},
"date":
{
"value": "今天是" + "{} {}".format(day, wek),
"color": "#8470FF"
},
"city": {
"value": "城市:" + city_name,
"color": "#808A87"
},
"weather": {
"value": "天气:" + wea,
"color": "#ED9121"
},
"min_temperature": {
"value": "最低气温:" + min,
"color": "#00FF00"
},
"max_temperature": {
"value": "最高气温" + max,
"color": "#FF6100"
},
"love_day": {
"value": "今天是我们恋爱的第" + lovedays + "天",
"color": "#FFC0CB"
},
"birthday": {
"value": "距离小宝的生日还有" + birthday + "天",
"color": "#FF8000"
}
}
}
data_user = {
"touser": to_user,
"template_id": config.template_id.get("id_forUser"),
"url": "https://m.tianqi.com/",
"topcolor": "#FF0000",
"data": {
"content":
{
"value": content,
"color": "#000000"
},
"date": {
"value": "今天是" + "{} {}".format(day, wek),
"color": "#8470FF"
},
"city": {
"value": "城市:" + city_name,
"color": "#808A87"
},
"weather": {
"value": "天气:" + wea,
"color": "#ED9121"
},
"min_temperature": {
"value": "最低气温:" + min,
"color": "#00FF00"
},
"max_temperature": {
"value": "最高气温" + max,
"color": "#FF6100"
}
}
}
if type == "baby":
return data_baby
else:
return data_user
# 晚安的json数据
def getNight_json(to_user, type):
content = getApi.getEvDayWanAn()
data_baby = {
"touser": to_user,
"template_id": config.template_id_n.get("id_forBaby"),
"url": "https://music.163.com/",
"topcolor": "#FF0000",
"data": {
"content":
{
"value": content,
"color": "#000000"
},
"like":
{
"value": "时间过得真快 我们在一起的时间又多了一天,晚安宝贝",
"color": "#000000"
}
}
}
data_user = {
"touser": to_user,
"template_id": config.template_id_n.get("id_forUser"),
"url": "https://music.163.com/",
"topcolor": "#FF0000",
"data": {
"content":
{
"value": content,
"color": "#000000"
},
}
}
if type == "baby":
return data_baby
else:
return data_user
3.getSomeDay.py
getSomeDay.py是函数计算距离生日还有好多天、在一起一共多少天,还有获得今日时间。
from datetime import datetime, date
from time import localtime
# 获得生日/相爱时间
# 时间函数 获得当前时间
def getTime():
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.isoweekday() - 1]
return today, week
# 时间函数 获得生日时间差
def getbirthDay(birthday, temp):
if temp == "user":
return birthday
else:
year = localtime().tm_year
month = localtime().tm_mon
day = localtime().tm_mday
today = datetime.date(datetime(year=year, month=month, day=day))
# 获取生日的月和日
birthday_month = int(birthday.split("-")[1])
birthday_day = int(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]
return birth_day
# 时间函数 获得相爱时间差
def getlove_day(love_date, temp):
if temp == "user":
return love_date
else:
year = localtime().tm_year
month = localtime().tm_mon
day = localtime().tm_mday
today = datetime.date(datetime(year=year, month=month, day=day))
# 获取在一起的日子的日期格式
love_year = int(love_date.split("-")[0])
love_month = int(love_date.split("-")[1])
love_day = int(love_date.split("-")[2])
love_date = date(love_year, love_month, love_day)
# 获取在一起的日期差
love_days = str(today.__sub__(love_date)).split(" ")[0]
return love_days
4.sendMessage.py
sendMessage.py调用微信的模板消息接口,用于发送消息。
from requests import post
def send_message(access_token, data):
url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={}".format(access_token)
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)
5.cityinfo.py
cityinfo.py是城市信息的配置文件 不需要改 但是文件内容太大 就在这不展示了 详情见我gitee库
四、云服务器的配置
1.云服务器的选择
我使用的云服务器是 腾讯云 的轻量应用服务器2核2G。完成注册认证登录后,选择官方镜像中应用镜像的宝塔Linux面板(因为使用简单方便)。
2.服务器的配置与登录宝塔面板
进入控制台,先重置密码,方便自己登录。
查看防火墙是否有8888端口号的开放,如果没用点击添加规则,如下图所示,添加8888端口即可。
进行步骤3复制代码,点击登录,跳转到webshell控制台,一键免密登录,第一次进入webshell会提示你下载编译,下载完成后粘贴刚刚复制的,enter键执行。复制外网面板地址到浏览器,输入username和password,登录宝塔面板。
3.宝塔面板
进入先去软件商城下载python项目管理器(配置简单方便),下载完成后,进入python项目管理器,版本管理中下载python3版本的(我用的是3.9.7)。ps:宝塔面板自带的python版本是python2.(下载python3后面还可以为公众号搭站)
点击终端进行登录验证输入刚刚你重置的密码,服务器ip是你自己服务器的内网ip(公网ip)。在终端输入python3 -V,查看python是否安装成功。
点击文件,找到home文件,进入创建文件夹sayGoodMorN,在sayGoodMorN文件夹内点击上传,上传我们配置好的全部py文件。如下图所示。
上传完毕后在sayGoodMorN文件夹下点击终端,进入终端执行以下代码,发送成功则有如下图所示。
python3 sayGoodMoring.py
点击计划任务,添加计划任务,按着下图填写就行(早安同理)
这样每日早安晚安的公众号就配置完成了。
都看到这里,觉得有用就留下你的赞吧。