python定時天氣預報(微信提醒)(部署到雲服務器)
聲明:僅供技術交流,請勿用於非法用途,如有其它非法用途造成損失,和本博客無關
需求:拿到當天的天氣預報信息,並且把天氣預報關鍵信息合成語音,然後將天氣預報信息和合成的語音通過微信公衆號發送給粉絲,最後部署程序到雲服務器,設置定時任務運行程序。
ps:有了上一篇的郵件提醒纔有了這一篇點擊跳轉
一、準備工作
在我的上一篇博客中列舉的那些準備,如果這裏也用到的話就不再詳細介紹了哈
- 微信公衆號測試賬號(爲了給微信發送信息)
- 雲盤存放保存合成的語音(爲了拿到能在線播放合成後語音的url地址)
- 雲服務器(爲了部署到雲服務器上)
- 安裝
xshell
(爲了操作雲服務器)
二、準備工作具體步驟
-
微信公衆號測試賬號
打開測試賬號申請頁面,用微信掃碼登錄授權即可http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login點擊跳轉,登錄成功之後你就擁有了一個微信公衆號的接口測試賬號,因爲這些接口包括了很大部分的訂閱號和服務號的接口,測試賬號基本上都可以調用的,我們個人又申請不了服務號,所以用這個測試賬號來練習也是不錯的選擇,好了,我就不過多地介紹他了,現在的接口文檔好像打不開了,不過你可以在這裏看服務號的接口文檔,需要用到的也就幾個而已哈哈,具體步驟如下圖
-
雲盤存放保存合成的語音
這裏的雲盤我找了很久,因爲要找那種可以通過代碼來上傳的網站才行,並且上傳後能提供在線訪問的url
地址,遇到了很多的坑,最後不負有心人,還是找到了一個滿意的雲盤哈哈,他就是OpenDrive
是個外國的網站https://www.opendrive.com點擊跳轉,直接註冊賬號就行了,然後他的接口文檔是用php
寫的,對我這個只會python
的來說,一開始簡直崩潰,不過細細看代碼也能看明白的,要相信自己哈哈。具體怎麼用python
代碼實現請看代碼。具體步驟如下圖:
-
雲服務器
雲服務器還是用三豐雲的免費服務器點擊跳轉,因爲我的上一篇博客已經介紹過了,這裏我就不重複了哈哈 -
安裝
xshell
同上
三、開始敲代碼
廢話不多說,具體細節請看代碼以及註釋。
- 導入需要用到的包
import requests
import json
import os #獲取文件大小
from aip import AipSpeech #百度api
import uuid #用來給合成的語音命名(全球唯一)
import random
- 定義獲取用戶城市的函數
def get_city_id(token,openid):
#token:憑證,openid:即用戶微信號id(是你測試公衆號裏面別人掃碼關注後會有的一個相對於你測試號的唯一id)
url='https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang=zh_CN'.format(token,openid)
r=requests.get(url)
city_id=r.json()['city']
sex=r.json()['sex']
return city_id,sex
- 定義合成語音的函數
def download_mp3(mp3_content,APP_ID,API_KEY,SECRET_KEY,sex):
if sex == 1: #女聲
per=random.choice([0,4,5,103,111])
else: #男聲
per=random.choice([1,3,106,110])
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
result = client.synthesis(mp3_content, 'zh', 1, {'vol': 15,'spd':3,'pit':8,'per': per})
if not isinstance(result, dict):
with open('/home/Juneway/weather.mp3', 'wb') as f:
f.write(result)
- 定義上傳合成語音文件並獲取在線播放url函數
def get_mp3_url(username,passwd):
#第一步:獲取sessionid
url='https://dev.opendrive.com/api/v1/session/login.json'
data={
'username': username,
'passwd' : passwd
}
r=requests.post(url,data=data)
SessionID=r.json()['SessionID']
# #刪除文件
# url = 'https://dev.opendrive.com/api/v1/folder/list.json/%s/NDBfMjA5NDE5MV9KMkNlbw'%SessionID
# r=requests.get(url)
# file_id=r.json()['Files'][0]['FileId']
# url='https://dev.opendrive.com/api/v1/file/trash.json'
# data={
# 'session_id':SessionID,
# 'file_id':file_id,
# 'access_folder_id':'NDBfMjA5NDE5MV9KMkNlbw'
# }
# r=requests.post(url,data=data)
#第二步:上傳文件
file_size=os.path.getsize('/home/Juneway/weather.mp3')
url='https://dev.opendrive.com/api/v1/upload/create_file.json'
data={
'session_id':SessionID,
'folder_id':'NDBfMjA5NDE5MV9KMkNlbw', #表示是music這個文件夾
'file_name':str(uuid.uuid1()).replace('-','')+'.mp3',
'file_size':file_size,
'access_folder_id':'NDBfMjA5NDE5MV9KMkNlbw'
}
r=requests.post(url,data=data)
file_id=r.json()['FileId']
DirUpdateTime=r.json()['DirUpdateTime']
url='https://dev.opendrive.com/api/v1/upload/open_file_upload.json'
data={
'session_id':SessionID,
'file_id':file_id,
'file_size':file_size,
'access_folder_id':'NDBfMjA5NDE5MV9KMkNlbw'
}
r=requests.post(url,data=data)
TempLocation=r.json()['TempLocation']
url='https://dev.opendrive.com/api/v1/upload/upload_file_chunk.json'
data={
'session_id':SessionID,
'file_id':file_id,
'temp_location':TempLocation,
'chunk_offset':0,
'chunk_size':file_size
}
files = {'file_data':open('/home/Juneway/weather.mp3','rb')}
r=requests.post(url,data=data,files=files)
url='https://dev.opendrive.com/api/v1/upload/close_file_upload.json'
data={
'session_id':SessionID,
'file_id':file_id,
'temp_location':TempLocation,
'file_size':file_size,
'file_time':DirUpdateTime,
'access_folder_id':'NDBfMjA5NDE5MV9KMkNlbw'
}
r=requests.post(url,data=data)
#第四步:獲取文件url地址
StreamingLink=r.json()['StreamingLink']
return StreamingLink
- 主函數
def main(appid,secret,key,mb_id,username,passwd,APP_ID,API_KEY,SECRET_KEY):
url='https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}'.format(appid,secret)
r=requests.get(url)
token=r.json()['access_token']
url='https://api.weixin.qq.com/cgi-bin/user/get?access_token=%s&next_openid='%token
r=requests.get(url)
user_list=r.json()['data']['openid']
for openid in user_list:
city_id,sex=get_city_id(token,openid)
url='https://free-api.heweather.net/s6/weather/forecast?location={0}&key={1}'.format(city_id,key)
headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
r=requests.get(url,headers=headers)
data=r.json()
#加上下面的判斷是因爲防止有些人的微信個人信息沒有填地區或者填寫的地區找不到相應的天氣預報
if data['HeWeather6'][0]['status'] == 'ok':
city=data['HeWeather6'][0]['basic']['location'] #城市
forecast_time=data['HeWeather6'][0]['update']['loc'] #預報時間
date=data['HeWeather6'][0]['daily_forecast'][0]['date'] #日期
day_weather=data['HeWeather6'][0]['daily_forecast'][0]['cond_txt_d'] #白天天氣
night_weather=data['HeWeather6'][0]['daily_forecast'][0]['cond_txt_n'] #晚間天氣
wind_dir=data['HeWeather6'][0]['daily_forecast'][0]['wind_dir'] #風向
wind_sc=data['HeWeather6'][0]['daily_forecast'][0]['wind_sc'] #風力
wind_spd=data['HeWeather6'][0]['daily_forecast'][0]['wind_spd'] #風速 公里/小時
tmp_min=data['HeWeather6'][0]['daily_forecast'][0]['tmp_min'] #最低氣溫
tmp_max=data['HeWeather6'][0]['daily_forecast'][0]['tmp_max'] #最高氣溫
sr=data['HeWeather6'][0]['daily_forecast'][0]['sr'] #日出時間
ss=data['HeWeather6'][0]['daily_forecast'][0]['ss'] #日落時間
mr=data['HeWeather6'][0]['daily_forecast'][0]['mr'] #月出時間
ms=data['HeWeather6'][0]['daily_forecast'][0]['ms'] #月落時間
mp3_content='{0}今天早上{1}。晚上{2}。氣溫{3}到{4}攝氏度。{5}。風力{6}級。風速{7}公里每小時。{8}日出。{9}日落。{10}月出。{11}月落。'.format(city,day_weather,night_weather,tmp_min,tmp_max,wind_dir,wind_sc,wind_spd,sr,ss,mr,ms)
#合成mp3
download_mp3(mp3_content,APP_ID,API_KEY,SECRET_KEY,sex)
#獲取mp3的url
mp3_url=get_mp3_url(username,passwd)
msg={
'touser':openid,
'template_id':mb_id, #模板id
'url':mp3_url,
'data':{
'city':{
'value':city,
'color':'#173177'
},
'date':{
'value':date,
'color':'#173177'
},
'day_weather':{
'value':day_weather,
'color':'#173177'
},
'night_weather':{
'value':night_weather,
'color':'#173177'
},
'wind_dir':{
'value':wind_dir,
'color':'#173177'
},
'wind_sc':{
'value':wind_sc,
'color':'#173177'
},
'wind_spd':{
'value':wind_spd,
'color':'#173177'
},
'tmp_min':{
'value':tmp_min,
'color':'#173177'
},
'tmp_max':{
'value':tmp_max,
'color':'#173177'
},
'sr':{
'value':sr,
'color':'#173177'
},
'ss':{
'value':ss,
'color':'#173177'
},
'mr':{
'value':mr,
'color':'#173177'
},
'ms':{
'value':ms,
'color':'#173177'
}
}
}
json_data=json.dumps(msg)
url='https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s'%token
#發送推文
r=requests.post(url,data=json_data)
- 程序入口
if __name__ == '__main__':
key = '你自己和風天氣應用的key' #和風天氣api
mb_id = '填你的模板id' #模板id
appid = '填你自己的' #測試公衆號
secret = '填你自己的' #測試公衆號
username = '賬號' #OpenDrive
passwd = '密碼' #OpenDrive
APP_ID = '填你自己的' #百度api
API_KEY = '填你自己的' #百度api
SECRET_KEY = '填你自己的' #百度api
main(appid,secret,key,mb_id,username,passwd,APP_ID,API_KEY,SECRET_KEY)
四、部署到雲服務器
五、結果展示
這個是對應語音的url
https://od.lk/s/NDBfMTEyODk2MDZf/6295074e130411ea863300155d08ba50.mp3點擊跳轉
ps:如果你不想敲代碼自己做的話,可以直接掃一掃下面的二維碼關注一下就可以了哦,名額有限哦哈哈
寫在最後
一開始,爲了想讓微信發語音繞了很多彎路,因爲微信發送的推文,點擊推文的話會進去一個聲明好的鏈接裏面,然後我就從這裏開始入手,就開始各種百度搜本地文件上傳到網絡上並拿到其在線訪問的url
,一開始想過用selenium
來模擬點擊來上傳文件,然後想想好像不現實,而且也不帥,於是就再找啊找,就希望能夠找到一個可以通過編寫代碼來上傳文件的網站,於是乎,便找到了OpenDrive
,發現他非常符合我的需求,可是他是一個外國的網站,並且其文檔是用php
語言來做事例的,一開始我是拒絕的,甚至還想請教一下身邊學php
的同事,不過我想了想,這麼簡單也要問別人?而且都做到這最後一步了,自己做出來成就感纔會爆棚。於是乎,我咬緊牙關一行代碼一行代碼的看php
,發現其實也不是很難嘛,我邊看邊想着怎麼用python
代碼來實現,最後在file_data
這個參數上面撞上了,我又開始各種百度python
上傳文件的案例,最後恍然大悟中做了出來哈哈。記得當時我大叫了一聲,幸好當時已經下班了,沒多少人在哈哈哈。