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

370 lines
14 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Starbucksの店舗検索からスクレイピング
author: kazu634
date: 2008-11-29
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>