blog/content/post/2009-10-27-00001251.md

183 lines
18 KiB
Markdown

---
title: グルメナビサイトを横断検索する perl スクリプト
author: kazu634
date: 2009-10-27
url: /2009/10/27/_1372/
wordtwit_post_info:
- 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:4875;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}'
categories:
- Perl
---
<div class="section">
<p>
作ってみました。まずはこのような pm ファイルを作成します。
</p>
<h4>
pm ファイル
</h4>
<pre class="syntax-highlight">
<span class="synStatement">package</span><span class="synType"> WebService::Gourmet;</span>
<span class="synStatement">use </span><span class="synConstant">5.010000</span>;
<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use </span>Carp;
<span class="synStatement">use base</span> <span class="synConstant">qw(Class::Accessor::Fast Exporter)</span>;
__PACKAGE__-&#62;mk_accessors(qw ( tel result ));
<span class="synStatement">use </span>WebService::Simple;
<span class="synStatement">use </span>YAML::Syck;
<span class="synStatement">use </span>XML::Simple;
<span class="synStatement">use </span>Encode;
<span class="synComment"># Items to export into callers namespace by default. Note: do not export</span>
<span class="synComment"># names by default without a very good reason. Use EXPORT_OK instead.</span>
<span class="synComment"># Do not simply export all your public functions/methods/constants.</span>
<span class="synComment"># This allows declaration use WebService::Gourmet ':all';</span>
<span class="synComment"># If you do not need this, moving things directly into @EXPORT or @EXPORT_OK</span>
<span class="synComment"># will save memory.</span>
<span class="synStatement">our</span> <span class="synIdentifier">%EXPORT_TAGS</span> = (
<span class="synConstant">'all'</span> =&#62; [
<span class="synConstant">qw(</span>
<span class="synConstant"> )</span>
]
);
<span class="synStatement">our</span> <span class="synIdentifier">@EXPORT_OK</span> = ( @{ <span class="synIdentifier">$EXPORT_TAGS</span>{<span class="synConstant">'all'</span>} } );
<span class="synStatement">our</span> <span class="synIdentifier">@EXPORT</span> = <span class="synConstant">qw(</span>
<span class="synConstant">)</span>;
<span class="synStatement">our</span> <span class="synIdentifier">$VERSION</span> = <span class="synConstant">'0.01'</span>;
<span class="synComment"># Preloaded methods go here.</span>
<span class="synStatement">sub</span><span class="synIdentifier"> search_hot </span>{
<span class="synStatement">my</span> <span class="synIdentifier">$self</span> = <span class="synStatement">shift</span>();
<span class="synComment"># ホットペッパー</span>
<span class="synStatement">my</span> <span class="synIdentifier">$gourmet</span> = WebService::Simple-&#62;<span class="synStatement">new</span>(
<span class="synConstant">base_url </span>=&#62; <span class="synConstant">&#34;http://webservice.recruit.co.jp/hotpepper/shop/v1/&#34;</span>,
<span class="synConstant">param </span>=&#62; { <span class="synConstant">key </span>=&#62; <span class="synConstant">'Your API key'</span>, }
);
<span class="synComment"># 入力された電話番号は「lll-mmm-nnnn」という形式のみを想定している。</span>
<span class="synComment"># しかし、ホットペッパーは「lllmmmnnnn」という形式のみ受け付ける。</span>
<span class="synComment"># そこで変換を行う。</span>
<span class="synStatement">my</span> <span class="synIdentifier">$arg</span> = <span class="synIdentifier">$self</span>-&#62;{tel};
<span class="synIdentifier">$arg</span> =~ <span class="synStatement">s/</span><span class="synConstant">-</span><span class="synStatement">//g</span>;
<span class="synComment"># APIをリクエストする</span>
<span class="synStatement">my</span> <span class="synIdentifier">$response</span> = <span class="synIdentifier">$gourmet</span>-&#62;get( { <span class="synConstant">tel </span>=&#62; <span class="synIdentifier">$arg</span>, } );
<span class="synComment"># 結果を $self-&#62;result に格納する</span>
<span class="synStatement">if</span> ( <span class="synStatement">defined</span> XMLin( <span class="synIdentifier">$response</span>-&#62;content )-&#62;{shop} ) {
<span class="synStatement">my</span> <span class="synIdentifier">$result</span> = XMLin( <span class="synIdentifier">$response</span>-&#62;content )-&#62;{shop};
<span class="synStatement">my</span> <span class="synIdentifier">$shopname</span> = encode( <span class="synConstant">'utf8'</span>, <span class="synIdentifier">$result</span>-&#62;{name} );
<span class="synStatement">my</span> <span class="synIdentifier">$address</span> = encode( <span class="synConstant">'utf8'</span>, <span class="synIdentifier">$result</span>-&#62;{address} );
<span class="synStatement">my</span> <span class="synIdentifier">$url</span> = encode( <span class="synConstant">'utf8'</span>, <span class="synIdentifier">$result</span>-&#62;{urls}-&#62;{pc} );
<span class="synStatement">my</span> <span class="synIdentifier">$tel</span> = <span class="synIdentifier">$self</span>-&#62;tel;
<span class="synIdentifier">$result</span> =
<span class="synConstant">&#34;[Hotpepper] </span><span class="synIdentifier">$shopname</span><span class="synSpecial">\t</span><span class="synConstant">|*店名|[</span><span class="synIdentifier">$url</span><span class="synConstant">:title=</span><span class="synIdentifier">$shopname</span><span class="synConstant">]|</span><span class="synSpecial">\\</span><span class="synConstant">n|*住所|</span><span class="synIdentifier">$address</span><span class="synConstant">|</span><span class="synSpecial">\\</span><span class="synConstant">n|*電話番号|</span><span class="synIdentifier">$tel</span><span class="synConstant">|&#34;</span>;
<span class="synIdentifier">$self</span>-&#62;result(<span class="synIdentifier">$result</span>);
}
<span class="synComment"># ヒットすれば t を返し、ヒットしなければ f を返す</span>
<span class="synStatement">return</span> <span class="synStatement">defined</span> XMLin( <span class="synIdentifier">$response</span>-&#62;content )-&#62;{shop};
}
<span class="synStatement">sub</span><span class="synIdentifier"> search_gournavi </span>{
<span class="synStatement">my</span> <span class="synIdentifier">$self</span> = <span class="synStatement">shift</span>();
<span class="synComment"># ぐるなびへのアクセス</span>
<span class="synStatement">my</span> <span class="synIdentifier">$gourmet</span> = WebService::Simple-&#62;<span class="synStatement">new</span>(
<span class="synConstant">base_url </span>=&#62; <span class="synConstant">&#34;http://api.gnavi.co.jp/ver1/RestSearchAPI/?&#34;</span>,
<span class="synConstant">param </span>=&#62; { <span class="synConstant">keyid </span>=&#62; <span class="synConstant">'Your API key'</span>, }
);
<span class="synComment"># 電話番号の取得</span>
<span class="synStatement">my</span> <span class="synIdentifier">$arg</span> = <span class="synIdentifier">$self</span>-&#62;{tel};
<span class="synComment"># APIをリクエストする</span>
<span class="synStatement">my</span> <span class="synIdentifier">$response</span> = <span class="synIdentifier">$gourmet</span>-&#62;get( { <span class="synConstant">tel </span>=&#62; <span class="synIdentifier">$arg</span>, } );
<span class="synComment"># 結果を $self-&#62;result に格納する</span>
<span class="synStatement">if</span> ( <span class="synStatement">defined</span> XMLin( <span class="synIdentifier">$response</span>-&#62;content )-&#62;{rest} ) {
<span class="synStatement">my</span> <span class="synIdentifier">$result</span> = XMLin( <span class="synIdentifier">$response</span>-&#62;content )-&#62;{rest};
<span class="synStatement">my</span> <span class="synIdentifier">$shopname</span> = encode( <span class="synConstant">'utf8'</span>, <span class="synIdentifier">$result</span>-&#62;{name} );
<span class="synStatement">my</span> <span class="synIdentifier">$address</span> = encode( <span class="synConstant">'utf8'</span>, <span class="synIdentifier">$result</span>-&#62;{address} );
<span class="synStatement">my</span> <span class="synIdentifier">$url</span> = encode( <span class="synConstant">'utf8'</span>, <span class="synIdentifier">$result</span>-&#62;{url} );
<span class="synStatement">my</span> <span class="synIdentifier">$tel</span> = <span class="synIdentifier">$self</span>-&#62;tel;
<span class="synStatement">my</span> <span class="synIdentifier">$image</span> = encode( <span class="synConstant">'utf8'</span>, <span class="synIdentifier">$result</span>-&#62;{image_url}-&#62;{shop_image1} );
<span class="synIdentifier">$result</span> =
<span class="synConstant">&#34;[ぐるなび] </span><span class="synIdentifier">$shopname</span><span class="synSpecial">\t</span><span class="synConstant">|*店名|[</span><span class="synIdentifier">$url</span><span class="synConstant">:title=</span><span class="synIdentifier">$shopname</span><span class="synConstant">]|</span><span class="synSpecial">\\</span><span class="synConstant">n|*住所|</span><span class="synIdentifier">$address</span><span class="synConstant">|</span><span class="synSpecial">\\</span><span class="synConstant">n|*電話番号|</span><span class="synIdentifier">$tel</span><span class="synConstant">|</span><span class="synSpecial">\\</span><span class="synConstant">n|*画像|[</span><span class="synIdentifier">$image</span><span class="synConstant">:image:w300]&#34;</span>;
<span class="synIdentifier">$self</span>-&#62;result(<span class="synIdentifier">$result</span>);
}
<span class="synComment"># ヒットすれば t を返し、ヒットしなければ f を返す</span>
<span class="synStatement">return</span> <span class="synStatement">defined</span> XMLin( <span class="synIdentifier">$response</span>-&#62;content )-&#62;{rest};
}
<span class="synStatement">sub</span><span class="synIdentifier"> search_dokoiku </span>{
<span class="synStatement">my</span> <span class="synIdentifier">$self</span> = <span class="synStatement">shift</span>();
<span class="synComment"># ドコイク?へのアクセス</span>
<span class="synStatement">my</span> <span class="synIdentifier">$gourmet</span> = WebService::Simple-&#62;<span class="synStatement">new</span>(
<span class="synConstant">base_url </span>=&#62; <span class="synConstant">&#34;http://api.doko.jp/v1/searchPOI.do?&#34;</span>,
<span class="synConstant">param </span>=&#62; {
<span class="synConstant">key </span>=&#62; <span class="synConstant">'Your API key'</span>,
<span class="synConstant">format </span>=&#62; <span class="synConstant">'xml'</span>,
}
);
<span class="synComment"># 電話番号の取得</span>
<span class="synStatement">my</span> <span class="synIdentifier">$arg</span> = <span class="synIdentifier">$self</span>-&#62;{tel};
<span class="synComment"># APIをリクエストする</span>
<span class="synStatement">my</span> <span class="synIdentifier">$response</span> = <span class="synIdentifier">$gourmet</span>-&#62;get( { <span class="synConstant">tel </span>=&#62; <span class="synIdentifier">$arg</span>, } );
<span class="synComment"># 結果を $self-&#62;result に格納する</span>
<span class="synStatement">if</span> ( <span class="synStatement">defined</span> XMLin( <span class="synIdentifier">$response</span>-&#62;content )-&#62;{poi} ) {
<span class="synStatement">my</span> <span class="synIdentifier">$result</span> = XMLin( <span class="synIdentifier">$response</span>-&#62;content )-&#62;{poi};
<span class="synStatement">my</span> <span class="synIdentifier">$shopname</span> = encode( <span class="synConstant">'utf8'</span>, <span class="synIdentifier">$result</span>-&#62;{name} );
<span class="synStatement">my</span> <span class="synIdentifier">$address</span> = encode( <span class="synConstant">'utf8'</span>, <span class="synIdentifier">$result</span>-&#62;{address} );
<span class="synStatement">my</span> <span class="synIdentifier">$url</span> = encode( <span class="synConstant">'utf8'</span>, <span class="synIdentifier">$result</span>-&#62;{dokopcurl} );
<span class="synStatement">my</span> <span class="synIdentifier">$tel</span> = <span class="synIdentifier">$self</span>-&#62;tel;
<span class="synIdentifier">$result</span> =
<span class="synConstant">&#34;[ドコイク?] </span><span class="synIdentifier">$shopname</span><span class="synSpecial">\t</span><span class="synConstant">|*店名|[</span><span class="synIdentifier">$url</span><span class="synConstant">:title=</span><span class="synIdentifier">$shopname</span><span class="synConstant">]|</span><span class="synSpecial">\\</span><span class="synConstant">n|*住所|</span><span class="synIdentifier">$address</span><span class="synConstant">|</span><span class="synSpecial">\\</span><span class="synConstant">n|*電話番号|</span><span class="synIdentifier">$tel</span><span class="synConstant">|&#34;</span>;
<span class="synIdentifier">$self</span>-&#62;result(<span class="synIdentifier">$result</span>);
}
<span class="synComment"># ヒットすれば t を返し、ヒットしなければ f を返す</span>
<span class="synStatement">return</span> <span class="synStatement">defined</span> XMLin( <span class="synIdentifier">$response</span>-&#62;content )-&#62;{poi};
}
<span class="synStatement">sub</span><span class="synIdentifier"> search </span>{
<span class="synStatement">my</span> <span class="synIdentifier">$self</span> = <span class="synStatement">shift</span>();
<span class="synStatement">if</span> ( <span class="synIdentifier">$self</span>-&#62;search_hot() ) {
say <span class="synIdentifier">$self</span>-&#62;result;
}
<span class="synStatement">if</span> ( <span class="synIdentifier">$self</span>-&#62;search_gournavi() ) {
say <span class="synIdentifier">$self</span>-&#62;result;
}
<span class="synStatement">if</span> ( <span class="synIdentifier">$self</span>-&#62;search_dokoiku() ) {
say <span class="synIdentifier">$self</span>-&#62;result;
}
}
<span class="synConstant">1</span>;
</pre>
<h4>
perl スクリプト
</h4>
<p>
この pm ファイルを用いる、perl スクリプトを作成します。
</p>
<pre class="syntax-highlight">
<span class="synComment"># === Libraries ===</span>
<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use utf8</span>;
<span class="synStatement">use lib</span> <span class="synConstant">'/Users/kazu634/bin/lib'</span>;
<span class="synStatement">use </span>WebService::Gourmet;
<span class="synComment"># === Main part ===</span>
<span class="synStatement">my</span> <span class="synIdentifier">$tel</span> = <span class="synStatement">shift</span> || <span class="synStatement">die</span> <span class="synConstant">&#34;Usage: gourmet 000-000-0000</span><span class="synSpecial">\n</span><span class="synConstant">&#34;</span>;
<span class="synStatement">die</span> <span class="synConstant">&#34;Telephone number must be with hyphen. For example, 000-000-0000&#34;</span>
<span class="synStatement">unless</span> ( <span class="synIdentifier">$tel</span> =~<span class="synStatement"> /</span><span class="synConstant">^</span><span class="synSpecial">\d+</span><span class="synConstant">-</span><span class="synSpecial">\d+</span><span class="synConstant">-</span><span class="synSpecial">\d+</span><span class="synConstant">$</span><span class="synStatement">/</span> );
<span class="synStatement">my</span> <span class="synIdentifier">$instance</span> = WebService::Gourmet-&#62;<span class="synStatement">new</span>( { <span class="synConstant">tel </span>=&#62; <span class="synIdentifier">$tel</span> } );
<span class="synIdentifier">$instance</span>-&#62;search();
</pre>
<h4>
実行結果
</h4>
<pre class="syntax-highlight">
~/bin on kazu634 <span class="synStatement">[</span><span class="synConstant">531</span><span class="synStatement">]</span> $: perl gourmet.pl <span class="synConstant">045-324-2831</span>
<span class="synStatement">[</span>ぐるなび<span class="synStatement">]</span> Backstreet Brewery <span class="synStatement">|</span>*店名<span class="synStatement">|[</span>http://r.gnavi.co.jp/g600174/?ak<span class="synStatement">=</span><span class="synConstant">VMPVyGdfIVYCrk8cr02oSYEV7QXvr8jhUTdC</span>%2Ba4dsB8%3D:title<span class="synStatement">=</span><span class="synConstant">Backstreet</span> Brewery<span class="synStatement">]|</span>\n<span class="synStatement">|</span>*住所<span class="synStatement">|</span><span class="synConstant">220-0005</span> 神奈川県横浜市西区南幸<span class="synConstant">2-6-6</span> DD・Z-POINT1F<span class="synStatement">|</span>\n<span class="synStatement">|</span>*電話番号<span class="synStatement">|</span><span class="synConstant">045-324-2831</span><span class="synStatement">|</span>\n<span class="synStatement">|</span>*画像<span class="synStatement">|[</span>http://apicache.gnavi.co.jp/image/rest/index.php?img<span class="synStatement">=</span><span class="synConstant">g600174v</span>.jpg<span class="synStatement">&#38;</span>sid<span class="synStatement">=</span><span class="synConstant">g600174</span>:image:w300<span class="synStatement">]</span>
<span class="synStatement">[</span>ドコイク?<span class="synStatement">]</span> Backstreet Brewery <span class="synStatement">|</span>*店名<span class="synStatement">|[</span>http://www.doko.jp/search/shop/sc71233363/?vos<span class="synStatement">=</span><span class="synConstant">apidoko1</span>:title<span class="synStatement">=</span><span class="synConstant">Backstreet</span> Brewery<span class="synStatement">]|</span>\n<span class="synStatement">|</span>*住所<span class="synStatement">|</span>神奈川県横浜市西区南幸<span class="synConstant">2-6</span>-6DD・Z-POINT1F<span class="synStatement">|</span>\n<span class="synStatement">|</span>*電話番号<span class="synStatement">|</span><span class="synConstant">045-324-2831</span><span class="synStatement">|</span>
</pre>
<p>
これを anything で取り込んで使うぞ!
</p>
</div>