python爬虫(21)给微信好友发送天气预报

用微信定时给好友发送天气预报

环境

系        统:windows10系统
编  辑  器:Sublime3
编程语言:python3
库           :wxpy、tkinter

前言

之前写过一个程序,获取7天内天气预报的,但是仅仅是获取到七天内某个城市的天气预报,没有想过具体的实际案例。
随后看了一些其他的模块,感觉跟微信结合起来的应用场景还是挺实用的,然后就把它折腾出来了。

基本功能

基本功能其实也是核心功能,主要就是获取指定城市的天气情况
本次利用的是百度的一个api网址:
http://api.map.baidu.com/telematics/v3/weather?location=%s&output=json&ak=TueGDhCvwI6fOrQnLM0qmXxY9N0OkOiQ&callback=?
其中location这个参数后面跟的就是城市,调用这个api可以获取到当前城市天气情况,比如北京当前天气:

python爬虫(21)给微信好友发送天气预报

得到的是json数据,经过简单的处理就可以得到能看的数据

核心程序如下:

#发送天气情况
def send_weather(location):

    path ='http://api.map.baidu.com/telematics/v3/weather?location=%s&output=json&ak=TueGDhCvwI6fOrQnLM0qmXxY9N0OkOiQ&callback=?'
    url = path % location
    print(url)
    response = requests.get(url)
    result = response.json()

    #如果城市错误就按照海淀发送天气
    if result['error'] !=0:
        location ='海淀'
        url = path % location
        print(url)
        response = requests.get(url)
        result = response.json()

    str0 = ('    这是今天的天气预报!\n')
    results = result['results']

    # 取出数据字典

    data1 = results[0]

    # 取出城市
    city = data1['currentCity']
    str1 ='    当前地区: %s\n' % city

    # 取出pm2.5值
    pm25 = data1['pm25']
    str2 ='    Pm值    : %s\n' % pm25

    # 将字符串转换为整数 否则无法比较大小
    if pm25 =='':
        pm25 =0
    pm25 =int(pm25)

    # 通过pm2.5的值大小判断污染指数
    if 0 <= pm25 <35:
        pollution ='优'
    elif 35 <= pm25 <75:
        pollution ='良'
    elif 75 <= pm25 <115:
        pollution ='轻度污染'
    elif 115 <= pm25 <150:
        pollution ='中度污染'
    elif 150 <= pm25 <250:
        pollution ='重度污染'
    elif pm25 >=250:
        pollution ='严重污染'
    str3 ='    污染指数: %s\n' % pollution

    result1 = results[0]

    weather_data = result1['weather_data']
    data = weather_data[0]
    #实时温度
    temperature_now = data['date']
    str4 ='    当前温度: %s\n' % temperature_now

    #风向
    wind = data['wind']
    str5 ='    风向    : %s\n' % wind

    #天气和温度
    weather = data['weather']
    str6 ='    天气    : %s\n' % weather
    str7 ='    温度    : %s\n' % data['temperature']

    #其他提示
    message = data1['index']
    str8 ='    穿衣    : %s\n' % message[0]['des']
    str9 ='    温馨提示: %s\n' % message[2]['des']
    str10 ='    运动    : %s\n' % message[3]['des']
    str11 ='    紫外线 : %s\n' % message[4]['des']

    #未来天气情况
    weather_data=result1['weather_data']
    future1='\t%s \n\t\t\t\t温度:%s\n\t\t\t\t天气:%s\n\t\t\t\t风向:%s\n ' % (weather_data[1]['date'],weather_data[1]['temperature'],weather_data[1]['weather'] ,weather_data[1]['wind'])
    future2='\t%s \n\t\t\t\t温度:%s\n\t\t\t\t天气:%s\n\t\t\t\t风向:%s\n ' % (weather_data[2]['date'],weather_data[2]['temperature'],weather_data[2]['weather'] ,weather_data[2]['wind'])
    future3='\t%s \n\t\t\t\t温度:%s\n\t\t\t\t天气:%s\n\t\t\t\t风向:%s\n ' % (weather_data[3]['date'],weather_data[3]['temperature'],weather_data[3]['weather'] ,weather_data[3]['wind'])
    future_weather='未来三天天气:\n'+future1+future2+future3
	
    str = str0 + str1 + str2 + str3 + str4 + str5 + str6 + str7 + str8 + str9 + str10 + str11+future_weather
    return str

 

PC上面的UI界面

将这个功能做成有UI界面的,可以输入一下城市,显示出该城市的天气情况,

核心代码如下:

def GUI():
	window=tk.Tk()
	#window.geometry('800*600')
	window.title('天气预报')

	def checkPassword():
		entercity = passwordEntry.get()
		confirmLable.delete(0,tk.END)

		weather=send_weather(entercity)

		for i in weather.split('\n'):
			confirmLable.insert(tk.END,i)


	passwordLabel=tk.Label(window,text='请输入城市',height=2,width=10,font=("Times", 10,'bold'),fg='red')
	passwordLabe = tk.Label(window,text='例如北京,张家界',height=2,width=10,font=('Times',10),fg='red')


	e=StringVar()
	passwordEntry =tk.Entry(window,width=25,textvariable=e,font=('Times',20,"bold"))
	e.set('北京')
	button=tk.Button(window,text='确定',command=checkPassword)

	confirmLable=tk.Listbox(window,height=10,width=45,font=('Times',20,'bold'),fg='blue',bg='#EEE5DE')

	passwordLabel.pack()
	passwordLabe.pack()
	passwordEntry.pack()
	button.pack()
	confirmLable.pack()

	window.mainloop()
GUI()

运行程序,效果如下:

python爬虫(21)给微信好友发送天气预报

和微信结合

大体思路是这样的,将上面UI里面换成微信好友的list,然后呢,微信里面,每个人都有一个地区显示,根据好友的地区向他们发送天气预报
显示上呢,前面好友名字,后面是好友所在城市,如果好友没有设置,就默认是北京

效果如下:

python爬虫(21)给微信好友发送天气预报

双击好友名字就可以直接给发送天气预报了.

全部代码

# -*- coding: utf-8 -*-
# @Date     : 2018-12-05 17:12:20
# @Author   : Jimy_Fengqi ([email protected])
# @Link     : https://blog.****.net/qiqiyingse
# @Version  : V1.0
# @pyVersion: 3.6

from tkinter import *
from wxpy import Bot
import requests,re
#发送天气情况
def send_weather(location):

    path ='http://api.map.baidu.com/telematics/v3/weather?location=%s&output=json&ak=TueGDhCvwI6fOrQnLM0qmXxY9N0OkOiQ&callback=?'
    url = path % location
    print(url)
    response = requests.get(url)
    result = response.json()

    #如果城市错误就按照海淀发送天气
    if result['error'] !=0:
        location ='海淀'
        url = path % location
        print(url)
        response = requests.get(url)
        result = response.json()

    str0 = ('    这是今天的天气预报!\n')
    results = result['results']

    # 取出数据字典

    data1 = results[0]

    # 取出城市
    city = data1['currentCity']
    str1 ='    当前地区: %s\n' % city

    # 取出pm2.5值
    pm25 = data1['pm25']
    str2 ='    Pm值    : %s\n' % pm25

    # 将字符串转换为整数 否则无法比较大小
    if pm25 =='':
        pm25 =0
    pm25 =int(pm25)

    # 通过pm2.5的值大小判断污染指数
    if 0 <= pm25 <35:
        pollution ='优'
    elif 35 <= pm25 <75:
        pollution ='良'
    elif 75 <= pm25 <115:
        pollution ='轻度污染'
    elif 115 <= pm25 <150:
        pollution ='中度污染'
    elif 150 <= pm25 <250:
        pollution ='重度污染'
    elif pm25 >=250:
        pollution ='严重污染'
    str3 ='    污染指数: %s\n' % pollution

    result1 = results[0]

    weather_data = result1['weather_data']
    data = weather_data[0]
    #实时温度
    temperature_now = data['date']
    str4 ='    当前温度: %s\n' % temperature_now

    #风向
    wind = data['wind']
    str5 ='    风向    : %s\n' % wind

    #天气和温度
    weather = data['weather']
    str6 ='    天气    : %s\n' % weather
    str7 ='    温度    : %s\n' % data['temperature']

    #其他提示
    message = data1['index']
    str8 ='    穿衣    : %s\n' % message[0]['des']
    str9 ='    温馨提示: %s\n' % message[2]['des']
    str10 ='    运动    : %s\n' % message[3]['des']
    str11 ='    紫外线 : %s\n' % message[4]['des']

    #未来天气情况
    weather_data=result1['weather_data']
    future1='\t%s \n\t\t\t\t温度:%s\n\t\t\t\t天气:%s\n\t\t\t\t风向:%s\n ' % (weather_data[1]['date'],weather_data[1]['temperature'],weather_data[1]['weather'] ,weather_data[1]['wind'])
    future2='\t%s \n\t\t\t\t温度:%s\n\t\t\t\t天气:%s\n\t\t\t\t风向:%s\n ' % (weather_data[2]['date'],weather_data[2]['temperature'],weather_data[2]['weather'] ,weather_data[2]['wind'])
    future3='\t%s \n\t\t\t\t温度:%s\n\t\t\t\t天气:%s\n\t\t\t\t风向:%s\n ' % (weather_data[3]['date'],weather_data[3]['temperature'],weather_data[3]['weather'] ,weather_data[3]['wind'])
    future_weather='未来三天天气:\n'+future1+future2+future3
	
    str = str0 + str1 + str2 + str3 + str4 + str5 + str6 + str7 + str8 + str9 + str10 + str11+future_weather
    return str



bot=Bot(cache_path=True)
my_friends=bot.friends()


root = Tk()
root.title('微信版本天气预报')
frame=Frame(root)
frame.pack()
def printList(event):
    print (lb.get(lb.curselection()) )
sb = Scrollbar(frame)    #垂直滚动条组件
sb.pack(side=RIGHT,fill=Y)  #设置垂直滚动条显示的位置
lb = Listbox(frame,selectmode=SINGLE,yscrollcommand=sb.set,height=10,width=25,font=('Times',10,'bold'),fg='green',bg='#EEE5DE')

lb.bind('<Double-Button-1>',printList)
#lb.bind('<Button-1>',printList)

for friend in my_friends:
    print(friend.remark_name,friend,friend.name,friend.nick_name)    
    if friend.city == '':
        lb.insert(END,str(friend.name)+'-------'+'未设置城市')
    else:
        lb.insert(END,str(friend.name)+'-------'+str(friend.city))



lb.pack(side=LEFT,fill=BOTH)
sb.config(command=lb.yview) #设置Scrollbar组件的command选项为该组件的yview()方法

	
def showthings():
    confirmLable.delete(0,END)
    content=lb.get(lb.curselection())
    confirmLable.insert(END,content)
    city=content.split('-------')[-1]
    if city == '未设置城市':
        city='河南'
        confirmLable.insert(END,'该好友未设置地区,默认为河南')
        weather_report=send_weather(city)
    else:
        weather_report=send_weather(city)
    firend_= my_friends.search(content.split('-------')[0])[0]
    #confirmLable.insert(END,firend)
    for i in weather_report.split('\n'):
        confirmLable.insert(END,i)
    print(firend_)
    firend_.send(weather_report)
    bot.file_helper.send('发送完毕') 

frame2=Frame(root)
frame2.pack()



button=Button(frame2,text='发送天气情况',command=showthings,font=('Times',20,'bold'),fg='green',bg='#EAE5DE')
button.pack()
frame3=Frame(root)
frame3.pack()
confirmLable=Listbox(frame3,height=10,width=45,font=('Times',20,'bold'),fg='blue',bg='#EEE5DE')
confirmLable.pack()
root.mainloop()