Perl

フィルターの概念を覚えた

  • POST
Web::Scraperにはフィルターというものがあります。要はスクレイピングした結果を anonymous subroutine に渡して、結果を操作できてしまう…というものです。 なんでそんなのが必要なの? Starbucksの店舗情報をスクレイピングしていて、HTMLの文字コードはShift-JISでした。そして、リンクへのURLには日本語が付加されていました。 ここでWeb::Scraperを用いてURLを取り込むと、私の環境ではUTF-8でエンコードされたURLが取得され、そのURLでアクセスしてもリンク先へ飛ぶことが出来ませんでした。UTF-8で取り込まれてしまったエンコード済みURLをデコードし、Shift-JISに変換し、再度エンコードするという処理が必要だということがわかりました。 ソース 実際にやってみます: use strict; use Web::Scraper; use URI; use URI::Escape; use utf8; use YAML; use Perl6::Say; use Encode; # ================= # === Main Part === # ================= # ========================= # === 各県へのURLを取得 === # ========================= # starbucksのURLを指定 my $uri = URI->new("http://www.starbucks.co.jp/search/index.html"); # スクレイピングの設定を行う my $scraper = scraper { process '//area[@href=~/.+SearchPerfecture/]', 'prefs[]' => [ '@href', sub{ my $url = $_->as_string; my @url_split = split( /=/, $url ); # utf8なURLをデコード my $utf8_encode = pop(@url_split); my $utf8 = uri_unescape($utf8_encode); # UTF-8に変換 my $temp = decode( 'utf8', $utf8 ); # Shift-JISに変換 $temp = encode( 'shiftjis', $temp ); # 再度エンコード $temp = uri_escape($temp); push( @url_split, $temp ); return {'shiftjis' => join( '=', @url_split ), 'utf-8' => $_->as_string}; } ]; process '//td[@class="SelectFromPlace"]//a', 'citys[]' => '@href'; }; # スクレイピングの実行 my $result = $scraper->scrape($uri); say YAML::Dump($result); 実行例 kazu634@srv634% perl test.