LoginSignup
9
6

More than 5 years have passed since last update.

Juliaで気象庁のホームページの情報を取得してファイルに保存する

Last updated at Posted at 2019-01-23

この記事について

Juliaに関して知識不足ですが、Qiitaにそもそも記事が少ないので書きました。
アドバイスがありましたらドシドシください。

Pythonを使って気象庁の震源リストデータを取得しようとしていたところ、後輩が先に作ってしまったのでせっかくだからJuliaでクローラーを作成しました。
アクセス先は気象庁の以下のページです。
http://www.data.jma.go.jp/svd/eqev/data/daily_map/

ホームページの構造としてはこのページの下に日毎のHTMLがつながっている感じです。
そのHTMLの名称がyyyymmdd.htmlなので、ループが簡単そうですね。

環境

PC環境

Windows10

ソフトウェア

Julia 1.0.3
※注意※
Julia 1.1.0では上手く動作しないと報告を受けています。ご注意ください。

使用パッケージ

HTTP
Dates

関連記事

JuliaをインストールしてPlotsでグラフを表示する

参考サイト

Dates(英語)
https://docs.julialang.org/en/v1/stdlib/Dates/index.html
HTTP(英語)
https://github.com/JuliaWeb/HTTP.jl

GithubなどはREADMEをちょっと読んだだけです。

実装開始!!!

EarthQuake.jl
# パッケージの宣言
using HTTP
using Dates

# 検索のベースURL
BaseURL = "http://www.data.jma.go.jp/svd/eqev/data/daily_map/"
# 保存先のパス(任意のパス)
PATH = "C:\\user\\user_name\\Desktop\\Julia\\"
# 開始日と終了日を指定
# 形式は yyyyMMdd(例:20170101=2017年1月1日)
# StartDate(開始日)が20170501なのはWebサービス上で最も古いデータがこの日付のため
StartDate = "20170501"
EndDate = "20170505"

ここまでは特に特徴的なものではなく、ほかの言語と同じように設定できると思います。
次に日付を指定していきます。

EarthQuake.jl
# Juliaで取り扱う日付のフォーマットに設定
df = DateFormat("yyyymmdd")
sd = Date(StartDate,df)
ed = Date(EndDate,df)

Datesパッケージを使用して開始日と終了日を日付に変更していきます。
ここで一つ問題がありまして、Date関数を使用するとすべてyyyy-mm-ddの形式に変換されてしまいます。
yyyymmdd形式に戻す方法を知っている方がいましたら教えてください。

次がメインの接続部分です。

EarthQuake.jl
# 差分日数の取得
d = ed - sd
days = Dates.value(d)

# 差分日数の分だけループを回す
for day in 0:days
    try
        # DATE型のデータをyyyymmddの形式に戻す
        SearchDay = sd + Dates.Day(day)
        year      = Dates.year(SearchDay)
        month     = Dates.month(SearchDay)
        day       = Dates.day(SearchDay)   
        # 月と日の0付け(桁合わせのため)
        if month <= 9
            month = string("0",month)
        end
        if day <= 9
            day = string("0",day)
        end
        # 検索用日付を作成(例:20170101)
        SearchDate = year
        SearchDate = string(SearchDate,month)
        SearchDate = string(SearchDate,day)

        # 検索日付が開始日以降であり、終了日以前であること
        # 強制終了条件として前日までの日付であること(基本的に当日のデータは整備されていない)
        if StartDate <= SearchDate && SearchDate <= EndDate && today() > SearchDay
            # 検索用のHTMLファイル名を生成
            SearchHTML = string(SearchDate,".html")
            # URL生成
            URL = string(BaseURL, SearchHTML)
            # URLを使用してリクエストを投げる
            r = HTTP.request("GET", URL)
            # 取得情報を保存
            f = open(string(PATH,string(SearchDate,".html")), "w")
            redirect_stdout(f)
            println(String(r.body))
            close(f)

            # 高速接続をしないために待機1秒を置く
            sleep(1)
        end
    catch e
        nothing
    end
end

Date型の引き算によって日付の差分を取得します。
これによって取得される値はDay型ですので、【days = Dates.value(d)】を使用して数値に直す必要があります。
このDay型をそのまま出力すると下の画像のように表示されます。
image.png

さきほども書きましたが、Date型のフォーマットをyyyymmddに直す方法が見つからなかったので、年月日を分解してくっつけています。
見た目がダサいのでどうにかしたいのですが、知っている方がいらっしゃいましたら教えてください。

HTTP.request("GET", URL)

重要なのはこの部分ですね。
ここでアクセスをしています。
注意事項としては、アクセス先が存在しない場合、ステータスコードが返ってくるわけではなく、エラーとしてプログラムが終了します。
ですので必ずTry文で囲ってください。

取得してきた内容を保存します。

f = open(string(PATH,string(SearchDate,".html")), "w")
redirect_stdout(f)
println(String(r.body))
close(f)

openで開いてredirect_stdoutでファイルに出力をさせます。
後は通常のprintln関数で出力していけば大丈夫です。

これを実行すると最初にPATHに設定した場所にHTMLファイルが作成されていると思います。

次回

次回は今回取得してきたHTMLから要素を取り出してCSVにして保存をしてみたいと思います。
手探り状態ですの時間がかかると思いますが、次回もよろしくお願いします。

全コード

EarthQuake.jl
#---------------------------------------------------------------------------------------------------------------------------------------------------------------------
# このプログラムは気象庁の震源リストにアクセスをして日別のHTMLデータを取得してくるものです
# 開始日と終了日を指定してその間の日付のデータを取得してきますが、気象庁のシステムに対応しているものが2017年5月1日からのものしか存在しません。ご注意ください
# これよりも過去のデータに関しては別プログラムを用意します 
# 
# 使用パッケージ
# 1. HTTTP  Webページアクセスのためのパッケージ
# 2. Dates  日付操作用のパッケージ
#---------------------------------------------------------------------------------------------------------------------------------------------------------------------

using HTTP
using Dates

# 検索のベースURL
BaseURL = "http://www.data.jma.go.jp/svd/eqev/data/daily_map/"
# 検索用日付
SearchDate = ""
# 保存先のパス(任意のパス)
PATH = "C:\\user\\user_name\\Desktop\\Julia\\"
# 開始日と終了日を指定
# 形式は yyyyMMdd(例:20170101=2017年1月1日)
# StartDate(開始日)が20170501なのはWebサービス上で最も古いデータがこの日付のため
StartDate = "20170501"
EndDate = "20170505"

# Juliaで取り扱う日付のフォーマットに設定
df = DateFormat("yyyymmdd")
sd = Date(StartDate,df)
ed = Date(EndDate,df)

# 差分日数の取得
d = ed - sd
days = Dates.value(d)

# 差分日数の分だけループを回す
for day in 0:days
    try
        # 検索する日付を算出する
        SearchDay  = sd + Dates.Day(day)
        # DATE型のデータをyyyymmddの形式に戻す
        # 検索用日付を作成(例:20170101)
        SearchDate = Dates.format(SearchDay,df)

        # 検索日付が開始日以降であり、終了日以前であること
        # 強制終了条件として前日までの日付であること(基本的に当日のデータは整備されていない)
        if StartDate <= SearchDate && SearchDate <= EndDate && today() > SearchDay
            # 検索用のHTMLファイル名を生成
            SearchHTML = string(SearchDate,".html")
            # URL生成
            URL = string(BaseURL, SearchHTML)
            # URLを使用してリクエストを投げる
            r = HTTP.request("GET", URL)
            # 取得情報を保存
            f = open(string(PATH,string(SearchDate,".html")), "w")
            redirect_stdout(f)
            println(String(r.body))
            close(f)

            # 高速接続をしないために待機1秒を置く
            sleep(1)
        end
    catch e
        nothing
    end
end

修正履歴

以下のソースコードを修正しました

        # 検索する日付を算出する
        SearchDay  = sd + Dates.Day(day)
        # DATE型のデータをyyyymmddの形式に戻す
        # 検索用日付を作成(例:20170101)
        SearchDate = Dates.format(SearchDay,df)
        # 月と日の0付け(桁合わせのため)
        if month <= 9
            month = string("0",month)
        end
        if day <= 9
            day = string("0",day)
        end
        # 検索用日付を作成(例:20170101)
        SearchDate = year
        SearchDate = string(SearchDate,month)
        SearchDate = string(SearchDate,day)

↓修正後

        # 検索する日付を算出する
        SearchDay  = sd + Dates.Day(day)
        # DATE型のデータをyyyymmddの形式に戻す
        # 検索用日付を作成(例:20170101)
        SearchDate = Dates.format(SearchDay,df)

また、Dates.DateFormatを関数と表現しておりましたが、正確にはそれは型であり、Date型への変換を行っているのはDate関数でした。
こちらも併せて修正いたしました。

9
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6