Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

この記事について

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関数でした。
こちらも併せて修正いたしました。

yokotate
専門学校からなんとなくIT企業に入社した万年素人SE(自称)。Pythonは業務で使ってないのに業務で使ってる言語よりも使っている時間が長い気がするのが最近の悩み。 最近はAI系の技術に興味を持ちつつも日々自分の基礎学力無さに嘆いている。 書く内容はほぼ初心者向け。投稿する記事の内容は個人の意見であり、所属する企業の見解を代表するものではありません。
https://github.com/yokotate
japan-systems
「2019年に50周年を迎えたIT企業です。最先端の技術により全国の企業、官公庁、自治体に多くの実績があります。」
https://www.japan-systems.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした