概要
Web サイト 花粉対策特集 - Yahoo!特別企画 を Ruby + Mechanize でスクレイピングして花粉飛散予報を取得する。
花粉飛散情報について
- 花粉飛散予報は今日と明日の2日分
- 沖縄県の花粉情報は無い
- 飛散量には「少ない」「やや多い」「多い」「非常に多い」「飛散前」「飛散終了」「情報なし」などの文字列が入ると思われる
参考: 名古屋市中区の花粉情報 | 花粉症特集 - Yahoo!特別企画
Ruby によるサンプルコード
スクレイピングのためのライブラリとして mechanize を利用する。
require 'mechanize'
# 花粉飛散情報。
#
# データソース:
# 花粉対策特集 - Yahoo!特別企画 {https://kafun.yahoo.co.jp/}
class Kafun
# 花粉飛散情報を取得する。
#
# @param pref_id [String] JIS X 0401 都道府県コード
# @param detail [true/false] 詳細情報(2日分の花粉予報)を取得するか?
# @return [Hash]
def get(pref_id, detail=false)
# URLの例
# 北海道: https://kafun.yahoo.co.jp/weather/1/ ← 「01」じゃなくて「1」
# 愛知県: https://kafun.yahoo.co.jp/weather/23/
# 沖縄県のデータは無し
# 都道府県コードが「01」で来ても「1」になるように to_i
url = "https://kafun.yahoo.co.jp/weather/#{pref_id.to_i}/"
agent = Mechanize.new
page = agent.get(url)
date = page.search('.date').inner_text
area = page.search('.dataBox__areaName a')
data = page.search('.dataBox__pollenData .text')
kind = page.search('.dataBox__pollenKind .text')
area_list = []
area.each_with_index do |e, i|
area_list << { # 地域毎にデータを持つ構造に
:area => e.inner_text, # 地域名
:url => "https:#{e[:href]}", # URL
:data => [{ # 花粉飛散情報(日付別データの配列)
:date => date, # 日付
:rank => data[i].inner_text, # 飛散量
:kind => kind[i].inner_text # 種類
}]
}
end
if detail
detail_area_list = []
area_list.each do |e|
# 2日分の花粉飛散情報を取得
detail_area_list << get_detail(e[:url], e[:area])
end
detail_area_list
else
# 1日分の花粉飛散情報を返す
area_list
end
end
private
def get_detail(url, area)
agent = Mechanize.new
page = agent.get(url)
date = page.search('.dataBox__date')
data = page.search('.dataBox__pollenData .text')
kind = page.search('.dataBox__pollenData .text__kind')
list = [] # 花粉飛散情報(日付別データの配列)
date.each_with_index do |e, i|
list << {
:date => e.inner_text, # 日付
:rank => data[i].inner_text, # 飛散量
:kind => kind[i].inner_text # 種類
}
end
{
:area => area, # 地域名
:url => url, # URL
:data => list # 花粉飛散情報(日付別データの配列)
}
end
end
puts '愛知県(都道府県コードは23)の花粉飛散情報を取得する(1日分)'
pp Kafun.new.get('23')
puts
puts '愛知県(都道府県コードは23)の花粉飛散情報を取得する(2日分)'
pp Kafun.new.get('23', true)
puts
サンプルコードの実行結果
愛知県(都道府県コードは23)の花粉飛散情報を取得する(1日分)
[{:area=>"名古屋市中区",
:url=>"https://kafun.yahoo.co.jp/weather/23/23106/",
:data=>[{:date=>"1月31日", :rank=>"飛散前", :kind=>"スギ花粉中心"}]},
{:area=>"豊橋市",
:url=>"https://kafun.yahoo.co.jp/weather/23/23201/",
:data=>[{:date=>"1月31日", :rank=>"飛散前", :kind=>"スギ花粉中心"}]},
{:area=>"岡崎市",
:url=>"https://kafun.yahoo.co.jp/weather/23/23202/",
:data=>[{:date=>"1月31日", :rank=>"飛散前", :kind=>"スギ花粉中心"}]},
{:area=>"設楽町",
:url=>"https://kafun.yahoo.co.jp/weather/23/23561/",
:data=>[{:date=>"1月31日", :rank=>"飛散前", :kind=>"スギ花粉中心"}]}]
愛知県(都道府県コードは23)の花粉飛散情報を取得する(2日分)
[{:area=>"名古屋市中区",
:url=>"https://kafun.yahoo.co.jp/weather/23/23106/",
:data=>
[{:date=>"1/31(水)", :rank=>"飛散前", :kind=>"スギ花粉中心"},
{:date=>"2/1(木)", :rank=>"少ない", :kind=>"スギ花粉中心"}]},
{:area=>"豊橋市",
:url=>"https://kafun.yahoo.co.jp/weather/23/23201/",
:data=>
[{:date=>"1/31(水)", :rank=>"飛散前", :kind=>"スギ花粉中心"},
{:date=>"2/1(木)", :rank=>"少ない", :kind=>"スギ花粉中心"}]},
{:area=>"岡崎市",
:url=>"https://kafun.yahoo.co.jp/weather/23/23202/",
:data=>
[{:date=>"1/31(水)", :rank=>"飛散前", :kind=>"スギ花粉中心"},
{:date=>"2/1(木)", :rank=>"少ない", :kind=>"スギ花粉中心"}]},
{:area=>"設楽町",
:url=>"https://kafun.yahoo.co.jp/weather/23/23561/",
:data=>
[{:date=>"1/31(水)", :rank=>"飛散前", :kind=>"スギ花粉中心"},
{:date=>"2/1(木)", :rank=>"少ない", :kind=>"スギ花粉中心"}]}]