気象情報のスクレイピング【入門編】


本記事は マイナビ Advent Calendar 2019 の11日目の記事になります。

私は気象好きの社会人1年目です。
今年4月に新卒としてマイナビに入社し、ビッグデータやらAIやらを扱う部署に配属になりました。
記事も初投稿なので温かい目で拝見して頂けれると幸甚です。

今回の取り組み

題名の通り、"気象情報をスクレイピングより取得する"ものになります。
今回は入門編なので概論的な話は抜きにして、
どのようなソースでスクレイピングができるのか、実際にやってみましょう。

スクレイピング

注意

概論的な話は抜きにして...と言っていたものの早速無視をしてしまいました。

下記はスクレイピングを初めてされる方へ注意事項です。
これを注意するだけで皆んなが幸せになるので一読お願いします。

今回のスクレイピングの対象となるWebサイト

スクレイピングを行う箇所

下記の気象庁のページ内にある天気概況をスクレイピングします。

実践

Pythonを用いてスクレイピングを行う際に利用するモジュールはいくつかあるとは思いますが、
ここではBeautifulSouprequestsの2つを使用します。

よし、実践!


from bs4 import BeautifulSoup
import requests

url = "http://www.jma.go.jp/jp/yoho/319.html"
req = requests.get(url).text
soup = BeautifulSoup(req, "html.parser")

forecast_text = soup.find('pre', class_="textframe").text

print(forecast_text)

以下は出力結果!

天気概況
令和元年12月10日16時43分 気象庁予報部発表

 伊豆諸島南部、小笠原諸島では、高波に注意してください。伊豆諸島では
、竜巻などの激しい突風や急な強い雨、落雷に注意してください。

 高気圧が日本のはるか東と西日本にあって、それぞれ東へ移動しています。引き続き、房総半島沖から伊豆諸島にかけては気圧の谷となっています。

 東京地方は、曇りとなっています。

 10日は、気圧の谷や湿った空気の影響により、曇りとなるでしょう。伊豆諸島では、雨や雷雨となる所がある見込みです。

 11日は、気圧の谷や湿った空気の影響により曇りとなりますが、朝から昼過ぎは高気圧に覆われて晴れるでしょう。伊豆諸島では、雨や雷雨となる所がある見込みです。

【関東甲信地方】
 関東甲信地方は、曇りや晴れとなっています。

 10日は、気圧の谷や湿った空気の影響により、関東地方は曇りで沿岸部では雨、伊豆諸島では雷雨の所があるでしょう。甲信地方や群馬県では高気圧に覆われて晴れる所もある見込みです。

 11日は、気圧の谷や湿った空気の影響により、朝晩を中心に曇りで沿岸部では雨、伊豆諸島では雷雨の所があるでしょう。日中は高気圧に覆われて晴れる所もある見込みです。

 関東地方と伊豆諸島の海上では、10日から11日にかけて、うねりを伴って波が高いでしょう。船舶は高波に注意してください。

おお!
ちゃんとスクレイピングが出来たようです。
数行のソースでサイト内の文章を取得することができました!
ライブラリの読み込みと出力部分を抜くと4行程になりますね!
簡単!

ソースについて

ソースについて全く説明がないのも如何なものかと思うので、
ざっくりソースの動作を説明しようと思います。

スクレイピング対象になるWebサイトのURLを指定


url = "http://www.jma.go.jp/jp/yoho/319.html"

Webページから内容を取得

requests.get()でスクレイピング対象のWebページから内容を取得します。


req = requests.get(url).text

htmlパース用のオブジェクト作成

ここではhtmlで書式化されているテキストファイルを
BeautifulSoupにより解釈しています。
これにより後のWebページ内の要素の探索が容易になります。


soup = BeautifulSoup(req, "html.parser")

指定したタグ内のテキストを取得

find()は条件に合致する1番最初に見つかった要素を返しています。
ここで言うと抽出する箇所は、
<pre class="textframe">天気概況~~</pre>のように
タグがpre要素、classtextframeにあたるので、それに対応して
.find('pre', class_="textframe")のような記述になっています。

そして、.textで指定した要素内のテキストを抽出する形になります。
今回は探索した際に
Webページ内で該当する要素が一つだけだったためfind()を使用していますが、
該当する要素が複数ある場合はfind_all()を使用する必要があります。
BeautifulSoup | find()/find_all()


forecast_text = soup.find('pre', class_="textframe").text

終わりに

今回は気象情報のスクレイピングを紹介させて頂きました。
上記の様に数行のソースで簡単にスクレイピングが行えるので皆さんも是非やってみて下さい!

おまけ

スクレイピングだけだともの寂しかったので
おまけで先程の出力結果に対して正規表現で、
欲しい文章を抽出しようと思います。

抽出するのは下記の赤線箇所

以下はソースの内容


import re

start_text = "東京地方"
end_text = "。"

compile_text = re.compile(r'{start}.*?{end}'.format(start=start_text, end=end_text), flags=re.DOTALL)
extraction_sentece = compile_text.search(forecast_text)
result = extraction_sentece.group()

print(result)

以下は出力結果

'東京地方は、曇りとなっています。'

😊