[Yahoo! Weather Replacement Version] How to get weather information with LINE Notify + Python

Introduction

In the previous post How to get the weather forecast with LINE Notify + Python, I introduced how to notify the weather forecast scraped from the weather forecast site on LINE. ..

However, since the source livedoor weather forecast has ended its service on July 31, 2020, the Web service from which weather information is collected has been changed. I decided to carry out (replacement).

Selection and reason for migration

This time, I chose Yahoo! Weather as the migration destination. スクリーンショット 2020-07-12 14.07.19.png

The reason I chose it is as follows.

--The tag structure is simple and not so different from the livedoor weather forecast rss, so the amount of correction can be minimized.

--Major as a weather forecast service. It is unlikely that the service will end in the future.

You can see the RSS data of the weather information of each place by looking at the Provided RSS page of the Yahoo! Weather Forecast.

Similar to the previous time, the following is a reference to the RSS data of Mito City, Ibaraki Prefecture. スクリーンショット 2020-07-12 12.12.40.png The title tag contains the date, city, weather, maximum / minimum temperature, and all the information you want. Is the description tag a summary of weather information? If you get these as a set, it seems that you can cover all the necessary information. It is also GOOD that the RSS of livedoor weather forecast and the tag structure are the same.

Execution environment

--OS: Windows10, Mac OS X, Linux are all available.

Source code

The basic logic is the same as the previous entry (https://qiita.com/S_eki/items/206ddb321768ad4e7544), There is a slight difference in the description of the weather information. Since it is used to judge the icon output, the description is matched to Yahoo !.

For example, in Yahoo! weather, it seems that ●● temporary </ font> </ b> ▲▲ is added like sunny and temporary cloudy, so this is added to the OR condition. ..

(Example) When the word "clear in the morning buttery" or "clear in the morning buttery" or "clear in the morning buttery" appears in the weather information ... SunToCloud.png

An icon with a sunny mark + cloudy mark is displayed.

GetWeather.py


#!/usr/bin/env python

import urllib.request
from bs4 import BeautifulSoup
import requests

icon_path = "Path where the icon is stored (enter with an absolute path)"

#Production token ID
line_notify_token = 'ACCESS TOKEN NAME'
#LINE Notify API URL
line_notify_api = 'https://notify-api.line.me/api/notify'

#RSS and URL to be extracted(The default is Mito City, Ibaraki Prefecture)
rssurl = "https://rss-weather.yahoo.co.jp/rss/days/4010.xml"
URL = "https://weather.yahoo.co.jp/weather/jp/8/4010/8201.html"

tenki = []
detail = []

## Parser :A method to extract and parse weather information from HTML tags of weather information web pages##########################
def Parser(rssurl):
   with urllib.request.urlopen(rssurl) as res:
      xml = res.read()
      soup = BeautifulSoup(xml, "html.parser")
      for item in soup.find_all("item"):
         title = item.find("title").string
         description = item.find("description").string
         if title.find("[ PR ]") == -1:
            tenki.append(title)
            detail.append(description)

## ck_Weather :Method to output the acquired weather information and the corresponding icon################################
def ck_Weather(i, detail):
   if (detail[i].find("Fine")) != -1 and (detail[i].find("Cloudy")) == -1 and (detail[i].find("rain")) == -1 and (detail[i].find("snow")) == -1:
       files = {'imageFile': open(icon_path + "Sun.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                            
   elif (detail[i].find("Sunny and cloudy")) != -1 or (detail[i].find("Clear in the morning butterflies")) != -1 or (detail[i].find("Sunny sometimes clouds")) != -1:
       files = {'imageFile': open(icon_path + "SunToCloud.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                        
   elif (detail[i].find("Sunny temporary rain")) != -1 or (detail[i].find("Sunny then rain")) != -1 or (detail[i].find("Sunny and sometimes rain")) != -1:
       files = {'imageFile': open(icon_path + "SunToRain.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                    
   elif (detail[i].find("Clear with brief snow")) != -1 or (detail[i].find("Clear after snow")) != -1 or (detail[i].find("Sunny and sometimes snow")) != -1:
       files = {'imageFile': open(icon_path + "SunToSnow.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                
   elif (detail[i].find("Cloudy")) != -1 and (detail[i].find("Fine")) == -1 and (detail[i].find("rain")) == -1 and (detail[i].find("snow")) == -1:
       files = {'imageFile': open(icon_path + "Cloud.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                            
   elif (detail[i].find("Cloudy temporary clear")) != -1 or (detail[i].find("Cloudy then sunny")) != -1 or (detail[i].find("Cloudy and sometimes sunny")) != -1:
       files = {'imageFile': open(icon_path + "CloudToSun.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                                        
   elif (detail[i].find("Cloudy temporary rain")) != -1 or (detail[i].find("Cloudy then rain")) != -1 or (detail[i].find("Cloudy and sometimes rain")) != -1:
       files = {'imageFile': open(icon_path + "CloudToRain.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                                                    
   elif (detail[i].find("Cloudy with brief snow")) != -1 or (detail[i].find("Cloudy then snow")) != -1 or (detail[i].find("Cloudy with periodic snow")) != -1:
       files = {'imageFile': open(icon_path + "CloudToSnow.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                                                                
   elif (detail[i].find("rain")) != -1 and (detail[i].find("Fine")) == -1 and (detail[i].find("Cloudy")) == -1 and (detail[i].find("snow")) == -1:
       files = {'imageFile': open(icon_path + "Rain.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                                                                            
   elif (detail[i].find("Temporary rain")) != -1 or (detail[i].find("After the rain")) != -1 or (detail[i].find("Rainy but sometimes clear")) != -1:
       files = {'imageFile': open(icon_path + "RainToSun.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                                                                                        
   elif (detail[i].find("Temporary cloudy rain")) != -1 or (detail[i].find("Cloudy after rain")) != -1 or (detail[i].find("Rain sometimes cloudy")) != -1:
       files = {'imageFile': open(icon_path + "RainToCloud.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                                                                                                    
   elif (detail[i].find("Rain with brief snow")) != -1 or (detail[i].find("After rain")) != -1 or (detail[i].find("Rain sometimes snow")) != -1:
       files = {'imageFile': open(icon_path + "RainToSnow.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                                                                                                                
   elif (detail[i].find("snow")) != -1 and (detail[i].find("Fine")) == -1 and (detail[i].find("rain")) == -1 and (detail[i].find("Cloudy")) == -1:
       files = {'imageFile': open(icon_path + "Snow.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                                                                                                                            
   elif (detail[i].find("Temporary snow")) != -1 or (detail[i].find("After snow")) != -1 or (detail[i].find("Snow sometimes clear")) != -1:
       files = {'imageFile': open(icon_path + "SnowToSun.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                                                                                                                                        
   elif (detail[i].find("Temporary cloudy snow")) != -1 or (detail[i].find("Cloudy after snow")) != -1 or (detail[i].find("Snow sometimes cloudy")) != -1:
       files = {'imageFile': open(icon_path + "SnowToCloud.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
                                                                                                                                                                                                    
   elif (detail[i].find("Snow with brief rain")) != -1 or (detail[i].find("After snow")) != -1 or (detail[i].find("Snow with occasion rain")) != -1:
       files = {'imageFile': open(icon_path + "SnowToRain.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)
    
   elif (detail[i].find("storm")) == -1:
       files = {'imageFile': open(icon_path + "Typhon.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)

   elif (detail[i].find("Blizzard")) == -1:
       files = {'imageFile': open(icon_path + "HeavySnow.png ","rb")}
       line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)

   else:
       line_notify = requests.post(line_notify_api, data=payload, headers=headers)


##Main processing###################################################################################

Parser(rssurl) #Extract weather information from HTML tags of weather forecast sites
for i in range(0,2):
    message = tenki[i]
    payload = {'message': "\n" + message}
    headers = {'Authorization': 'Bearer ' + line_notify_token}  

    ck_Weather(i, detail) #Outputs weather information and corresponding weather icons

message = URL
payload = {'message': message}
headers = {'Authorization': 'Bearer ' + line_notify_token}  # Notify URL
line_notify = requests.post(line_notify_api, data=payload, headers=headers)

################################################################################################

Execution result

Set cron on Raspberry Pi and run it automatically. For details, see "Execution result" and "I want to automatically execute the script" and "Icon according to the weather information" in How to get the weather forecast with LINE Notify + Python. See the chapter "I tried to put out."

image1.png image0.png

I was able to successfully port from livedoor weather forecast to Yahoo !. As far as the contents of RSS are concerned, this may be simpler and easier to maintain.

Recommended Posts