M.C.P.C.

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


| トップページ |

2009年11月24日 00:14

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

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

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

前回は、メインイベントのHTMLからのスクレイピングをWeb::Scraperを使って行いました。アドビのサイトの構造がtable要素で作られていましたので、table要素でデータが作られている場合のサンプルとして参考になると思います、というところまでやりました。

今回は、取得するデータを、後の利用に便利なように変形していくことの一つとして、特定の単語がでてきたら、1、それ以外だったらundef、というPerlにとって都合のよい形式にしてみようと思います。


さて、先回、取得したデータは、こんな感じでした。ちなみにこれはYAML::SyckのDumpになっています。

---
codes:
  -
    address: 北海道札幌市西区二十四軒2条6丁目1番8号 TEL:011-621-1000 FAX:011-621-1500
    company: 株式会社 須田製版
    illustratorcs4: 'Yes'
    indesigncs4: 'Yes'
    pdfx1a: 'Yes'
    pdfx4: 'Yes'
    pref: 北海道
  -
    address: 北海道札幌市北区北8条西8丁目TEL:011-747-8886 FAX:011-756-7971
    company: 北海道大学生活協同組合印刷 情報サービス部
    illustratorcs4: 'Yes'
    indesigncs4: 'Yes'
    pdfx1a: 'Yes'
    pdfx4:  
    pref: 北海道
  -
  ...
  -
    address: 大分県大分市碩田町2-2-13TEL:097-536-4111 FAX:097-538-1149
    company: 株式会社 双林社
    illustratorcs4: 'Yes'
    indesigncs4: 'Yes'
    pdfx1a: 'Yes'
    pdfx4: ''
    pref: 大分県

illustratorcs4、indesigncs4、pdfx1a、pdfx4というのが、それぞれの印刷会社が対応しているかどうかを表すのですけれども、入っている値が'Yes'、''、空白、とまちまちです。これを、1またはundefにするとわかりがいいと思います。

そもそも、これの'Yes'って何が入っているんでしょうか。それは、先回のWeb::Scraperのプログラムの

my $s = scraper {
  process '//div[@class="tabcontent"][1]//table[@class="data-bordered max"]/tbody/tr', 'codes[]' => scraper {
    process '//td[1]', pref    => 'TEXT';
    process '//td[2]', company => 'TEXT';
    process '//td[3]', address => 'TEXT';
    process '//td[4]', illustratorcs4 => 'TEXT';
    process '//td[5]', indesigncs4    => 'TEXT';
    process '//td[6]', pdfx1a  => 'TEXT';
    process '//td[7]', pdfx4   => 'TEXT';
  };
};

という箇所によります。process '//td[7]', pdfx4 => 'TEXT';と指定しているので、

HTMLの

<tbody>
  <tr>
    <td>北海道</td>
    <td><a href="http://www.suda.co.jp/" target="_blank"
      >株式会社 須田製版</a></td>
    <td>北海道札幌市西区二十四軒2条6丁目1番8号<br />
      TEL:011-621-1000 FAX:011-621-1500</td>
    <td class="yes">Yes</td>
    <td class="yes">Yes</td>
    <td class="yes">Yes</td>
    <td class="yes">Yes</td>
  </tr>

であれば7番目のtdの中身

Yes

が入るということになります。

この指定の仕方を変えると、ほしい値が入るようになります。

filename: test5.pl

#!/usr/bin/perl
 
use strict;
use warnings;
use utf8;
use Web::Scraper;
use YAML::Syck;
use Encode;
 
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';
    process '//td[2]', company => 'TEXT';
    process '//td[3]', address => 'TEXT';
    process '//td[4]', illustratorcs4 =>
      [ 'TEXT', sub { return $_ =~m/yes/i ? 1 : undef; } ];
    process '//td[5]', indesigncs4    =>
      [ '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);
print Dump($scraped);
 
exit;
 
__END__

フィルタ機能というのを使って、取得してきた値を無名関数を使って変えてあげることができます。

実行結果はこんな感じ。

---
codes:
  -
    address: 北海道札幌市西区二十四軒2条6丁目1番8号 TEL:011-621-1000 FAX:011-621
-1500
    company: 株式会社 須田製版
    illustratorcs4: 1
    indesigncs4: 1
    pdfx1a: 1
    pdfx4: 1
    pref: 北海道
  -
    address: 北海道札幌市北区北8条西8丁目TEL:011-747-8886 FAX:011-756-7971
    company: 北海道大学生活協同組合印刷 情報サービス部
    illustratorcs4: 1
    indesigncs4: 1
    pdfx1a: 1
    pdfx4: ~
    pref: 北海道
  -
  ...
  -
    address: 大分県大分市碩田町2-2-13TEL:097-536-4111 FAX:097-538-1149
    company: 株式会社 双林社
    illustratorcs4: 1
    indesigncs4: 1
    pdfx1a: 1
    pdfx4: ~
    pref: 大分県

undefが入っているところはこのDumpでは~で表現されています。これで、'Yes'ばかりでうざかったのがすっきりしました!

おまけ。

さっきまでこんなコードになっていた。

filename: test6.pl

#!/usr/bin/perl
 
use strict;
use warnings;
use utf8;
use Web::Scraper;
use YAML::Syck;
use Encode;
 
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';
    process '//td[2]', company => 'TEXT';
    process '//td[3]', address => 'TEXT';
    process '//td[4]', illustratorcs4 =>
      sub { return $_->as_text =~ m/yes/i ? 1 : undef; };
    process '//td[5]', indesigncs4    =>
      sub { return $_->as_text =~ m/yes/i ? 1 : undef; };
    process '//td[6]', pdfx1a         =>
      sub { return $_->as_text =~ m/yes/i ? 1 : undef; };
    process '//td[7]', pdfx4          =>
      sub { return $_->as_text =~ m/yes/i ? 1 : undef; };
  };
};
 
my $scraped = $s->scrape($html);
print Dump($scraped);
 
exit;
 
__END__

この書き方をした場合、無名関数の中の$_に入っているのは、HTML::Elementのオブジェクトなんで、$_->as_textという書き方ができる。ふつうは、最初に出したコードのほうがわかりやすいですよね。


さて、次回は、この要領で、addressの中身に住所と電話番号とFAX番号が混ざっているのを何とかしたいと思います。これをちゃんと住所のみにしないと、ジオコーディングAPIに問い合わせできないので重要です。

投稿 大野 義貴 [GoogleMaps] | |

トラックバック(0)

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

コメント(2)

4回もコピペするんであれば、sub is_yes{ ... }とかで外だしにして、コールバックではそのサブルーチンだけ書くほうが読みやすいと思った。

もう何回かありますので、そこらへんで整形していくときに直していきます。

コメントする