Added a seven day forecast
#! /usr/bin/env python3 # Do the imports import tkinter as tk import tkinter.font as tkfont from bs4 import BeautifulSoup as bs import requests import urllib import base64 # Create weather class to get info class Weather: def __init__(self): # Set some vars LANGUAGE = 'en-US, en;q=0.5' USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36" # session vars session = requests.Session() session.headers['User-Agent'] = USER_AGENT session.headers['Accept-Language'] = LANGUAGE session.headers['Content-Language'] = LANGUAGE # Url to google weather, get the data, use soup to parse url = 'https://www.google.com/search?lr=lang_en&ie=UTF-8&q=weather' data = session.get(url) soup = bs(data.text, 'html.parser') # Set an empty dict and grab the data we want self.results = {} self.results['region'] = soup.find('div', attrs={'id': 'wob_loc'}).text self.results['current temperature'] = soup.find('span', attrs={'id': 'wob_tm'}).text self.results['last updated'] = soup.find('div', attrs={'id': 'wob_dts'}).text self.results['current weather'] = soup.find('span', attrs={'id': 'wob_dc'}).text self.results['precipitation'] = soup.find('span', attrs={'id': 'wob_pp'}).text self.results['humidity'] = soup.find('span', attrs={'id': 'wob_hm'}).text self.results['wind speed'] = soup.find('span', attrs={'id': 'wob_ws'}).text self.results['img'] = soup.find('img', attrs={'class': 'wob_tci', 'id': 'wob_tci'})['src'] # Create empty list to hold seven day data # Get the wanted data seven_day = [] days = soup.find('div', attrs={'id': 'wob_dp'}) for day in days.find_all('div', attrs={'class': 'wob_df'}): name = day.find_all('div')[0].attrs['aria-label'] image = day.find('img') temp = day.find_all('span', {'class': 'wob_t'}) high_tmp = temp[0].text low_tmp = temp[2].text seven_day.append({'name': name, 'image': image, 'high': high_tmp, 'low': low_tmp}) # Pop off the first data as we already displaying todays forecast seven_day.pop(0) # Add the list to our dict self.results['seven day'] = seven_day # Create the tkinter window class class Window: def __init__(self, parent): # set the window parent and configure rows and columns self.parent = parent self.parent.columnconfigure(0, weight=1) self.parent.rowconfigure(0, weight=1) # Initiate the weather class self.weather = Weather() # Create the main container container = tk.Frame(self.parent) container.grid(column=0, row=0, sticky='news') container.grid_columnconfigure(0, weight=3) # Container to hold the data in our header header_container = tk.Frame(container) header_container.grid(column=0, row=0, sticky='new') header_container.grid_columnconfigure(1, weight=3) # Container for holding weather info self.info_container = tk.Frame(container) self.info_container.grid(column=0, row=1, sticky='news') for i in range(2): self.info_container.grid_columnconfigure(i, weight=3, uniform='info') # Container for extended forecast self.seven_day_container = tk.Frame(container) self.seven_day_container['relief'] = 'groove' self.seven_day_container['highlightbackground'] = 'gray' self.seven_day_container['highlightcolor'] = 'gray' self.seven_day_container['highlightthickness'] = 1 self.seven_day_container.grid(column=0, row=2, sticky='new') for i in range(len(self.weather.results['seven day'])): self.seven_day_container.grid_columnconfigure(i, weight=3, uniform='days') # Label for the image self.img_label = tk.Label(header_container) self.img_label['image'] = self.get_image(self.weather.results['img']) self.img_label['relief'] = 'groove' self.img_label.grid(column=0, row=0, sticky='new') # Label for header text header = tk.Label(header_container) header['text'] = self.weather.results['region'] header['font'] = tkfont.Font(size=18, weight='bold') header['relief'] = 'groove' header['padx'] = 8 header['fg'] = 'blue' header.grid(column=1, row=0, sticky='news') # Create empty list for labels and set a counter self.labels = [] i = 0 # Loop through the dict and assign to labels for key, value in self.weather.results.items(): if key != 'region' and key != 'img' and key != 'seven day': if key == 'current temperature': text = value.title() + '\u00b0' + ' F' else: text = value.title() self.labels.append([tk.Label(self.info_container, text=key.title(), anchor='w'), tk.Label(self.info_container, text=text, anchor='w')]) self.labels[i][0]['font'] = tkfont.Font(weight='bold', size=10) self.labels[i][0]['relief'] = 'groove' self.labels[i][1]['relief'] = 'groove' self.labels[i][0].grid(column=0, row=i, sticky='new', ipadx=5) self.labels[i][1].grid(column=1, row=i, sticky='new', ipadx=5) i += 1 # Create a header label for the extended forecast label = tk.Label(self.seven_day_container) label['text'] = 'Extended Forecast' label['font'] = tkfont.Font(weight='bold', size=14) label['bg'] = 'lightgray' label.grid(column=0, columnspan=len(self.weather.results['seven day']), row=0, sticky='new') # Create empty list to hold days self.days = [] i = 0 # Loop through the seven day forecast info for data in self.weather.results['seven day']: self.days.append(tk.Label(self.seven_day_container)) self.days[i]['compound'] = 'bottom' self.days[i]['text'] = f'{data["name"]}\n H: {data["high"]}\u00b0 F / L: {data["low"]}\u00b0 F' self.days[i]['font'] = tkfont.Font(weight='bold', size= 8) self.days[i]['image'] = self.get_image(data['image']['src']) self.days[i]['relief'] = 'groove' self.days[i].grid(column=i, row=1, sticky='new') i += 1 # Call self.update to update the information self.update() # function/method for getting and returning the image def get_image(self, src): url = 'https:' + src img = urllib.request.urlopen(url) raw = img.read() img.close() image = tk.PhotoImage(data=raw) image.img = image return image # Create the update function/method def update(self): self.img_label['image'] = self.get_image(self.weather.results['img']) i = 0 for key, value in self.weather.results.items(): if key != 'region' and key != 'img' and key != 'seven day': if key == 'current temperature': text = value.title() + '\u00b0' + ' F' else: text = value.title() self.labels[i-1][1]['text'] = text i += 1 i = 0 for img in self.weather.results['seven day']: self.days[i]['image'] = self.get_image(img['image']['src']) i += 1 self.info_container.after(300000, self.update) def main(): root = tk.Tk() root.title('Tkinter Weather App') root['padx'] = 5 root['pady'] = 4 root.resizable(False, False) Window(root) root.mainloop() main()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts