背景
某天下班淋雨成了落汤鸡,发了个朋友圈感慨一下啊,然后......
夜深人静之时,突然收到了来自学妹的Py文件,运行之后发现事情并不简单(如下图):
这是暗示我...下次出门给她带把伞?不管那么多,作为一个程序猿,遇到程序先拆解一下。
工具
爬虫:requests
解析:re
UI:tkinter
代码解读
想要做一个获取天气预报的小程序,第一步要做的就是能够进行天气预报的爬取,这里通过城市名称匹配百度天气的URL进行爬取,并通过正则的方式进行解析,最终以字典的形式返回结果。
classWeather(object): def__init__(self): passdefcrawl(self, key): url='http://weathernew.pae.baidu.com/weathernew/pc?query='+key+'天气&srcid=4982&city_name='+key+'&province_name='+key# 设置请求头headers= { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36', 'Referer': 'https://googleads.g.doubleclick.net/' } # 页面HTMLres=requests.get(url, headers=headers).text# 时间time=re.search(r'\{\"update_time\":\"(.+?)\"', res).group(1) # 天气weather=re.search(r'\"weather\"\:\"(.+?)\"', res).group(1) weather=weather.encode('utf-8').decode("unicode-escape") # 气温weather_l=re.search(r'temperature_night\"\:\"(.+?)\"', res).group(1) weather_h=re.search(r'temperature_day\"\:\"(.+?)\"', res).group(1) # 风力wind_now=re.search(r'\"wind_power_day\"\:\"(.+?)\"', res).group(1) wind_now=wind_now.encode('utf-8').decode("unicode-escape") wind_name=re.search(r'\"wind_direction_day\"\:\"(.+?)\"', res).group(1) wind_name=wind_name.encode('utf-8').decode("unicode-escape") wind=wind_name+wind_now# 贴示desc=re.search(r'\"desc\"\:\"(.+?)\"', res).group(1) desc=desc.encode('utf-8').decode("unicode-escape") # 结果生dic= { '城市': key, '更新时间': time, '天气': weather, '温度': weather_l+'-'+weather_h+'摄氏度', '风力': wind, '贴示': desc, } returndic
写好了爬取天气预报的代码之后,下面就可以写一个UI来和输入/爬取的内容进行交互的,写UI的方式大同小异,代码如下:
classWeather_UI(object): def__init__(self): self.window=Tk() self.weather=Weather() self.window.title(u'天气预报') # 设置窗口大小和位置self.window.geometry('310x370') # 创建一个文本框self.result_text0=Label(self.window, text=u'学长所在城市:\n要写中文呦') self.result_text0.place(x=10, y=5, height=130) self.result_text0.bind('提示') self.result_text1=Text(self.window, background='#ccc') self.result_text1.place(x=140, y=10, width=155, height=155) self.result_text1.bind("<Key-Return>", self.submit) # 创建一个按钮# 为按钮添加事件self.submit_btn=Button(self.window, text=u'获取天气', command=self.submit) self.submit_btn.place(x=170, y=165, width=70, height=25) self.submit_btn2=Button(self.window, text=u'清空', command=self.clean) self.submit_btn2.place(x=250, y=165, width=35, height=25) # 标题self.title_label=Label(self.window, text=u'今日天气:') self.title_label.place(x=10, y=165) # 结果self.result_text=Text(self.window, background='#ccc') self.result_text.place(x=10, y=190, width=285, height=165) defsubmit(self): # 从输入框获取用户输入的值content=self.result_text1.get(0.0, END).strip().replace("\n", " ") # 把城市信息传到爬虫函数中result=self.weather.crawl(content) # 将结果显示在窗口中的文本框中fork, vinresult.items(): self.result_text.insert(END, k+':'+v) self.result_text.insert(END, '\n') self.result_text.insert(END, '\n') # 清空文本域中的内容defclean(self): self.result_text1.delete(0.0, END) self.result_text.delete(0.0, END) defrun(self): self.window.mainloop()
运行结果如下:
完整代码
importjsonimportrequestsimportreimporttkinterasTkfromtkinterimportTk, Button, Entry, Label, Text, ENDclassWeather(object): def__init__(self): passdefcrawl(self, key): url='http://weathernew.pae.baidu.com/weathernew/pc?query='+key+'天气&srcid=4982&city_name='+key+'&province_name='+key# 设置请求头headers= { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36', 'Referer': 'https://googleads.g.doubleclick.net/' } # 页面HTMLres=requests.get(url, headers=headers).text# 时间time=re.search(r'\{\"update_time\":\"(.+?)\"', res).group(1) # 天气weather=re.search(r'\"weather\"\:\"(.+?)\"', res).group(1) weather=weather.encode('utf-8').decode("unicode-escape") # 气温weather_l=re.search(r'temperature_night\"\:\"(.+?)\"', res).group(1) weather_h=re.search(r'temperature_day\"\:\"(.+?)\"', res).group(1) # 风力wind_now=re.search(r'\"wind_power_day\"\:\"(.+?)\"', res).group(1) wind_now=wind_now.encode('utf-8').decode("unicode-escape") wind_name=re.search(r'\"wind_direction_day\"\:\"(.+?)\"', res).group(1) wind_name=wind_name.encode('utf-8').decode("unicode-escape") wind=wind_name+wind_now# 贴示desc=re.search(r'\"desc\"\:\"(.+?)\"', res).group(1) desc=desc.encode('utf-8').decode("unicode-escape") # 结果生dic= { '城市': key, '更新时间': time, '天气': weather, '温度': weather_l+'-'+weather_h+'摄氏度', '风力': wind, '贴示': desc, } returndicclassWeather_UI(object): def__init__(self): self.window=Tk() self.weather=Weather() self.window.title(u'天气预报') # 设置窗口大小和位置self.window.geometry('310x370') # 创建一个文本框self.result_text0=Label(self.window, text=u'学长所在城市:\n要写中文呦') self.result_text0.place(x=10, y=5, height=130) self.result_text0.bind('提示') self.result_text1=Text(self.window, background='#ccc') self.result_text1.place(x=140, y=10, width=155, height=155) self.result_text1.bind("<Key-Return>", self.submit) # 创建一个按钮# 为按钮添加事件self.submit_btn=Button(self.window, text=u'获取天气', command=self.submit) self.submit_btn.place(x=170, y=165, width=70, height=25) self.submit_btn2=Button(self.window, text=u'清空', command=self.clean) self.submit_btn2.place(x=250, y=165, width=35, height=25) # 标题self.title_label=Label(self.window, text=u'今日天气:') self.title_label.place(x=10, y=165) # 结果self.result_text=Text(self.window, background='#ccc') self.result_text.place(x=10, y=190, width=285, height=165) defsubmit(self): # 从输入框获取用户输入的值content=self.result_text1.get(0.0, END).strip().replace("\n", " ") # 把城市信息传到爬虫函数中result=self.weather.crawl(content) # 将结果显示在窗口中的文本框中fork, vinresult.items(): self.result_text.insert(END, k+':'+v) self.result_text.insert(END, '\n') self.result_text.insert(END, '\n') # 清空文本域中的内容defclean(self): self.result_text1.delete(0.0, END) self.result_text.delete(0.0, END) defrun(self): self.window.mainloop() A=Weather_UI() A.run()