番組表API(非公式)があるのでNokogiriで切って出力形式に。
何度も繰り返しアクセスするのはNHK側に迷惑だろうから、一度取ったデータはtabledataディレクトリにYAMLで保存します。
また番組表は当日午前5時〜翌日午前5時となっているので、午前5時を一日の始まりとして処理しています。
ただし、NHK第2は午前1時前(不定)〜午前6時が放送休止なので、強引に「放送休止中」と出力していますw
勉強中のものなので下手くそですがw
参考:
らじる★らじるの番組表API - 別館 子子子子子子(ねこのここねこ)
スクレイピングのためのNokogiri利用メモ - それはそれ。これはこれ。
# coding: utf-8 require 'open-uri' require 'nokogiri' require 'yaml/store' def read_saved_data(save_file_path) saved_data = IO::read(save_file_path) readed_data = YAML::load(saved_data) readed_data['timetable'] end def get_timetable(url, save_file_path) h = {} doc = Nokogiri::HTML(open url) items = doc.xpath("//item") items.each do |item| hj = {} item.children.each do |j| hj[j.name] = j.text.strip end index = item.xpath("eventid").text.to_i h[index] = hj end # save timetable data as YAML metadata = YAML::Store.new(save_file_path) metadata.transaction do metadata["timetable"] = h end h end def check_nowonair(h, now) nowonair = {} h.each do |index, value| if Time.parse(value["starttime"]) <= now && now <= Time.parse(value["endtime"]) nowonair[:title] = value["title"] nowonair[:starttime] = value["starttime"].scan(/\d\d:\d\d/)[0] nowonair[:url] = value["text"] end end nowonair end ch = ARGV[0].downcase case ch when "r1" then ch_sign = "第1" when "r2" then ch_sign = "第2" when "fm" then ch_sign = "FM" else raise ArgumentError, "argument must be r1/r2/fm" end tbl = {} now = Time.new broadcast_time = now - 5 * 60 * 60 save_file_path = File.expand_path("tabledata/nhk#{ch}_#{broadcast_time.strftime("%y%m%d")}_timetable.yaml") url = "http://cgi4.nhk.or.jp/hensei/api/sche-nr.cgi?tz=all&ch=net#{ch}&date=#{now.strftime("%Y-%m-%d").to_s}" Dir.mkdir(File.expand_path("tabledata")) unless File.directory?(File.expand_path("tabledata")) if File.exists?(save_file_path) tbl = read_saved_data(save_file_path) else tbl = get_timetable(url, save_file_path) end nowonair = check_nowonair(tbl, now) nowonair[:starttime] = "放送休止中" unless nowonair[:starttime] puts "NHK#{ch_sign} #{nowonair[:starttime]} #{nowonair[:title]} #{nowonair[:url]}"