気象庁にダウンロードサイトがありますが
気象庁にもっとよいダウンロードサイトがあることに、作ってから気が付いたのですが、あえてRでYahoo!から過去の天気を取得します。
Windowsで動かす想定なのでところどころにiconvが入っていますが、Linux等の環境の場合は"cp932"->"utf-8"にする必要があります。
※iconvによって、html_nodesの結果(単純な文字列のリストではない!)が単純な文字列のリストになるみたいなので、iconvが本質的に意味のある操作になっている箇所があります。取得の仕方がhtml_textだったり文字列置換だったりしますが、統一のとれていないクソコードでごめんなさい。。。
weather.R
library(rvest)
library(stringr)
library(plyr)
library(dplyr) # plyrだけでいいかも
getYahooWeather <- function(y, m, url.base = "http://weather.yahoo.co.jp/weather/jp/past/13/4410.html"){
# 東京の天気を取得
# q <- html("http://weather.yahoo.co.jp/weather/jp/past/13/4410.html")
q <- html(sprintf("%s?c=%s&m=%s", url.base, y, m))
# 年の取得
year <- html_nodes(q, xpath = '//div[@id="yjw_past_area_navi"]/p') %>%
html_text() %>%
iconv("utf-8", "cp932")
# 月の取得
month <- html_nodes(q, xpath = '//td[@colspan=7]') %>%
html_text() %>%
iconv("utf-8", "cp932")
if(length(month) > 2){
month <- month[c(1,3)]
}
# 日付、天気の取得
l <- html_nodes(q, xpath = '//td[@align="center"]/a') %>%
iconv("utf-8", "cp932")
weather <- l %>% str_replace_all("\\n", "") %>%
str_replace_all(".+amp;d=", "") %>%
str_replace_all(".+alt=\"", "") %>%
str_replace_all("\".+", "")
df <- data.frame(d = 1:(length(weather)/2))
df$day <- as.numeric(weather[(1:(length(weather)/2))*2 - 1])
df$weather <- weather[(1:(length(weather)/2))*2]
# ソートした時にイマイチなのでas.numericする。
df$month <- as.numeric(str_replace_all(ifelse(df$day == df$d, month[[1]], month[[2]]), "月", ""))
df$year <- as.numeric(str_replace_all(year,"年",""))
# 気温の取得
temp <- html_nodes(q, xpath = '//td[@align="center"]/small/font') %>%
html_text() %>%
iconv("utf-8", "cp932")
df$temp_max <- temp[(1:(length(temp)/2))*2 - 1]
df$temp_min <- temp[(1:(length(temp)/2))*2]
df
}
# 以下、実際の利用方法
df.all = data.frame(d=1,day=1,weather="a",month=1,year=1,temp_max=1,temp_min=1)
df.all <- df.all[F,]
for(y in c(2014,2015)){
for(m in c(1,3,5,7,9,11)){
df.all <- merge(df.all, getYahooWeather(y,m), all.x=T, all.y=T)
}
}
df.all <- df.all[order(df.all$day), ]
df.all <- df.all[order(df.all$month), ]
df.all <- df.all[order(df.all$year), c("year","month","day","weather","temp_max","temp_min")]
write.csv(df.all, "temp.csv", row.names = F)
もっとスマートなやり方があれば、ぜひ教えて頂けると助かります。