用Python制作简易天气预报2.0(全国天气网:北京)

from tkinter import *
from tkinter import ttk
from bs4 import BeautifulSoup
import requests
import re
from matplotlib import pyplot as plt
import numpy as np
from PIL import Image,ImageTk
import os

def main():
    def request(city_class = "change-title",local_time_class = "local-time",temperature_class = "temperature",
                weather_class = "weather-icon-wrap",row_first_class = "row-first",weather_card_class = "weather-columns" ):
        global new_date
        global w_t#声明全局变量
       
        def handle(ci,lt,t,w,rf,wi):
            wc = text1.get(1.0,END)#获取15日数据
            ct = lt + t + w + rf + wi + wc#爬取数据汇总
            ct.replace("\n","")
            var_ci.set(ci)
            var_lt.set(lt)#写入当前时间
            var_tr.set(t)#写入当前时间气温
            var_rf.set(rf)#写入当前时间空气
            var_wi.set(wi)#写入当前时间风向
            var_t.set("°")#写入气温°
            var_w.set(w)#写入当前时间天气
            ##当前天气数据处理
           
            with open("content.txt","w+") as f:
                f.write(ct)
                #写入爬取汇总数据
            Button1.configure(text = "刷新")
            #输入爬取15日数据

        ##数据记录模块

        Button1.configure(text = "刷新中")
        root.update()
               
        headers = {"User-Agent":"Mozilla/5.0(Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/86.0.4240.198 Safari/537.36 QIHU 360EE/13.0.2290.0"} #请求头
        
        Url = Entry1.get()#请求URL
        try:
            hp = requests.get(Url,headers = headers,timeout = None)
            if hp.status_code > 400:
                print("Request Error",hp.status_code)
        except:
            pass
        #响应错误检测

        root.title("天气预报爬取" + "  状态:"+str(hp.reason)+"  网页编码:"+str(hp.apparent_encoding))

        soup = BeautifulSoup(hp.text,"lxml",from_encoding = "utf-8")#创建BeautifulSoup对象

        city = soup.find("strong",class_ = city_class)
        city = city.text.strip() + "\n"
        #爬取查询城市
        local_time = soup.find("div",class_ = local_time_class)
        local_time = local_time.text.strip() + "\n"
        #爬取当前时间
        temperature = soup.find("div",class_ = temperature_class)
        temperature = temperature.text.strip() + "\n"
        #爬取当前时间气温
        weather = soup.find("div",attrs = {"class":weather_class})
        weather = weather.text.strip() + "\n"
        #爬取当前时间天气
        row_first = soup.find("span",class_ = row_first_class)
        row_first = row_first.text.strip() + "\n"
        #爬取当前时间空气
        wind = soup.find_all("span")[10].text
        #爬取当前时间风向
        
        try:
            text1.delete(1.0,END)#尝试清除刷新前15日天气预报内容
        except Exception:
            pass
        weather_card = soup.find_all("ul",class_ = weather_card_class)
        card = [card.text for card in weather_card]#获取15日天气预报列表数据
        for n in range(len(card)):
            text1.insert(END,"".join("".join(card[n]).split())+"\n")#写入15日天气内容
            
        #爬取15日天气预报

        weather_date = soup.find_all("div",class_ = "weather-date")#爬取15天天气日期
        date = [date.text for date in weather_date]
        new_date = []
        new_temperature = []
        w_t = []
        
        for i in range(len(date)):
            new_date.append(re.sub(r"\D","",date[i]))#删除非数字内容 
        #提取15日日期
       
        for i in range(15):
            w_t.append((soup.find_all("div")[45+i*6].text).replace("℃",""))
        w_t = re.split(",|/",str(w_t).replace("[","").replace("]","").replace("'",""))#截取15日天气最值

        #获取15日最低/高温
    
        handle(city,local_time,temperature,weather,row_first,wind)#调入数据记录模块
        
        ##主模块

        

    def figure():
        lowest_temperature = np.array(w_t[::2])#最低温度
        highest_temperature = np.array(w_t[1::2])#最高温度
        l_t = list(map(int,lowest_temperature))#将列表元素转换为数字格式
        h_t = list(map(int,highest_temperature))#..
        x = np.arange(1,16)#生成元素
        plt.xticks(x,new_date)#设置x轴坐标点
        
        y_l = np.array(l_t)
        y_h = np.array(h_t)
        #设置列表元素为整型
 
        plt.rcParams['font.sans-serif']=['SimHei']#用黑体显示中文
        plt.rcParams['axes.unicode_minus']=False #正常显示符号  
        plt.plot(x, y_l,color = "blue",alpha = 1,linestyle = "-.",marker = "o",label = "最低温度")#最低温度折线图
        plt.plot(x, y_h,color = "red",alpha = 1,linestyle = "-.",marker = "^",label = "最高温度")#最高温度折线图
        plt.fill_between(x,y_h,y_l,label = "温差范围")#温差范围色块
        for num in range(15):
            plt.text(x[num],l_t[num],l_t[num],fontsize = 12)#设置最低气温各点的数值
            plt.text(x[num],h_t[num],h_t[num],fontsize = 12)#设置最高气温各点的数值
        plt.title("未来15日气温走向")
        plt.xlabel("日期")
        plt.ylabel("温度")
        plt.legend()#让label显示在合适的位置
        plt.grid()
        plt.show()

    ##气温折线图

    root = Tk()
    root.title("天气预报爬取")
    w = root.winfo_screenwidth()#获取屏幕宽度
    h = root.winfo_screenheight()#获取屏幕高度
    width = 400
    height = 450
    pw = (w - width - 100)/2
    ph = (h - height - 100)/2
    root.geometry("%dx%d+%d+%d"%(width,height,pw,ph))#设置主窗口大小

    Entry1 = ttk.Entry(root,font = ("微软雅黑",9))
    Entry1.insert(END,"https://tianqi.so.com/weather/101010100")#(全国天气网:北京)
    Entry1.configure(state = "readonly")
    Entry1.place(x = 40,y = 28,width = 245,height = 21)
    #天气爬取网站

    Button1 = ttk.Button(root,text = "刷新",command = request)
    Button1.place(x = 289,y = 26,width = 52,height = 25)
    #刷新按钮
    global text1
    text1 = Text(root,bg = "black",fg = "white",font = ("微软雅黑",9),relief = "raised")
    text1.place(x = 35,y = 197,width = 290,height = 220)
    #15日数据显示文本
    Scr = Scrollbar()
    Scr.config(command = text1.yview)
    text1.config(yscrollcommand = Scr.set)
    Scr.place(x = 325,y = 197,height = 220)
    #文本滚动条

    var_ci = StringVar()
    Label0 = Label(root,textvariable = var_ci,font = ("微软雅黑",10),relief = "flat")
    Label0.place(x = 40,y = 65)
    #城市
    var_lt = StringVar()
    Label1 = Label(root,textvariable = var_lt,font = ("微软雅黑",10),relief = "flat")
    Label1.place(x = 80,y = 65)
    #当前时间
    var_tr = StringVar()
    Label2 = Label(root,textvariable = var_tr,font = ("微软雅黑",23),relief = "flat")
    Label2.place(x = 37,y = 97)
    #°
    var_t = StringVar()
    Label3 = Label(root,textvariable = var_t,font = ("微软雅黑",23),relief = "flat")
    Label3.place(x = 79,y = 100)
    #当前气温
    var_w = StringVar()
    Label4 = Label(root,textvariable = var_w,font = ("微软雅黑",23),relief = "flat")
    Label4.place(x = 98,y = 96)
    #当前天气
    var_rf = StringVar()
    Label5 = Label(root,textvariable = var_rf,font = ("微软雅黑",11),relief = "flat")
    Label5.place(x = 40,y = 150)
    #当前空气
    var_wi = StringVar()
    Label6 = Label(root,textvariable = var_wi,font = ("微软雅黑",11),relief = "flat")
    Label6.place(x = 121,y = 150)
    #当前风向
    
    ##当天天气概况设置

    main_menu = Menu(root)
    main_menu.add_command(label = "figure",command = figure)
    root.config(menu = main_menu)

    request()
    root.mainloop()
    #gui界面设置

if __name__ == "__main__":
    main()

(在原有的基础上加了点料,还是比较简陋,欢迎大佬指教)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值