blog/content/post/2008/11/29/2008-11-29-00001077.md

370 lines
14 KiB
Markdown
Raw Normal View History

2019-03-31 11:00:21 +00:00
---
title: Starbucksの店舗検索からスクレイピング
author: kazu634
date: 2008-11-29
url: /2008/11/29/_1157/
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:4405;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}'
categories:
- Perl
- scraper
---
<div class="section">
<p>
<a href="http://d.hatena.ne.jp/sirocco634/20081125/1227625128" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20081125/1227625128', ' Starbucksの店舗情報を取得する &#8211; その1 &#8211; 武蔵の日記');" target="_blank"> Starbucksの店舗情報を取得する &#8211; その1 &#8211; 武蔵の日記</a>」のつづきだよ。
</p>
<blockquote>
<ul>
<li>
「starbucks」に関連する最近のエントリ <ul>
<li>
<a href="http://d.hatena.ne.jp/sirocco634/20081125/1227625128" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20081125/1227625128', ' Starbucksの店舗情報を取得する &#8211; その1 &#8211; 武蔵の日記');" target="_blank"> Starbucksの店舗情報を取得する &#8211; その1 &#8211; 武蔵の日記</a>
</li>
<li>
<a href="http://d.hatena.ne.jp/sirocco634/20060915/1158289200" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20060915/1158289200', '映画・『UDON』 &#8211; 武蔵の日記');" target="_blank">映画・『UDON』 &#8211; 武蔵の日記</a>
</li>
</ul>
</li>
</ul>
</blockquote>
<p>
<a name="seemore"></a>
</p>
<h4>
これまでのまとめ
</h4>
<p>
<a href="http://www.starbucks.co.jp/search/index.html/" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://www.starbucks.co.jp/search/index.html/', 'ページを表示できません。|スターバックス コーヒー ジャパン');" target="_blank">ページを表示できません。|スターバックス コーヒー ジャパン</a>からリンクの抽出を前回行いました。今回は個別のページから情報を取得します。
</p>
<h4>
取得したいページ
</h4>
<p>
たとえば「<a href="http://www.starbucks.co.jp/search/result_city2.php?SearchPerfecture=%8B" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://www.starbucks.co.jp/search/result_city2.php?SearchPerfecture=%8B', 'http://www.starbucks.co.jp/search/result_city2.php?SearchPerfecture=%8B');" target="_blank">http://www.starbucks.co.jp/search/result_city2.php?SearchPerfecture=%8B</a>{%8F%E9%8C%A7:title]」のページです。個々の情報が次のように並んでいます。
</p>
<p>
<center>
</center>
</p>
<p>
<a href="http://f.hatena.ne.jp/sirocco634/20081129222026" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://f.hatena.ne.jp/sirocco634/20081129222026', '');" class="hatena-fotolife" target="_blank"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/s/sirocco634/20081129/20081129222026.png" alt="f:id:sirocco634:20081129222026p:image" title="f:id:sirocco634:20081129222026p:image" class="hatena-fotolife" /></a>
</p></p>
<p>
ここから情報を取得します。
</p>
<h4>
Web::Scraper
</h4>
<p>
こういう場合は<a href="http://search.cpan.org/~miyagawa/Web-Scraper-0.24/lib/Web/Scraper.pm" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://search.cpan.org/~miyagawa/Web-Scraper-0.24/lib/Web/Scraper.pm', 'Web::Scraper');" target="_blank">Web::Scraper</a>を使うとよいようです。そこで実際に使ってみました。
</p>
<p>
参考にしたのは以下のページです:
</p>
<ul>
<li>
<a href="http://search.cpan.org/~miyagawa/Web-Scraper-0.24/lib/Web/Scraper.pm" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://search.cpan.org/~miyagawa/Web-Scraper-0.24/lib/Web/Scraper.pm', 'Web::Scraper &#8211; Web Scraping Toolkit inspired by Scrapi &#8211; search.cpan.org');" target="_blank">Web::Scraper &#8211; Web Scraping Toolkit inspired by Scrapi &#8211; search.cpan.org</a>
</li>
<li>
<a href="http://d.hatena.ne.jp/naoya/20070509/1178686816" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/naoya/20070509/1178686816', 'Web::Scraper &#8211; naoyaのはてなダイアリー');" target="_blank">Web::Scraper &#8211; naoyaのはてなダイアリー</a>
</li>
<li>
<a href="http://e8y.net/mag/013-web-scraper/" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://e8y.net/mag/013-web-scraper/', 'use Web::Scraper; &#8211; 今日のCPANモジュール');" target="_blank">use Web::Scraper; &#8211; 今日のCPANモジュール</a>
</li>
</ul>
<h4>
実際のコード
</h4>
<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 </span>URI;
<span class="synStatement">use </span>Web::Scraper;
<span class="synStatement">use </span>YAML;
<span class="synStatement">use </span>Encode;
<span class="synStatement">use utf8</span>;
<span class="synComment"># === Main part ===</span>
<span class="synComment"># Web::Scraperのインスタンスを作成</span>
<span class="synStatement">my</span> <span class="synIdentifier">$scraper</span> = scraper {
<span class="synComment"># 切り出す位置を指定</span>
<span class="synComment"># 今回は複数ある「&#60;div class=&#34;Table01&#34;&#62;...&#60;/div&#62;」の間を切り出し、</span>
<span class="synComment"># storesという配列に格納</span>
process <span class="synConstant">'//div[contains(@class, &#34;Table01&#34;)]'</span>, <span class="synConstant">'stores[]'</span> =&#62; scraper {
<span class="synComment"># 「&#60;div class=&#34;Table01&#34;&#62;」からの相対的な位置で切り出す位置を指定</span>
<span class="synComment"># 「//tr[1]/td[2]」は「&#60;div class=&#34;Table01&#34;&#62;」から</span>
<span class="synComment"># 一つ目の「&#60;tr&#62;」の中にある二つ目の「&#60;td&#62;...&#60;/td&#62;」の間にあるテキスト情報を</span>
<span class="synComment"># キー「store_name」としてハッシュに格納する</span>
process <span class="synConstant">'//tr[1]/td[2]'</span>, <span class="synConstant">'store_name'</span> =&#62; <span class="synConstant">'TEXT'</span>;
process <span class="synConstant">'//tr[2]/td[2]'</span>, <span class="synConstant">'address'</span> =&#62; <span class="synConstant">'TEXT'</span>;
process <span class="synConstant">'//tr[3]/td[2]'</span>, <span class="synConstant">'tel'</span> =&#62; <span class="synConstant">'TEXT'</span>;
process <span class="synConstant">'//tr[4]/td[2]'</span>, <span class="synConstant">'nearby_station'</span> =&#62; <span class="synConstant">'TEXT'</span>;
process <span class="synConstant">'//tr[5]/td[2]'</span>, <span class="synConstant">'open_close'</span> =&#62;<span class="synConstant">'TEXT'</span>;
}
};
<span class="synComment"># 実際に情報を取得する</span>
<span class="synStatement">my</span> <span class="synIdentifier">$result</span> = <span class="synIdentifier">$scraper</span>-&#62;scrape(
URI-&#62;<span class="synStatement">new</span>(
<span class="synConstant">&#34;http://www.starbucks.co.jp/search/result_city2.php?SearchPerfecture=%88</span><span class="synIdentifier">%A4</span><span class="synConstant">%92m%8C</span><span class="synIdentifier">%A7</span><span class="synConstant">&#34;</span>
)
);
<span class="synComment"># 情報の表示</span>
<span class="synStatement">print</span> encode( <span class="synConstant">'utf8'</span>, Dump(<span class="synIdentifier">$result</span>-&#62;{stores}) );
</pre>
<h4>
実行結果
</h4>
<blockquote>
<p>
&#8212;
</p>
<ul>
<li>
address: 郵便番号450-6013愛知県 名古屋市中村区 名駅 1-1-4 JRセントラルタワーズ 13F
</li>
</ul>
<p>
nearby_station: &#8216;名古屋駅 ( JR東海道本線、JR関西本線、名古屋市営地下鉄桜通線、名古屋市営地下鉄東山線、近鉄名古屋線 ) 徒歩2分 新名古屋駅 ( 名鉄名古屋本線、名鉄犬山線 ) 徒歩4分 名古屋セントラルタワーズ内&#8217;
</p>
<p>
open_close: &#8216;月~木: 8:00 23:00 [LO 22:30]金: 8:00 23:00 [LO 22:30]土: 8:00 23:00 [LO 22:30]日: 8:00 23:00 [LO 22:30]祝日: 8:00 23:00 [LO 22:30]定休日:不定休&#8217;
</p>
<p>
store_name: &#8216;名古屋JRセントラルタワーズ店&#8217;
</p>
<p>
tel: &#8216;052-586-7087 &#8217;
</p>
<ul>
<li>
address: 郵便番号460-0008愛知県 名古屋市中区 栄 4-6-1 ホテルプリシード名古屋 1F
</li>
</ul>
<p>
nearby_station: &#8216;栄駅 ( 名古屋市営地下鉄東山線、名古屋市営地下鉄名城線 ) 徒歩7分 栄町駅 ( 名鉄瀬戸線 ) 徒歩7分 ホテルプリシード名古屋&#8217;
</p>
<p>
open_close: &#8216;月~木: 7:00 22:00金: 7:00 22:30土: 7:00 22:30日: 7:00 22:00祝日: 7:00 22:00定休日不定休&#8217;
</p>
<p>
store_name: &#8216;ホテルプリシード名古屋 栄4丁目店&#8217;
</p>
<p>
tel: &#8216;052-251-7773 &#8217;
</p>
<ul>
<li>
address: 郵便番号444-0840愛知県 岡崎市 戸崎町外山 38-5 イオンモール岡崎
</li>
</ul>
<p>
nearby_station: &#8216;岡崎駅 ( JR東海道本線、愛知環状鉄道 ) 徒歩20分 東岡崎駅 ( 名鉄名古屋本線 ) 徒歩35分 イオンモール岡崎内&#8217;
</p>
<p>
open_close: &#8216;月~木: 10:00 22:00金: 10:00 22:00土: 10:00 22:00日: 10:00 22:00祝日: 10:00 22:00定休日不定休&#8217;
</p>
<p>
store_name: &#8216;イオンモール岡崎店&#8217;
</p>
<p>
tel: &#8216;0564-59-1010 &#8217;
</p>
<ul>
<li>
address: 郵便番号480-1124愛知県 愛知郡 長久手町戸田谷 901-1 アピタ長久手店
</li>
</ul>
<p>
nearby_station: &#8216;藤ヶ丘駅 ( 名古屋市営地下鉄東山線、東部丘陵線リニモ ) 徒歩25分 アピタ長久手店ショッピングセンター内1F&#8217;
</p>
<p>
open_close: &#8216;月~木: 10:00 22:00金: 10:00 22:00土: 10:00 22:00日: 10:00 22:00祝日: 10:00 22:00定休日不定休&#8217;
</p>
<p>
store_name: &#8216;名古屋 アピタ長久手店&#8217;
</p>
<p>
tel: &#8216;0561-61-7022 &#8217;
</p>
<ul>
<li>
address: 郵便番号450-0002愛知県 名古屋市中村区 名駅 4-7-25 名駅地下街サンロード
</li>
</ul>
<p>
nearby_station: &#8216;名古屋駅 ( JR東海道本線、JR関西本線、名古屋市営地下鉄桜通線、名古屋市営地下鉄東山線、近鉄名古屋線 ) 徒歩3分 新名古屋駅 ( 名鉄名古屋本線、名鉄犬山線 ) 徒歩3分 婦人服ITOJUの向かい側&#8217;
</p>
<p>
open_close: &#8216;月~木: 7:30 21:30金: 7:30 21:30土: 7:30 21:30日: 7:30 21:30祝日: 7:30 21:30定休日不定休&#8217;
</p>
<p>
store_name: &#8216;名駅地下街 サンロード店&#8217;
</p>
<p>
tel: &#8216;052-586-3252 &#8217;
</p>
<ul>
<li>
address: 郵便番号460-0008愛知県 名古屋市中区 栄 3-1-8 名古屋栄東急イン 1F
</li>
</ul>
<p>
nearby_station: &#8216;栄駅 ( 名古屋市営地下鉄東山線、名古屋市営地下鉄名城線 ) 徒歩3分 栄町駅 ( 名鉄瀬戸線 ) 徒歩3分 栄東急イン1F&#8217;
</p>
<p>
open_close: &#8216;月~木: 7:00 22:00金: 7:00 22:30土: 7:00 22:30日: 7:00 22:00祝日: 7:00 22:00定休日不定休&#8217;
</p>
<p>
store_name: &#8216;栄東急イン店&#8217;
</p>
<p>
tel: &#8216;052-262-2156 &#8217;
</p>
<ul>
<li>
address: 郵便番号460-0003愛知県 名古屋市中区 錦 2-18-19 三井住友銀行名古屋ビル 1F
</li>
</ul>
<p>
nearby_station: &#8216;伏見駅 ( 名古屋市営地下鉄東山線、名古屋市営地下鉄鶴舞線 ) 徒歩3分 電気文化会館の前の三井住友銀行の中&#8217;
</p>
<p>
open_close: &#8216;月~木: 7:00 22:00金: 7:00 22:00土: 8:00 22:00日: 8:00 21:00祝日: 8:00 21:00定休日不定休&#8217;
</p>
<p>
store_name: &#8216;三井住友銀行名古屋ビル店&#8217;
</p>
<p>
tel: &#8216;052-232-1516 &#8217;
</p>
<ul>
<li>
address: 郵便番号470-2100愛知県 知多郡 東浦町緒川申新田二区 67-8 イオンモール東浦
</li>
</ul>
<p>
nearby_station: &#8216;緒川駅 ( JR武豊線 ) 徒歩5分 イオン東浦ショッピングセンター&#8217;
</p>
<p>
open_close: &#8216;月~木: 10:00 22:00金: 10:00 22:00土: 10:00 22:00日: 10:00 22:00祝日: 10:00 22:00定休日不定休&#8217;
</p>
<p>
store_name: &#8216;イオンモール東浦店&#8217;
</p>
<p>
tel: &#8216;0562-82-2723 &#8217;
</p>
<ul>
<li>
address: 郵便番号456-8580愛知県 名古屋市熱田区 神宮 3-6-34 名鉄パレ百貨店 神宮
</li>
</ul>
<p>
nearby_station: &#8216;神宮前駅 ( 名鉄名古屋本線、名鉄常滑線 ) 徒歩1分 東口の階段降りてすぐ&#8217;
</p>
<p>
open_close: &#8216;月~木: 7:00 21:30金: 7:00 21:30土: 7:00 21:30日: 7:00 21:00祝日: 7:00 21:00定休日不定休&#8217;
</p>
<p>
store_name: &#8216;名鉄 神宮前駅店&#8217;
</p>
<p>
tel: &#8216;052-683-5013 &#8217;
</p>
<ul>
<li>
address: 郵便番号460-0002愛知県 名古屋市中区 丸の内 3-20-17 中外東京海上ビル 1F
</li>
</ul>
<p>
nearby_station: &#8216;久屋大通駅 ( 名古屋市営地下鉄名城線、名古屋市営地下鉄桜通線 ) 徒歩1分 地下鉄久屋大通駅1番出口すぐ&#8217;
</p>
<p>
open_close: &#8216;月~木: 7:00 22:00金: 7:00 22:30土: 7:00 22:30日: 8:00 22:00祝日: 8:00 22:00定休日不定休&#8217;
</p>
<p>
store_name: &#8216;桜通り大津店&#8217;
</p>
<p>
tel: &#8216;052-962-1055 &#8217;
</p>
</blockquote>
<h4>
これからの課題
</h4>
<ul>
<li>
検索トップページから再帰的に全てのページの店舗情報を取得できるようにする
</li>
</ul>
</div>