このページで Python でやっているのと同じことを、Ruby でやってみたものです。
元ページは簡単な HTML の読み方についても解説されてあります。
やること
気象庁のサイト(例えばこんな感じ)から、
札幌, 室蘭, 函館, 青森, 秋田, 盛岡, 山形, 仙台, 福島, 新潟, 金沢, 富山, 長野, 宇都宮, 福井, 前橋, 熊谷, 水戸, 岐阜, 名古屋, 甲府, 銚子, 津, 静岡, 横浜, 松江, 鳥取, 京都, 彦根, 広島, 岡山, 神戸, 和歌山, 奈良, 松山, 高松, 高知, 徳島, 下関, 福岡, 佐賀, 大分, 長崎, 熊本, 鹿児島, 宮崎
の都市の、
年月日, 陸の平均気圧(hPa), 海の平均気圧(hPa), 降水量(mm), 平均気温(℃), 平均湿度(%), 平均風速(m/s), 日照時間(h)
を取得し、csv形式でファイルに書き出します。
前提
「Nokogiri」という Gem が必要です。gem install nokogiri
などでインストールして下さい。
Linux Mint 20.3 で実行したので、Windows では文字化けが起きるかも知れません。(追記:よく考えてみたら今回のはほぼ数値データしか扱っていないので、文字化けはたぶんないですね。)
コード
Ruby
require "nokogiri"
require "open-uri"
require "csv"
place_codeA = [14, 21, 23, 31, 32, 33, 35, 34, 36, 54, 56, 55, 48, 41, 57, 42, 43, 40, 52, 51, 49, 45, 53, 50, 46, 68, 69, 61, 60, 67, 66, 63, 65, 64, 73, 72, 74, 71, 81, 82, 85, 83, 84, 86, 88, 87]
place_codeB = [47412, 47423, 47430, 47575, 47582, 47584, 47588, 47590, 47595, 47604, 47605, 47607, 47610, 47615, 47616, 47624, 47626, 47629, 47632, 47636, 47638, 47648, 47651, 47656, 47670, 47741, 47746, 47759, 47761, 47765, 47768, 47770, 47777, 47780, 47887, 47891, 47893, 47895, 47762, 47807, 47813, 47815, 47817, 47819, 47827, 47830]
place_name = ["札幌", "室蘭", "函館", "青森", "秋田", "盛岡", "山形", "仙台", "福島", "新潟", "金沢", "富山", "長野", "宇都宮", "福井", "前橋", "熊谷", "水戸", "岐阜", "名古屋", "甲府", "銚子", "津", "静岡", "横浜", "松江", "鳥取", "京都", "彦根", "広島", "岡山", "神戸", "和歌山", "奈良", "松山", "高松", "高知", "徳島", "下関", "福岡", "佐賀", "大分", "長崎", "熊本", "鹿児島", "宮崎"]
base_url = "http://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php"
place_data = place_name.zip(place_codeA, place_codeB)
place_data.each do |place, pc_a, pc_b|
all_list = [['年月日', '陸の平均気圧(hPa)', '海の平均気圧(hPa)', '降水量(mm)', '平均気温(℃)', '平均湿度(%)', '平均風速(m/s)', '日照時間(h)']]
puts place
(2007..2017).each do |year|
puts year
(1..12).each do |month|
url = base_url + "?prec_no=#{pc_a}&block_no=#{pc_b}&year=#{year}&month=#{month}&day=1&view=p1"
body = Nokogiri::HTML(URI.open(url)) #サイトのHTMLを取得し、Nokogiriに流し込む
sleep(1) #サイト攻撃にならないためのマナー
#Nokogiriから返ってきたオブジェクトを加工する
body.css("tr.mtx").drop(4).each do |row|
data = row.css("td").map(&:text) #map(&:text)でtd要素の「中身」を得ている
row_data = ["#{year}/#{month}/#{data[0]}"]
col_idxs = [1, 2, 3, 6, 9, 11, 16] #取得する列の一覧
row_data += col_idxs.map { |i| data[i].to_f.to_s }
all_list << row_data
end
end
end
#ファイルに書き出し
CSV.open(place + ".csv", "w") do |csv|
all_list.each { |row| csv << row }
end
end
元の Python コードにないのはsleep(1)
です。直接サイトにアクセスするので、マナーとして入れておきました。また、データをわざわざ一旦 Float に変換するのは、必要ない気もしますがそのままにしてあります。(追記。"--".to_f
が0.0
になることに気づいたので、コードを修正しました。)
なお、sleep(1)
を入れてあるせいで、このコードをすべて実行するのにはかなりの時間がかかります。のんびりお待ち下さい。