(v_05)BeautifulSoup ヤフー 週間天気
週間天気を抽出
BeautifulSoupでヤフーの天気データを抽出しようと思います。
前回は「全国の天気」を抽出しました。
今回は「週間天気(エリア、ピンポイント)」データを抽出したいと思います。
BeautifulSoupのインストールなどは記事(v_01)を参照して下さい。※開発環境はThonny、ブラウザはFirefoxを使用しています。
※記事を記載してる間に日付が変わったりで内容と画像と違う場合があります。
週間天気
以下の図はヤフーの「週間天気」のサイトです。
赤枠の文字列とマップ上の情報を抽出したいと思います。
Yahooの天気・災害から全国の天気の右側に週間天気があります。
ブロック域(東北や四国・・)週間天気から選択した都道府県における地域レベルの週間天気を抽出します。
例えば、ブロック域で四国を選択>徳島県なら北部、南部があります。
ここでは南部(日和佐)を選択した状態で記載します。
南部(日和佐)を選択した場合には、アドレスは「https://weather.yahoo.co.jp/weather/jp/36/7120.html#week」で、以下のように表示されました。※アドレスは適宜変更して下さい。
「①地域名②タイトル③週間天気データ」をBeautifulSoupを使って抽出します。
パース
上記アドレスでHTMLをパースします。ThonnyのShell部で行って行きます。
とりあえずThonnyのShell部で動作を確認して行きます。
>>> import urllib.request
>>> from bs4 import BeautifulSoup
>>> url='https://weather.yahoo.co.jp/weather/jp/36/7120.html' #'#week'は不要
>>> req = urllib.request.Request(url)
>>> html = urllib.request.urlopen(req)
>>> soup = BeautifulSoup(html, "html.parser")
①地域名
Firefoxでタグなどを調査するとclass_=’yjw_sub_md_lined’で指定できそうです。
文字は’h2’タグにあります。
※「Firefoxで調査」については記事(v_01)を参照下さい。
>>> tgt=soup.find(class_='yjw_sub_md_lined')
>>> area=tgt.find('h2')
>>> area
<h2 class="yjM">南部(日和佐)エリアの情報</h2>
テキスト部を抽出します。
>>> area.get_text(" -- ", strip=True)
'南部(日和佐)エリアの情報'
ちなみに.stringでも拾えます。
>>> area.string
'南部(日和佐)エリアの情報'
②タイトル
Firefoxで調査するとid=”week”で指定できました。
>>> tgt=soup.find(id="week")
>>> tgt
<div class="yjw_title_h2 yjw_clr" id="week">
<h2 class="yjMt">週間天気</h2>
<p class="yjSt yjw_note_h2">2024年1月19日 15時00分発表</p>
</div>
テキスト部を抽出します。
>>> tgt.get_text(" -- ", strip=True)
'週間天気 -- 2024年1月19日 15時00分発表'
③週間天気データ
Firefoxで調査するとclass_=’yjw_table’で指定できます。
各’tr’タグは日付、天気、気温、降水確率の行に当たります。
その中に各々、週間分7個の’td’タグ内にデータがあります。
>>> tgt=soup.find(class_='yjw_table')
>>> tr=tgt.find_all('tr')
>>> len(tr)
4 #行数(日付、天気、気温、降水確率)
>>> td=tr[1].find_all('td') #天気 tr[1]
>>> len(td)
7 #7日
天気を抽出してみます。
>>> td[1] #2日目(図では1月22日)
<td width="15%"><img alt="雨のち晴" border="0" src="https://s.yimg.jp/images/weather
/general/next/size90/311_day.png"/><br/>
<small>雨のち晴</small>
</td>
テキスト部を抽出します。
>>> td[1].get_text("", strip=True)
'雨のち晴'
気温を抽出してみます。
>>> td=tr[2].find_all('td') #気温 tr[2]
テキスト部を抽出します。
>>> td[1].get_text("", strip=True) #2日目(図では1月22日)
'169' #つながってしまう
>>> td[1].get_text("|", strip=True) # ‘|’で仕切る
'16|9'
ちなみに
同じ処理で「地域の週間天気」と「ピンポイントの週間天気」のデータを抽出できます。
ピンポイント天気は地域の週間天気のページの下からも選択できます。
選択したピンポイント天気のページには「今日の天気」「明日の天気」「週間天気」があります。
スクリプト
以上をまとめスクリプトを以下のようにしました。
地域「南部(日和佐)」、ピンポイント「美波町」の場合で記載しています。
週間天気を地域、ピンポイントのアドレスを指定できるようにしました。
ywek_01b.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import urllib.request
from bs4 import BeautifulSoup
# Yahoo 週間天気 地域とピンポイント同じスクリプトで読める※アドレスは適宜変更
url_0='https://weather.yahoo.co.jp/weather/jp/36/7120.html' #地域 南部(日和佐)
url_1='https://weather.yahoo.co.jp/weather/jp/36/7120/36387.html' #ピンポイント 美波町
# 週間天気 エリア、ピンポイント 選択
pl=int(input ('INPUT 週間天気 エリア(0)ポイント(1): '))
if pl==1:
url=url_1
else:
url=url_0
print(url,'\n')
#パース
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) # 南部(日和佐)エリアの情報 美波町エリアの情報
#週間天気タイトル
tgt=soup.find(id="week")
cap=tgt.get_text(" -- ", strip=True)
print(cap) # 週間天気 -- 2024年1月20日 15時00分発表
#表の天気データ
tgt=soup.find(class_='yjw_table')
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)
# 表示ようにデータ加工 1行にまとめてから順次表示
s_dat=[]
for i in range(4):
d=''
for j in range(7):
dat=yjw[i][j]
if len(dat) < 8:
dat=dat+ ' '*(8-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 ywek_01b.py
INPUT 週間天気 エリア(0)ポイント(1): 0
https://weather.yahoo.co.jp/weather/jp/36/7120.html
南部(日和佐)エリアの情報
週間天気 -- 2024年1月20日 15時00分発表
日付 1月22日(月) 1月23日(火) 1月24日(水) 1月25日(木) 1月26日(金) 1月27日(土)
天気 晴時々曇 晴時々曇 晴時々曇 晴時々曇 晴時々曇 曇時々晴
気温(℃) 15|5 9|-1 7|-2 9|-1 11|1 13|2
降水確率(%) 20 0 0 0 0 20
まとめ
BeautifulSoupを使ってヤフーの週間天気データを抽出することができました。