稼働中

(v_06)BeautifulSoup ヤフー ピンポイント天気

ピンポイント天気を抽出

BeautifulSoupでヤフーの天気データを抽出しようと思います。
今回はピンポイント天気データを抽出します。
BeautifulSoupのインストールなどは記事(v_01)を参照して下さい。
※開発環境はThonny、ブラウザはFirefoxを使用しています。
※記事を記載してる間に日付が変わったりで内容と画像と違う場合があります。

ピンポイント天気

ピンポイント天気のページには「今日の天気」「明日の天気」「週間天気」があります。
「今日の天気」「明日の天気」ををBeautifulSoupを使って抽出します。
「週間天気」は前回の記事(v_05)で抽出できるので省きます。
Yahoo天気・災害でピンポイントのエリアを徳島県>南部(日和佐)>美波町を選択した場合のアドレス「https://weather.yahoo.co.jp/weather/jp/36/7120/36387.html」を使って抽出しました。
具体的には「①エリア名②タイトル③今日、明日の天気」のテキストです。
※アドレスは適宜変更して下さい。

パース

上記アドレスでHTMLをパースします。ThonnyのShell部で行って行きます。
とりあえずThonnyのShell部で動作を確認して行きます。


>>> import urllib.request
>>> from bs4 import BeautifulSoup
>>> url='https://weather.yahoo.co.jp/weather/jp/36/7120/36387.html'#美波町
>>> req = urllib.request.Request(url)
>>> html = urllib.request.urlopen(req)
>>> soup = BeautifulSoup(html, "html.parser")

①エリア名

Firefoxでタグなどを調査するとclass_=’yjw_sub_md_lined’で指定できそうです。
文字は’h2’タグにあります。


>>> tgt=soup.find(class_='yjw_sub_md_lined')
>>> area=tgt.find('h2')

テキスト部を抽出します。


>>> area.get_text("", strip=True)
'美波町エリアの情報'

ちなみに.stringでも拾えます。


>>> area.string
'美波町エリアの情報'

②タイトル

Firefoxで調査するとclass_=’yjw_title_h2’で指定できました。


>>> tgt=soup.find(class_='yjw_title_h2')

テキスト部を抽出します。


>>> tgt.get_text("", strip=True)
'ピンポイント天気2024年1月20日\u300018時00分発表'

③今日、明日の天気

※このへんから日付が変わってます。
Firefoxで調査すると今日の天気はid=’yjw_pinpoint_today’で指定できます。
明日の天気はid=’yjw_pinpoint_tomorrow’で指定できます。
小見出しは’h3’にあります。


>>> tgt=soup.find(id='yjw_pinpoint_today')
>>> h3=tgt.find('h3')
>>> h3.get_text("", strip=True)
'今日の天気- 1月21日(日)'

天気情報は各’tr’タグはそれぞれ時刻、天気、気温、湿度、降水量、風向の6行に当たります。
その中に各々、項目と3時間毎の天気データが’td’タグ9列内にあります。
天気情報 調査


>>> tgt=soup.find(id='yjw_pinpoint_today')
>>> tr=tgt.find_all('tr')

>>> len(tr)
6                               #行数(時刻、天気、気温、湿度、降水量、風向)

>>> td=tr[1].find_all('td')     # tr[1] 2行目(天気)
>>> len(td)
9                               #9列

天気を抽出してみます。


>>> td[1]                       #0時
<td>
<img alt="雨" border="0" height="40" src="https://s.yimg.jp/images/weather/general
/next/pinpoint/size80/51_night_g.png" width="40"/><br/>
<small><font color="#999999">雨</font></small>
</td>

テキスト部を抽出します。


>>> td[1].get_text("", strip=True)
'雨'

ちなみに18時の天気の場合です。


>>> td[7].get_text("", strip=True)
'晴れ'

気温を抽出してみます。


>>> td=tr[2].find_all('td')         #tr[2]気温

テキスト部を抽出します。


>>> td[4].get_text("", strip=True)  #td[4] 9時
'13'

風向風速は’|’で区切って表示します。


>>> td=tr[5].find_all('td')             #tr[5] 風向風速
>>> td[4].get_text("|", strip=True)     #td[4] 9時 ‘|’で仕切る
'西北西|3'

スクリプト

以上をまとめスクリプトを以下のようにしました。
ピンポイント「美波町」の場合で記載しています。「今日の天気」、「明日の天気」を指定できるようにしました。


ypin_01b.py
# -*- coding: utf-8 -*-
import urllib.request
from bs4 import BeautifulSoup

# Yahoo weather ピンポイント天気
url='https://weather.yahoo.co.jp/weather/jp/36/7120/36387.html'#美波町

# 今日(0)明日(1)の選択
dd=int(input ('INPUT ピンポイント 今日(0)明日(1): '))
if dd==1:               #id='yjw_pinpoint_tomorrow'
    pass
else:
    dd=0                #id='yjw_pinpoint_today'

#parse
req = urllib.request.Request(url)
html = urllib.request.urlopen(req)
soup = BeautifulSoup(html, "html.parser")

#エリア名
tgt=soup.find(class_='yjw_sub_md_lined')
area=tgt.find('h2')
cap=area.get_text("", strip=True)
print(cap)         #美波町エリアの情報
print(url)

#タイトル
tgt=soup.find(class_='yjw_title_h2')
cap=tgt.get_text("", strip=True)
print(cap)         #ピンポイント天気2024年1月21日 16時00分発表

#ピンポイント今日・明日 _today _tomorrow
if dd==1:
    tgt=soup.find(id='yjw_pinpoint_tomorrow')
else:
    tgt=soup.find(id='yjw_pinpoint_today')

h3=tgt.find('h3')
cap=h3.get_text("", strip=True)
print(cap)           #今日の天気- 1月21日(日)

#天気情報
tr=tgt.find_all('tr')
yjw=[]                  #各テキストデータ
row=0
for r in tr:
    td=r.find_all('td')
    dat=[]
    for d in td:
        if row==0 or row==3:
            t_dat=d.get_text("", strip=True)
        else:
            t_dat=d.get_text("|", strip=True)
        dat.append(t_dat)
    row=row+1
    yjw.append(dat)

#結果表示
s_dat=[]
# 6:時刻、天気、気温、湿度、降水量、風向風速 の行
for i in range(6):
    d=''
    # 8: 項目、0、3、6、9・・・・21時の列
    for j in range(8):
        dat=yjw[i][j]
        if j==0:
            dat=dat+ '  '*(7-len(dat))
        else:            
            if len(dat) < 6:
                dat=dat+ ' '*(5-len(dat))
        e=f'{dat:<8}'
        d=d + e + '\t' #1行の文字列にまとめる 
    s_dat.append(d)    #行ごとのリストデータ

#行ごとを表示
for p in s_dat:
    print(p) 

実行結果

以下のような結果になりました。※ThonnyのShellに表示されます。
ピンポイント天気 実行結果


>>> %Run ypin_01b.py
INPUT ピンポイント 今日(0)明日(1): 1
美波町エリアの情報
https://weather.yahoo.co.jp/weather/jp/36/7120/36387.html
ピンポイント天気2024年1月21日 18時00分発表
明日の天気- 1月22日(月)
時刻          	0時      	3時      	6時      	9時      	12時     	15時     	18時     	
天気          	晴れ      	晴れ      	晴れ      	晴れ      	晴れ      	曇り      	曇り      	
気温(℃)    	9       	8       	8       	10      	14      	13      	10      	
湿度(%)    	65      	71      	71      	61      	46      	57      	68      	
降水量(mm) 	0       	0       	0       	0       	0       	0       	0       	
風向|風速(m/s)	北北西|4   	北北西|3   	北北西|3   	北北西|3   	東|3     	南東|2    	北北東|2   	

まとめ

BeautifulSoupを使ってヤフーのピンポイント天気データを抽出することができました。