本文在python中用requests和Beautifulsoup爬取天气、温度、风向、空气质量、十五天天气预报等数据,并基于tkinter实现图形用户界面
from tkinter import *
from tkinter import ttk
from bs4 import BeautifulSoup
import requests
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" ):
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日天气预报
handle(city,local_time,temperature,weather,row_first,wind)#调入数据记录模块
##主模块
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)
#当前风向
##当天天气概况设置
request()
root.mainloop()
#gui界面设置
if __name__ == "__main__":
main()