前回の記事に引き続き、降水ナウキャストの一日分の画像を一気に集めて、ひとつのgifを作成しようと思います。
降水ナウキャスト(気象庁)をスクレイピングして5分毎の降水データ取得する
本記事ではrequestsを使い画像をダウンロード、Pythonの画像処理ライブラリPillowを使いgifの作成までの一連のプログラムを紹介します。
環境と使用するモジュール
・MacBook Air Early2015(MacOS High Sierra)
・Python 3.6.2(pip3)
・requests (pip3 install requests)
・Pillow (pip3 install PIL)
・datetime,glab,os (標準モジュール)
コード
画像データを採る
前回同様、気象庁の降水ナウキャストからデータを取得していきます。サイト訪問後、気象レーダーの画像を(MacのChromeでは)右クリックで「画像のURLをコピー」で画像のURLが取得できます。
取得したURLの以下の部分を組み替えることで、別の時刻のデータを取得できます。
201811091035
左から年、月、日、時、分となっており、5分間隔で更新、ゼロ埋めの処理を施す必要があります。まずは前日の年、月、日データまでをdatetimeを使って取得していきます。
import datetime
time1 = (datetime.datetime.now() - datetime.timedelta(days=1))
#出力結果
2018-11-08 11:42:37.877244
datetime.datetime.now()
で現在時刻の取得、-datetime.timedelta(days=1)
で現在時刻の1日分の減算ができます。
time2 = datetime.datetime(year=time1.year, month=time1.month, day=time1.day)
#出力結果
2018-11-08 00:00:00
前日の00:00にセットします
time3 = [(time2 + datetime.timedelta(minutes=(5*i))).strftime('%Y%m%d%H%M') for i in range(288)]
#出力結果
['201811080000', '201811080005', '201811080010', '201811080015',..... '201811082355']
リスト内包表記を使って288回(5分毎に画像がアップロードされるので、12x24=288)rangeで回しつつ5分ずつ加算していきます。strftime('%Y%m%d%H%M')
で取得した時間を任意のフォーマット(201811~)に変換します。time2でセットした00:00から5分間隔で一日分加算すると201811080000から201811082355までのデータがtime3に格納されていることがわかります。
以上で必要な時間データは取得できたので実際にURLとつなげて画像ファイルをダウンロードしていきます。
for i in time3:
url = 'http://www.jma.go.jp/jp/radnowc/imgs/radar/000/{}-00.png'.format(i)
req = requests.get(url)
if req.status_code == 200:
with open(i + '.png', "wb") as w:
w.write(req.content)
print('Downloaded --> {}'.format(url))
else:
print('Error --> {}'.format(url))
urlには画像URLに取得した時間データをはめたもの。reqでurlにリクエスト。statusが200だったものをpngでダウンロードしてローカルに保存。statusが200以外のものをエラーとして処理します。
gifを作成する
取得した一日分の画像データを使ってgifを作成していきます。まず画像ファイルを操作するためのglabとそれを処理するための画像ライブラリPillowをインポートします。
import grob
from PIL import Image
Pillowを使ったgif作成のコードですが、以下の記事を参考にしました。
Python PillowでPNGからGIFを作る
files = sorted(glob.glob('*.png'))
images = [Image.open(i) for i in files]
images[0].save(file_name, save_all=True, append_images=images[1:], duration=50, loop=0)
Image.save()の引数durationはフレームの表示時間をミリ秒で指定、loopはgifのループ回数で0の場合は無限ループとなります。
完成形
import requests,datetime,glob,os
from PIL import Image
def get_image():
time1 = (datetime.datetime.now() - datetime.timedelta(days=(1)))
time2 = datetime.datetime(year=time1.year, month=time1.month, day=time1.day)
time3 = [(time2 + datetime.timedelta(minutes=(5*i))).strftime('%Y%m%d%H%M') for i in range(288)]
for i in time3:
url = 'http://www.jma.go.jp/jp/radnowc/imgs/radar/000/{}-00.png'.format(i)
req = requests.get(url)
if req.status_code == 200:
with open(i + '.png', "wb") as w:
w.write(req.content)
print('Downloaded --> {}'.format(url))
else:
print('Error --> {}'.format(url))
def make_gif():
file_name = (datetime.datetime.now() - datetime.timedelta(days=1)).strftime('%Y-%m-%d') + '.gif'
files = sorted(glob.glob('*.png'))
images = [Image.open(i) for i in files]
images[0].save(file_name, save_all=True, append_images=images[1:], duration=50, loop=0)
[os.remove(f) for f in files]
if __name__ == '__main__':
get_image()
make_gif()
実行すると以下のようなgifが保存されていると思います。
2018年11月8日の降水情報 pic.twitter.com/Lmh8LGvEgJ
— 秋 (@qxi_) 2018年11月9日
最後に
一回のプログラムで288枚の画像をダウンロードするので、新しくディレクトリーを作ってその中で実行したほうが良さそうです。筆者の調べですが気象庁の降水ナウキャストの画像データは最大で5日前まで遡ることができました。あとプログラミングを初めて1年近く経ちますが重い腰を起こしてようやくgithubを動かしてみたので一応リンク貼っておきます。