M.C.P.C.

―むり・くり―プラスコミュニケーション(更新終了)


| トップページ |

2010年11月27日 00:00

Adobe Creative Suite 出力対応店一覧をGoogle Mapsで表示させる(16)

このエントリーをはてなブックマークに追加 mixiチェック

アドビのCS5対応プリントショップのリストのページから、Google Mapsに表示させるやつの16回目。

前回は、京都市専用のジオコーダ「ジオどす」を使ってみたのですが、今回の住所ではあまり結果が良くないっぽいので、やめた、っというところまでやりました。

今回は、Google Maps APIのジオコーディングでうまく出なかった3つの住所を、どうにかしてジオコーディングを通すため、「辞書」を作る、というのをやってみたいと思います。


さて、前々回と、前回で、Google Maps APIのジオコーダでうまく出ない3つの住所と、それを修正してうまく出る住所、というのが判明しています。

×岐阜県岐阜市長良福田町1丁目30番地
○岐阜県岐阜市福田町1丁目30

×大阪府大阪市西城区南津守7-15-16
○大阪府大阪市西成区南津守7-15-16

×京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F
○京都府京都市下京区五条烏丸町407-2

「×」のほうが、アドビのページから取得できる住所で、これをそのままジオコーダに突っ込んでもだめです。「○」のほうは、ジオコーダで座標が取得できる住所です。

つまり、「×」の住所が取得された時、「○」の住所に差し替えてしまえばよいわけです。

プログラムとしては、こんな感じになります。

Filename: test16.pl

use strict;
use warnings;
use utf8;
use Encode;
 
my $dict = (
  '岐阜県岐阜市長良福田町1丁目30番地'
    => '岐阜県岐阜市福田町1丁目30',
  '大阪府大阪市西城区南津守7-15-16'
    => '大阪府大阪市西成区南津守7-15-16',
  '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F'
    => '京都府京都市下京区五条烏丸町407-2',
);
 
my $input = '岐阜県岐阜市長良福田町1丁目30番地';
#my $input = '大阪府大阪市西城区南津守7-15-16';
#my $input = '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F';
 
print "input: $input\n";
print 'output: '.encode_utf8($dict{$input})."\n";
 
exit;
 
__END__

実行してみる

$ perl test16.pl
input: 岐阜県岐阜市長良福田町1丁目30番地
output: 岐阜県岐阜市福田町1丁目30
$

このように、連想配列を使うと、ある文字列に対応した文字列を用意できます。なので、「辞書」と呼ぶこともあります。

いまのプログラムのままだと、辞書が引けない文字列があった場合は、何も出力されないことになりますので、辞書が引けなかった場合は、辞書を引こうとした文字列をそのまま出力するようにします。

Filename: test17.pl

use strict;
use warnings;
use utf8;
use Encode;
 
my $dict = (
  '岐阜県岐阜市長良福田町1丁目30番地'
    => '岐阜県岐阜市福田町1丁目30',
  '大阪府大阪市西城区南津守7-15-16'
    => '大阪府大阪市西成区南津守7-15-16',
  '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F'
    => '京都府京都市下京区五条烏丸町407-2',
);
 
#my $input = '岐阜県岐阜市長良福田町1丁目30番地';
#my $input = '大阪府大阪市西城区南津守7-15-16';
#my $input = '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F';
my $input = '北海道札幌市西区二十四軒2条6丁目1番8号';
 
print "input: $input\n";
print 'output: '.encode_utf8($dict{$input} or $input)."\n";
 
exit;
 
__END__

($dict{$input} or $input)

の様に書きますと、連想配列のキーに対する値がある場合は $dict{$input} の値が使われ、ない場合は $dict{$input} が undef になりますので、or 以降の $input が採用されます。

この辞書を、12回目のスクレイピングスクリプトとくっつけます。

Filename: test18.pl

#!/usr/bin/perl
 
use strict;
use warnings;
use utf8;
use Web::Scraper;
use YAML;
use Encode;
use WebService::Simple;
 
my %dict = (
  '岐阜県岐阜市長良福田町1丁目30番地'
    => '岐阜県岐阜市福田町1丁目30',
  '大阪府大阪市西城区南津守7-15-16'
    => '大阪府大阪市西成区南津守7-15-16',
  '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F'
    => '京都府京都市下京区五条烏丸町407-2',
);
 
my $geo = WebService::Simple->new(
    response_parser => 'JSON',
    base_url => 'http://maps.google.com/maps/api/geocode/',
    param    => {
      region   => 'jp',
      language => 'ja',
      sensor   => 'false',
    },
);
 
open my $fh, '<', 'printshop.html';
my $html = decode_utf8(do { local $/; <$fh> });
close $fh;
 
my $s = scraper {
    process '//div[@class="tabcontent"][1]//table[@class="data-bordered max"]/tbody/tr', 'codes[]' => scraper {
        process '//td[1]', pref    => [ 'TEXT', sub { s/\s//g; } ];
        process '//td[2]', company => [ 'TEXT', sub { s/\s//g; } ];
        process '//td[3]', address => [ 'TEXT', sub { s/\s//g; s/TEL:.+$//i; return $_; } ];
        process '//td[3]', phone   => [ 'TEXT', sub { s/\s//g; if(m/TEL:([\d-]+)/i){return $1;};}];
        process '//td[3]', fax     => [ 'TEXT', sub { s/\s//g; s/:/:/g; if(m/FAX:([\d-]+)/i){return $1;};undef;}];
        process '//td[4]', illustratorcs5 => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[5]', indesigncs5    => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[6]', pdfx1a         => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[7]', pdfx4          => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
    };
};
 
my $scraped = $s->scrape($html);
 
foreach my $item ( @{$scraped->{codes}} ) {
  my $address = $item->{address};
  my $res = $geo->get( 'json', { address => ( $dict{$address} or $address ) } );
  my $val = $res->parse_response();
  print Dump( $val );
  sleep 1;
}
 
exit;
 
__END__

こんな感じで実行

$ perl test18.pl > results18.txt
$ grep -e 'status' resutls18.txt
status: OK
status: OK
status: OK
...
status: OK
status: OK
status: OK
$

これで、すべての住所がGoogle Maps APIでジオコーディングできるようになりました。

本当は、こうやって辞書を用意するのではなく、サイトに上がっているデータが正規化されているほうがいいんですけれども。ともかく、大阪の印刷会社さんの住所の件は、近々アドビさんがセミナーで来たときに直してくれるようお願いしてみようかなと思っています。(←迷惑かもな)

次回は、すべての住所から座標がとれましたので、いよいよGoogle Maps上で表示できるよう、JSON形式のデータを吐き出せるようにしたいと思います。


(2010-11-29 21:32追記)

2010-11-29 21:00の時点で、大阪の企業様の住所は、アドビ様から修正をしていただきました(アドビシステムズの岩本様からご連絡をいただきました)。

投稿 大野 義貴 [GoogleMaps] | |

トラックバック(0)

トラックバックURL: http://blog.dtpwiki.jp/MTOS/mt-tb.cgi/3419

コメントする