python制作天气预报的代码怎么写
这篇文章主要讲解了“python制作天气预报的代码怎么写”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python制作天气预报的代码怎么写”吧!
源代码1.Weather_Tool-v1.0.py
fromtkinterimport*fromtkinterimportttkfromPILimportImage,ImageTkfromtkinterimportmessageboxfromWeather_SpiderimportWeather_GetfromthreadingimportThreadimportdatetimeimporttime'''5-11.打开首页定位当前位置获取天气(ip定位+jieba分词+城市号+城市天气)**5.11实现**2.用户手动选择,查看当前所选城市天气(Toplevel+Combobox)**已实现**5-141.加入notepad,显示多个城市天气(notebookFrame)**已实现**2.频繁刷新检测(线程计时10秒)**已实现**3.用户选择主题(Menu.add_radiobutton())**已实现**4.一个窗口多个Combobox,怎样处理选择事件**已实现**5-151.右击notebookframe标题出现“关闭”菜单**已砍掉**2.用户添加了城市后,label出现在了最后的Frame中**未实现**'''imgs=['./img/loading.png']classApp:def__init__(self):self.w=Tk()self.w.title('天气预报小工具-v1.0')width=600height=282left=(self.w.winfo_screenwidth()-width)/2top=(self.w.winfo_screenheight()-height)/2self.w.geometry('%dx%d+%d+%d'%(width,height,left,top))self.w.iconbitmap('biticon.ico')self.w.resizable(False,False)self.cerate_widgets()self.first_launch()self.set_widgets()self.place_widgets()self.thread_it(self.show_local_weather)self.w.mainloop()defcerate_widgets(self):self.note=ttk.Notebook()self.f1=Frame()self.tree=ttk.Treeview(self.f1)self.l1_var=StringVar()self.l1=ttk.Label(self.f1,textvariable=self.l1_var)self.m=Menu(self.w)self.w['menu']=self.mself.s1=Menu(self.m,tearoff=False)self.s2=Menu(self.m,tearoff=False)self.s3=Menu(self.m,tearoff=False)defset_widgets(self):self.location=[]style=ttk.Style(self.w)style.theme_use("default")columns=('rq','tq','flfx','zdqw','zgqw')self.tree.config(show='headings',columns=columns)self.tree.column(columns[0],anchor=CENTER,minwidth=95,width=110)self.tree.column(columns[1],anchor=CENTER,minwidth=60,width=70)self.tree.column(columns[2],anchor=CENTER,minwidth=90,width=100)self.tree.column(columns[3],anchor=CENTER,minwidth=90,width=100)self.tree.column(columns[4],anchor=CENTER,minwidth=90,width=100)self.tree.heading('rq',text='日期')self.tree.heading('tq',text='天气')self.tree.heading('flfx',text='风向风力')self.tree.heading('zdqw',text='最低气温')self.tree.heading('zgqw',text='最高气温')self.m.add_cascade(label='开始',menu=self.s1)self.s1.add_command(label='aaa',command='')self.s1.add_separator()self.s1.add_command(label='退出',command=self.quit_window)self.m.add_cascade(label='操作',menu=self.s2)self.s2.add_command(label='刷新',command=lambda:self.thread_it(self.refresh_weather))self.s2.add_command(label='添加城市',command=lambda:self.thread_it(self.select_city),state='disable')s2_sub=Menu(self.s2,tearoff=0)self.s2.add_separator()self.s2.add_cascade(label='更换主题',menu=s2_sub)self.m.add_cascade(label='关于',menu=self.s3)self.s3.add_command(label='关于作者',command=lambda:messagebox.showinfo('关于作者','作者很神秘,什么都没留下'))self.tree.tag_configure('evenColor',background='lightblue')self.w.protocol('WM_DELETE_WINDOW',self.quit_window)themes=['default','clam','alt','classic']self.themevar=StringVar()fori,tinenumerate(themes):s2_sub.add_radiobutton(label=t,variable=self.themevar,command=lambda:self.thread_it(self.change_theme),value=t)self.themevar.set('default')defplace_widgets(self):self.note.place(x=0,y=0,width=600,height=282)self.tree.place(x=0,y=0,width=600,height=150)self.l1.place(x=0,y=150,height=85,width=600)deffirst_launch(self):'''第一次启动,展示加载图片提示信息:return:'''self.start_time=time.time()paned=PanedWindow(self.w)self.img=imgsimg=Image.open(self.img[0])paned.image=ImageTk.PhotoImage(img)self.load_img=Label(self.w,image=paned.image)self.load_lab=Label(self.w,text='Loading...')self.load_img.pack()self.load_lab.pack()defshow_local_weather(self):'''展示定位天气信息:return:'''self.l1_var.set('正在刷新天气......')items=self.tree.get_children()foriteminitems:self.tree.delete(item)try:city,item=Weather_Get().get_local_weather()self.load_img.destroy()self.load_lab.destroy()self.s2.entryconfig('添加城市',state='normal')self.note.add(self.f1,text=city)i=0fordatainitem['recent']:self.tree.insert('',i,values=(data.get('日期'),data.get('天气'),data.get('风力风向'),data.get('最低气温'),data.get('最高气温')))i+=1self.l1_var.set(f'今天:{self.show_date()}当前所在地区:{city}当前气温:{item["now"]}感冒指数:{item["ganmao"]}')exceptTypeError:messagebox.showerror('错误','天气信息加载失败!')self.l1_var.set('天气信息加载失败!')self.s2.entryconfig('添加城市',state='normal')defrefresh_weather(self):"""刷新天气后,10秒内不能点击刷新:return:"""self.s2.entryconfig('刷新',state='disable')self.show_local_weather()self.thread_it(self.wait_time)defwait_time(self):'''线程计时10s,十秒后刷新按钮可点击:return:'''time.sleep(10)self.s2.entryconfig('刷新',state='normal')defshow_date(self):"""展示日期信息,便于天气展示:return:"""date=str(datetime.date.today())year,month,day=date.split('-')week_day_dict={0:'星期一',1:'星期二',2:'星期三',3:'星期四',4:'星期五',5:'星期六',6:'星期日',}now=datetime.datetime.now()date_index=now.weekday()returnf'{year}年{month}月{day}日{week_day_dict[date_index]}'defselect_city(self):'''Toplevel让用户选择城市,后台获取城市号:return:'''self.t=Toplevel()self.t.resizable(0,0)width=300height=140left=(self.t.winfo_screenwidth()-width)/2top=(self.t.winfo_screenheight()-height)/2self.t.geometry('%dx%d+%d+%d'%(width,height,left,top))self.t.title('选择城市')self.tl1=ttk.Label(self.t,text='请选择城市:')self.tl1.pack()provinces=Weather_Get().get_provinces()self.tc1=ttk.Combobox(self.t,justify='center',state='readonly',value=provinces)self.tc2=ttk.Combobox(self.t,justify='center',state='readonly')self.tc1.pack()self.tc1.bind('<<ComboboxSelected>>',self.show_tc2_value)self.tc2.bind('<<ComboboxSelected>>',self.show_tc3_value)self.tc2.pack()self.tc3=ttk.Combobox(self.t,justify='center',state='readonly')self.tc3.pack()self.tb1=ttk.Button(self.t,text='选择',command=lambda:self.thread_it(self.ack_city))self.tb1.pack(pady=10)#----待完善defack_city(self):'''Toplevel中选择了城市,选择使用notebook中建立Frame展示所选城市信息:return:'''cityno=self.get_city_no()weather_item=Weather_Get().get_weather(cityno)location=self.province_name+self.city_name+self.regioniflocationinself.location:messagebox.showwarning('警告','此城市已添加,请勿重复添加!')else:self.location.append(location)self.f2=Frame(takefocus=True)self.note.add(self.f2,text=location)self.tree2=ttk.Treeview(self.f2)columns=('rq','tq','flfx','zdqw','zgqw')self.tree2.config(show='headings',columns=columns)self.tree2.column(columns[0],anchor=CENTER,minwidth=95,width=110)self.tree2.column(columns[1],anchor=CENTER,minwidth=60,width=70)self.tree2.column(columns[2],anchor=CENTER,minwidth=90,width=100)self.tree2.column(columns[3],anchor=CENTER,minwidth=90,width=100)self.tree2.column(columns[4],anchor=CENTER,minwidth=90,width=100)self.tree2.heading('rq',text='日期')self.tree2.heading('tq',text='天气')self.tree2.heading('flfx',text='风向风力')self.tree2.heading('zdqw',text='最低气温')self.tree2.heading('zgqw',text='最高气温')self.tree2.place(x=0,y=0,width=600,height=150)#label_='label'+str(self.click_no)#label_var='label'+str(self.click_no)+'_var'self.fl1_var=StringVar()self.fl1=ttk.Label(self.f2,textvariable=self.fl1_var)self.fl1.place(x=0,y=150,height=85,width=600)items=self.tree2.get_children()foriteminitems:self.tree2.delete(item)try:item=weather_itemcity=locationi=0fordatainitem['recent']:self.tree2.insert('',i,values=(data.get('日期'),data.get('天气'),data.get('风力风向'),data.get('最低气温'),data.get('最高气温')))i+=1self.fl1_var.set(f'今天:{self.show_date()}当前所在地区:{city}当前气温:{item["now"]}感冒指数:{item["ganmao"]}')exceptTypeError:messagebox.showerror('错误','天气信息加载失败!')self.fl1_var.set(f'{city}天气信息加载失败!')self.t.destroy()defchange_tab(self,*args):passdefshow_tc2_value(self,event):'''展示"市"级信息:paramevent::return:'''self.tc2.config(value=[])self.tc3.config(value=[])self.province_name=self.tc1.get()cities=Weather_Get().get_cities(self.province_name)self.tc2.config(value=cities)defshow_tc3_value(self,event):'''展示"区/县"级信息:paramevent::return:'''self.city_name=self.tc2.get()regions=Weather_Get().get_regions(self.province_name,self.city_name)self.tc3.config(value=regions)defget_city_no(self):"""根据省、市、区、县获取城市号:return:城市号"""self.region=self.tc3.get()city_no=Weather_Get().get_city_id_by_add(self.province_name,self.city_name,self.region)returncity_nodefchange_theme(self,):'''更换主题:return:'''theme=self.themevar.get()style=ttk.Style(self.w)style.theme_use(theme)defquit_window(self):ret=messagebox.askyesno('退出','是否要退出?')ifret:self.w.destroy()defthread_it(self,func,*args):'''防止线程冲突:paramfunc::paramargs::return:'''t=Thread(target=func,args=args)t.setDaemon(True)t.start()if__name__=='__main__':a=App()2.Weather_Spider.py
#coding:utf-8importrequestsimportjsonfromlxmlimportetreeimportjiebaclassWeather_Get():def__init__(self):self.base_ip_url='http://ip-api.com/json'self.location_url='https://ip.tool.chinaz.com/'#获取中国国内城市--number接口self.city_number_url='http://static.2ktq.com/sktq/common/city_China.json'#天气查询接口self.base_weather_url='http://wthrcdn.etouch.cn/weather_mini?citykey={}'self.headers={'user-agent':'Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/81.0.4044.138Safari/537.36',}self.item=self.get_city_item()defrequest(self,url,headers):"""请求url,可自定义请求头:paramurl:请求的url:paramheaders:自定义的请求头:return:网页文本数据"""s=requests.session()s.keep_alive=Falsetry:r=s.get(url,headers=headers)r.encoding='utf-8'ifr.status_code==200:r.encoding=r.apparent_encodingreturnr.textelse:returnNoneexceptrequests.exceptions.ConnectionError:returnNonedefget_city(self):"""通过ip定位到当前城市:return:所在省市位置信息"""my_headers={'Connection':'keep-alive','Host':'ip.tool.chinaz.com','sec-ch-ua':'"GoogleChrome";v="89","Chromium";v="89",";NotABrand";v="99"','user-agent':'Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/81.0.4044.138Safari/537.36','Upgrade-Insecure-Requests':'1'}res=etree.HTML(self.request(self.location_url,headers=my_headers))location=res.xpath('//div[@class="WhoIpWrapjspu"]//span[@class="Whwtdhalfw30-0lh34tlml80"]/em/text()')#结巴分词好费时间啊jieba_cut_result=jieba.lcut(''.join(location))try:#去除首位的国家和网络类型deljieba_cut_result[0]deljieba_cut_result[-1]item={}#如果结果为类似石家庄裕华则自动加入市区ifjieba_cut_result[0]!=jieba_cut_result[1]:item['province']=jieba_cut_result[0]+'市'item['city']=jieba_cut_result[1]+"区"returnitemelse:#如果结果为类似北京北京则自动加入市item['province']=jieba_cut_result[0]+'市'item['city']=jieba_cut_result[1]+"市"returnitemexceptIndexError:returnFalsedefget_city_item(self):res=self.request(self.city_number_url,headers=self.headers)item=eval("{'cities':"+res+"}")returnitemdefget_provinces(self):province=[pforpinself.item['cities']]#print(province)returnprovincedefget_cities(self,province):cities_=self.item['cities'][province]cities=[cityforcityincities_.keys()]returncitiesdefget_regions(self,province,city):regions_=self.item['cities'][province][city]regions=[regionforregioninregions_.keys()]#print(province,city,regions)returnregionsdefget_city_id_by_add(self,province,city,region=''):ifregion=='':city_no=self.item['cities'][province][city][city].replace('CN','')else:city_no=self.item['cities'][province][city][region].replace('CN','')returncity_nodefget_cityid(self,province,city):"""通过省、市在字典中查找对应的城市号:paramprovince:省:paramcity:市:return:城市号"""ifprovinceinself.item['cities'].keys():try:#河北省唐山市唐山市(通常的省市)number=self.item['cities'][province].get(city).get(city).replace('CN','')returnnumberexceptAttributeError:number=self.item['cities'][province].get(province).get(city).replace('CN','')returnnumberelse:print('未检索到关于{}{}的信息!'.format(province,city))defget_weather(self,number):weather_data=json.loads(self.request(self.base_weather_url.format(number),self.headers))#pprint.pprint(weather_data)data=weather_data['data']item={}yesterday={}item_list=[]yesterday['日期']=data['yesterday']['date']+'(昨天)'item['now']=data['wendu']+'℃'item['ganmao']=data['ganmao']yesterday['天气']=data['yesterday']['type']yesterday['风力风向']=data['yesterday']['fx']+data['yesterday']['fl'].replace('<![CDATA[','').replace(']]>','')yesterday['最低气温']=data['yesterday']['low'].replace('低温','')yesterday['最高气温']=data['yesterday']['high'].replace('高温','')item_list.append(yesterday)count=0forweateherindata['forecast']:item2={}ifcount==0:date=weateher['date']+'(今天)'elifcount==1:date=weateher['date']+'(明天)'elifcount==2:date=weateher['date']+'(后天)'else:date=weateher['date']+f'({count-1}天后)'item2['日期']=dateitem2['天气']=weateher['type']item2['风力风向']=weateher['fengxiang']+weateher['fengli'].replace('<![CDATA[','').replace(']]>','')item2['最低气温']=weateher['low'].replace('低温','')item2['最高气温']=weateher['high'].replace('高温','')item_list.append(item2)count+=1item['recent']=item_listreturnitemdefget_local_weather(self):item=Weather_Get().get_city()ifitem:p=item['province']c=item['city']number=Weather_Get().get_cityid(p,c)weather=Weather_Get().get_weather(number)returnp+c,weatherelse:returnFalse
感谢各位的阅读,以上就是“python制作天气预报的代码怎么写”的内容了,经过本文的学习后,相信大家对python制作天气预报的代码怎么写这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。