0
2

More than 1 year has passed since last update.

気象データを Python でスクレイピングする方法(10分値データ)

Posted at

きっかけ

気象データを取得したいと思い気象庁のサイトにアクセスしたところ、なぜかエラーになりCSVダウンロードができませんでした。

Web上での表示は問題無くできますので、この表データをCSV化できないかを考えました。

すでにやられていたこと

調べてみると、気象データのスクレイピングは様々な方がチャレンジされていました。
なかでも、こちらの記事のソースコードをそのまま実行すれば私の環境でも動きました。
非常に助かりました。

ちなみに、Pythonでは、BeautifulSoupというライブラリを使うのが定石のようです。
このようなコマンドでインストールできます。

pip3 install beautifulsoup4

今回試したこと

前述のブログでは1時間値を取得していましたので、10分値のデータを取得できるようにコードを変更してみました。
prec_noが都道府県の番号、block_noが地点の番号を示しているので、実行する時には好きな番号に書き換えてもらえばと思います。

tenki.py
# -*- coding: utf-8 -*-
import os
import datetime
import csv
import urllib.request
from bs4 import BeautifulSoup

def str2float(weather_data):
    return weather_data

def scraping(url, date):

    # 気象データのページを取得
    html = urllib.request.urlopen(url).read()
    soup = BeautifulSoup(html)
    trs = soup.find("table", { "class" : "data2_s" })

    data_list = []
    data_list_per_hour = []

    # table の中身を取得
    for tr in trs.findAll('tr')[3:]: # 変更
        tds = tr.findAll('td')

        if tds[1].string == None:
            break;

        data_list.append(date)
        data_list.append(tds[0].string)
        data_list.append(str2float(tds[1].string))
        data_list.append(str2float(tds[2].string))
        data_list.append(str2float(tds[3].string))
        data_list.append(str2float(tds[4].string))
        data_list.append(str2float(tds[5].string))
        data_list.append(str2float(tds[6].string))
        data_list.append(str2float(tds[7].string))
        data_list.append(str2float(tds[8].string))
        #data_list.append(str2float(tds[9].string)) # 変更
        #data_list.append(str2float(tds[10].string))
        #data_list.append(str2float(tds[11].string))
        #data_list.append(str2float(tds[12].string))
        #data_list.append(str2float(tds[13].string))

        data_list_per_hour.append(data_list)

        data_list = []

    return data_list_per_hour

def create_csv():
    # CSV 出力先ディレクトリ
    output_dir = r"/Users/username/Downloads"

    # 出力ファイル名
    output_file = "weather.csv"

    # データ取得開始・終了日
    start_date = datetime.date(2023, 1, 1)
    end_date   = datetime.date(2023, 1, 2)

    # CSV の列
    fields = ["年月日", "時間", "降水量", "気温", "相対湿度",
              "平均風速", "平均風向", "最大瞬間風速", "最大瞬間風向", "日照時間"]

    with open(os.path.join(output_dir, output_file), 'w') as f:
        writer = csv.writer(f, lineterminator='\n')
        writer.writerow(fields)

        date = start_date
        while date != end_date + datetime.timedelta(1):

            # 対象url(10分値の場合)
            url = "http://www.data.jma.go.jp/obd/stats/etrn/view/10min_a1.php?" \
                  "prec_no=46&block_no=0388&year=%d&month=%d&day=%d&view="%(date.year, date.month, date.day)
            data_per_day = scraping(url, date)

            for dpd in data_per_day:
                writer.writerow(dpd)

            date += datetime.timedelta(1)

if __name__ == '__main__':
    create_csv()

補足

10分値のデータは1時間とは取得できる表の列名が異なるため、その部分だけ書き換えています。
元の記事には、str2float()という関数があったのですが、テキスト値も一律に0に変換されてしまうので、取り急ぎ無意味な処理にしています。
もっと簡単にしたり、数値と文字列で適切な処理に変更することもできそうです。

0
2
0

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
0
2