関西電力だけは、やや書式が異なるようですが、次のように書けば良さそう。
#!/usr/local/bin/perl use strict; use utf8; use Encode; use HTTP::Request::Common; use JSON qw/encode_json/; use LWP::UserAgent; #各電力会社から提供されている電力使用状況csvを取得し、保存します。 #30分間隔?のcron jobにすると良いと思います。 my $OUT_DIR = '../html/data'; #使用状況data(json)の保存先 my @AREAS = ({name=>'tokyo', site_url=>'http://www.tepco.co.jp/forecast/index-j.html', data_url=>'http://www.tepco.co.jp/forecast/html/images/juyo-j.csv', }, {name=>'tohoku', site_url=>'http://setsuden.tohoku-epco.co.jp/graph.html', data_url=>'http://setsuden.tohoku-epco.co.jp/common/demand/juyo_tohoku.csv', }, {name=>'chubu', site_url=>'http://denki-yoho.chuden.jp/index.html', data_url=>'http://denki-yoho.chuden.jp/denki_yoho_content_data/juyo_cepco.csv', }, {name=>'kansai', site_url=>'http://www.kepco.co.jp/setsuden/graph/index.html', data_url=>'http://www.kepco.co.jp/yamasou/juyo1_kansai.csv', } ); my $HTTP_TIMEOUT = 10; my $HTTP_MAX_RETRY = 5; main(); exit(0); sub main { for my $area (@AREAS){ my $pow_info = get_pow_info($area); next unless($pow_info); my $save_path = "$OUT_DIR/$area->{name}.json"; open(my $fh,">",$save_path) or die "can't open $save_path :$!"; print $fh encode_json($pow_info); close($fh) or die "can't close $save_path :$!"; } } sub get_pow_info { my ($area) = @_; my $ua = LWP::UserAgent->new(); $ua->timeout($HTTP_TIMEOUT); my $req = HTTP::Request->new(GET=>$area->{data_url}); my $i = 0; while( $i++ < $HTTP_MAX_RETRY ){ my $res = $ua->request($req); if($res->is_success){ if ($area->{name} eq 'kansai'){ return parse_csv_data_kansai($res->content); } else { return parse_csv_data_common($res->content,$area->{name}); } } print STDERR $res->status_line,"\n"; } print STDERR "exceeded HTTP_MAX_RETRY\n"; return undef; } sub parse_csv_data_common { my ($csv_lines_str,$area_name) = @_; my @csv_lines = split("\n",decode('utf8',$csv_lines_str)); my $ret = {}; #更新日時の取得 if($csv_lines[0] =~ /^(\d+)\D(\d+)\D(\d+) (\d+)\D(\d+) UPDATE/o ){ $ret->{Update} = sprintf("%04d-%02d-%02d %02d:%02d",$1,$2,$3,$4,$5); } else { print STDERR "can't parse csv(update) $area_name at $csv_lines[0]"; return undef; } #ピーク時供給力(万kW) if($csv_lines[2] =~ /^(\d+)/o ){ $ret->{Capacity} = $1; } else { print STDERR "can't parse csv(capacity) $area_name at $csv_lines[2]"; return undef; } #電力使用量の取得 my $i = 31; while($i >= 8 ){ my $csv_line = $csv_lines[$i]; if ($csv_line =~ /^(\d+)\D(\d+)\D(\d+),(\d+):\d+,(\d+)/o ){ my $date = sprintf("%04d-%02d-%02d",$1,$2,$3); my $hour = $4; my $usage = $5; if ($usage>0){ $ret->{Date} = $date; $ret->{Hour} = $hour; $ret->{Usage} = $usage; last; } } else { print STDERR "can't parse csv(usage) $area_name at $csv_line"; return undef; } $i--; } return $ret; } sub parse_csv_data_kansai { my ($csv_lines_str) = @_; my $area_name = 'kansai'; my @csv_lines = split("\n",decode('cp932',$csv_lines_str)); my $ret = {}; #更新日時の取得 if($csv_lines[0] =~ /^(\d+)\D(\d+)\D(\d+) (\d+)\D(\d+) UPDATE/o ){ $ret->{Update} = sprintf("%04d-%02d-%02d %02d:%02d",$1,$2,$3,$4,$5); } else { print STDERR "can't parse csv(update) $area_name at $csv_lines[0]"; return undef; } #ピーク時供給力(万kW) if($csv_lines[2] =~ /^(\d+)/o ){ $ret->{Capacity} = $1; } else { print STDERR "can't parse csv(capacity) $area_name at $csv_lines[2]"; return undef; } #電力使用量の取得 my $i = 34; while($i >= 11 ){ my $csv_line = $csv_lines[$i]; if ($csv_line =~ /^(\d+)\D(\d+)\D(\d+),(\d+):\d+,(\d+)/o ){ my $date = sprintf("%04d-%02d-%02d",$1,$2,$3); my $hour = $4; my $usage = $5; if ($usage>0){ $ret->{Date} = $date; $ret->{Hour} = $hour; $ret->{Usage} = $usage; last; } } else { print STDERR "can't parse csv(usage) $area_name at $csv_line"; return undef; } $i--; } return $ret; }