Yahoo乗り換え案内を使って通勤時間の短い場所を探すRubyスクリプトを書いてみた。

コロナ禍でリモートワーク中心の生活になった僕ですが、一方で平時はオフィスで働きたい…と思うこの頃を送ってます。

一方で子供の成長も待ってくれないし今住んでいる場所だと都心に近すぎて逆に今後の子育てに十分な広さの部屋を借りるor買うのが難しくなってしまうし…と考えて、将来の住む場所を探してみることにしました。

また長い将来を考えると、将来もずっと同じ場所で働いている可能性はむしろ低い(転職するかもしれないし、会社自身が移転するかもしれない)ので、複数の場所からのアクセスがいい所を探したい。

などを考えて、自動で各駅のYahoo乗り換え案内のデータをスクレイピングして、運賃と所要時間をcsvファイルに出力するスクリプトを書いてみました。

require "open-uri"
require "nokogiri"
require "csv"
charset = nil

# 住む場所の候補 
start_stations = [
  '川崎',
  '西馬込',
  '池上',
  '武蔵小杉',
  '新川崎',
  '元住吉',
]
# 勤務地の発着時刻
des_hour = '20'
des_minute = '10'.to_i
# 帰りかどうか
is_reverse = true
# 勤務地の候補
des_stations = [
  '新橋',
  '田町',
  '東京',
  '秋葉原',
  '虎ノ門',
  '大手町',
  '品川',
  '渋谷',
  '飯田橋',
  '新宿',
  '恵比寿',
  '六本木',
  '目黒',
  '五反田',
  '大崎',
  '横浜',
  '新横浜',
  'みなとみらい',
  '池袋',
  '上野',
  '橋本',
  '日本橋',
  '銀座',
  '永田町',
  '後楽園',
]
time_table = {}
fare_table = {}

start_stations.each do |start_station|
  puts start_station
  time_table[start_station] = {}
  fare_table[start_station] = {}
  des_stations.each do |des_station|
    if start_station != des_station
      url_params = [ 
        ['fromgid', ''],
        ['from', is_reverse ? des_station : start_station],
        ['togid', ''],
        ['to', is_reverse ? start_station : des_station],
        ['viacode', ''],
        ['via', ''],
        ['viacode', ''],
        ['via', ''],
        ['viacode', ''],
        ['via', ''],
        ['y', '2020'], # 年
        ['m', '10'], # 月
        ['d', '15'], # 日
        ['hh', des_hour],
        ['m2', des_minute % 10],
        ['m1', des_minute / 10],
        ['type', is_reverse ? 1 : 4],
        ['ticket', 'ic'],
        ['expkind', '1'],
        ['ws', '2'], # 1(急いで乗り換え)~ 4(ゆっくり乗り換え)
        ['s', '0'],
        ['kw', is_reverse ? start_station : des_station]
      ]
      url = "https://transit.yahoo.co.jp/search/result?#{URI.encode_www_form(url_params)}"

      begin
        html = URI.open(url) do |page|
          charset = page.charset
          page.read
        end

        contents = Nokogiri::HTML.parse(html,nil,charset)
        route01 = contents.css('#rsltlst').first
        time = route01.css('dl > dd > ul > li.time').first
        minutes = time.css('span.small').first.content.gsub(/([0-9]{1,2}時間)*([0-9]{1,2})分/) { $1.to_i * 60 + $2.to_i } 
        fare = route01.css('dl > dd > ul > li.fare').first.content.gsub(/円/, "")
      rescue => e
      	puts "calculation failed. #{start_station} #{des_station} #{e}"
      end
    else
      fare = 0
      minutes = 0
    end
    puts "#{des_station} #{fare} #{minutes}"
    time_table[start_station][des_station] = minutes
    fare_table[start_station][des_station] = fare
    sleep 7
  end
end

CSV.open('times.csv','w') do |csv|
  csv << [''] + des_stations
  start_stations.each do |start_station|
    csv << [start_station] + des_stations.map do |des_station|
      time_table[start_station][des_station]
    end
  end
end

CSV.open('fares.csv','w') do |csv|
  csv << [''] + des_stations
  start_stations.each do |start_station|
    csv << [start_station] + des_stations.map do |des_station|
      fare_table[start_station][des_station]
    end
  end
end

コメントを残す

メールアドレスが公開されることはありません。