LoginSignup
8
8

More than 5 years have passed since last update.

Rで天気と気温をスクレイピング(デフォルト東京)

Posted at

気象庁にダウンロードサイトがありますが

気象庁にもっとよいダウンロードサイトがあることに、作ってから気が付いたのですが、あえて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)

もっとスマートなやり方があれば、ぜひ教えて頂けると助かります。

8
8
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
8
8