'Trying to High and Low data from weather.gov in beautiful soup

#importing needed libraries
import requests
from bs4 import BeautifulSoup
import pandas as pd

#asking for users lat/long
lat = input("Enter the Latitude: ")
lon = input("Enter the Longitude: ")
#inputting user lat/long
url = ("https://forecast.weather.gov/MapClick.php? 
lat={0}&lon={1}#.YkoEDufMKUk")

r = requests.get(url)
# getting all of the data from the website
soup = BeautifulSoup(r.content,"html.parser")
week = soup.find(id="seven-day-forecast-body")
items = soup.find_all("div",class_ = "tombstone-container")
period_name = [item.find(class_="period-name").get_text() for item in 
items]
short_desc = [item.find(class_="short-desc").get_text() for item in 
items]
temp_low = [item.find(class_="temp temp-low").get_text() for item in 
items]
temp_high = [item.find(class_="temp temp-high").get_text() for item in 
items]
    

The temp_low and temp_high is my current attempts at getting them separated but I just get this error message. I need the data from the high and low to go into different lists in the csv file.
runfile('C:/Users/19mcgowanj/Desktop/untitled2.py', wdir='C:/Users/19mcgowanj/Desktop') Traceback (most recent call last):

File "C:\Users\19mcgowanj\Desktop\untitled2.py", line 21, in temp_low = [item.find(class_="temp-low").get_text() for item in items]

File "C:\Users\19mcgowanj\Desktop\untitled2.py", line 21, in temp_low = [item.find(class_="temp-low").get_text() for item in items]

AttributeError: 'NoneType' object has no attribute 'get_text'

https://forecast.weather.gov/MapClick.php?lat=39.32920000000007&lon=-82.09978499999994#.YkoEDufMKUk

This is the website

This is the previous assignment that I started from.

#importing needed libraries
import requests
from bs4 import BeautifulSoup
import pandas as pd

#asking for users lat/long
lat = input("Enter the Latitude: ")
lon = input("Enter the Longitude: ")
#inputting user lat/long
url = ("https://forecast.weather.gov/MapClick.php?lat={0}&lon= 
{1}#.YlBoEOfMKUm".format(lat,lon))

r = requests.get(url)
# getting all of the data from the website
soup = BeautifulSoup(r.content,"html.parser")
week = soup.find(id="seven-day-forecast-body")
items = soup.find_all("div",class_ = "tombstone-container")
period_name = [item.find(class_="period-name").get_text() for item in 
items]
short_desc = [item.find(class_="short-desc").get_text() for item in 
items]
temp = [item.find(class_="temp").get_text() for item in items]

#formatting data
df = pd.DataFrame({"Period" : period_name,"Short Description" : 
short_desc,"Temperature" : temp,})
#saving to csv
df.to_csv("2801_WeatherData.csv")

#rerunning the top portion but for athens and saving it to 
#2801_WeatherData_athens instead.
url = ("https://forecast.weather.gov/MapClick.php? 
lat=39.32920000000007&lon=-82.09978499999994#.YkoEDufMKUk")

r = requests.get(url)

soup = BeautifulSoup(r.content,"html.parser")
week = soup.find(id="seven-day-forecast-body")
items = soup.find_all("div",class_ = "tombstone-container")
period_name = [item.find(class_="period-name").get_text() for item in 
items]
short_desc = [item.find(class_="short-desc").get_text() for item in 
items]
temp = [item.find(class_="temp").get_text() for item in items]


df = pd.DataFrame({"Period" : period_name,"Short Description" : 
short_desc,"Temperature" : temp,})

df.to_csv("2801_WeatherData_athens.csv")


Solution 1:[1]

You can use this example how to parse data from the website:

import requests
from bs4 import BeautifulSoup

url = "https://forecast.weather.gov/MapClick.php?lat=39.32920000000007&lon=-82.09978499999994"

soup = BeautifulSoup(requests.get(url).content, "html.parser")
for f in soup.select("li.forecast-tombstone"):
    print(f.select_one(".period-name").get_text(strip=True, separator=" "))
    print(f.select_one(".short-desc").get_text(strip=True, separator=" "))
    print(f.select_one(".temp").text)
    print("-" * 80)

Prints:

This Afternoon
Showers
High: 45 °F
--------------------------------------------------------------------------------
Tonight
Scattered Showers then Partly Cloudy
Low: 30 °F
--------------------------------------------------------------------------------
Sunday
Sunny
High: 59 °F
--------------------------------------------------------------------------------
Sunday Night
Partly Cloudy
Low: 42 °F
--------------------------------------------------------------------------------
Monday
Chance Showers
High: 68 °F
--------------------------------------------------------------------------------
Monday Night
Showers
Low: 51 °F
--------------------------------------------------------------------------------
Tuesday
Chance Showers then Partly Sunny
High: 70 °F
--------------------------------------------------------------------------------
Tuesday Night
Mostly Cloudy then Chance Showers
Low: 56 °F
--------------------------------------------------------------------------------
Wednesday
Chance Showers
High: 75 °F
--------------------------------------------------------------------------------

EDIT: To create a DataFrame and save it to CSV:

import requests
import pandas as pd
from bs4 import BeautifulSoup

url = "https://forecast.weather.gov/MapClick.php?lat=39.32920000000007&lon=-82.09978499999994"

soup = BeautifulSoup(requests.get(url).content, "html.parser")

all_data = []
for f in soup.select("li.forecast-tombstone"):
    all_data.append(
        (
            f.select_one(".period-name").get_text(strip=True, separator=" "),
            f.select_one(".short-desc").get_text(strip=True, separator=" "),
            f.select_one(".temp").text,
        )
    )

df = pd.DataFrame(all_data, columns=["name", "desc", "temp"])
print(df)
df.to_csv("data.csv", index=False)

Prints:

             name                                  desc         temp
0  This Afternoon                        Showers Likely  High: 45 °F
1         Tonight  Scattered Showers then Partly Cloudy   Low: 30 °F
2          Sunday                                 Sunny  High: 59 °F
3    Sunday Night                         Partly Cloudy   Low: 42 °F
4          Monday                        Chance Showers  High: 68 °F
5    Monday Night                               Showers   Low: 51 °F
6         Tuesday      Chance Showers then Partly Sunny  High: 70 °F
7   Tuesday Night     Mostly Cloudy then Chance Showers   Low: 56 °F
8       Wednesday                        Chance Showers  High: 75 °F

and saves data.csv (screenshot from LibreOffice):

enter image description here


EDIT: To have 2 columns High/Low in DataFrame:

df[["temp_type", "temp"]] = df["temp"].str.split(" ", expand=True, n=1)
df["temp_type"] = df["temp_type"].str.strip(":")
df = (
    df.pivot(index=["name", "desc"], columns="temp_type", values="temp")
    .fillna("")
    .reset_index()
)
df.columns.name = ""
print(df)

Prints:

             name                                  desc   High    Low
0          Monday                        Chance Showers  68 °F       
1    Monday Night                               Showers         51 °F
2          Sunday                                 Sunny  59 °F       
3    Sunday Night                         Partly Cloudy         42 °F
4  This Afternoon                        Showers Likely  45 °F       
5         Tonight  Scattered Showers then Partly Cloudy         30 °F
6         Tuesday      Chance Showers then Partly Sunny  70 °F       
7   Tuesday Night     Mostly Cloudy then Chance Showers         56 °F
8       Wednesday                        Chance Showers  75 °F       

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1