nokogiriとopen-uriを使ってアパホテルの店舗数を数えてみる

前回に引き続きチェーン店の店舗数を数えてみます。

[nokogiriとopen-uriを使って松屋の店舗数を数えてみる](http://qiita.com/murata0705/items/65d4b4275b68430be35e)

アパホテルのホテル一覧ページを探してみると、このページから情報を取得することができそうです。

[ホテルネットワーク一覧](http://www.apahotel.com/hotel/)

![ホテルネットワーク一覧｜【公式】アパホテル｜ビジネスホテル予約サイト.png](https://qiita-image-store.s3.amazonaws.com/0/34733/2470658c-781b-b48c-ac1e-355717b229ed.png)

ただここに店舗数は載っていないので、店舗数が載っているページと場所を探す必要があります。
ボタンをクリックして次の階層のページ（北海道）に行くと、店舗数がありました。

[北海道のホテル](http://www.apahotel.com/hotel/hokkaido/)

![北海道のホテル｜【公式】アパホテル｜ビジネスホテル予約サイト.png](https://qiita-image-store.s3.amazonaws.com/0/34733/c96933c9-ab03-8fb9-f7a9-c7ea563eefd0.png)


まずはこの要素を取ってくるコードを書きます。

```rb
# coding: utf-8
require 'open-uri'
require 'nokogiri'

URL = "http://www.apahotel.com/hotel/hokkaido/"
doc = Nokogiri::HTML(open(URL), nil, 'utf-8')
puts doc.css(".number_box span")
```
出力結果

```
<span>18</span>
```

件数を取れました。
他の県のページを確認しても同じフォーマットなので、この処理を繰り返すために各都道府県のURLを収集します。

```rb
# coding: utf-8
require 'open-uri'
require 'nokogiri'

URL = "http://www.apahotel.com/hotel"
doc = Nokogiri::HTML(open(URL), nil, 'utf-8')
puts doc.css(".side_hotel_search li a")
```
出力結果

```
<a href="/hotel/hokkaido/">北海道エリア</a>
<a href="javascript:void(0)">東北エリア</a>
<a href="/hotel/miyagi/">宮城県</a>
<a href="/hotel/yamagata/">山形県</a>
<a href="/hotel/fukushima/">福島県</a>
<a href="/hotel/aomori/">青森県</a>
<a href="/hotel/iwate/">岩手県</a>
<a href="/hotel/akita/">秋田県</a>
<a href="javascript:void(0)">甲信越エリア</a>
<a href="/hotel/niigata/">新潟県</a>
<a href="/hotel/nagano/">長野県</a>
<a href="/hotel/yamanashi/">山梨県</a>
<a href="javascript:void(0)">首都圏エリア</a>
<a href="/hotel/tokyo/">東京都</a>
<a href="/hotel/kanagawa/">神奈川県</a>
<a href="/hotel/chiba/">千葉県</a>
<a href="/hotel/saitama/">埼玉県</a>
<a href="/hotel/tochigi/">栃木県</a>
<a href="/hotel/gunma/">群馬県</a>
<a href="/hotel/ibaraki/">茨城県</a>
<a href="javascript:void(0)">東海エリア</a>
<a href="/hotel/aichi/">愛知県</a>
<a href="/hotel/gifu/">岐阜県</a>
<a href="/hotel/shizuoka/">静岡県</a>
<a href="/hotel/mie/">三重県</a>
<a href="javascript:void(0)">北陸エリア</a>
<a href="/hotel/ishikawa/">石川県</a>
<a href="/hotel/fukui/">福井県</a>
<a href="/hotel/toyama/">富山県</a>
<a href="javascript:void(0)">関西エリア</a>
<a href="/hotel/osaka/">大阪府</a>
<a href="/hotel/hyogo/">兵庫県</a>
<a href="/hotel/wakayama/">和歌山県</a>
<a href="/hotel/kyoto/">京都府</a>
<a href="/hotel/nara/">奈良県</a>
<a href="/hotel/shiga/">滋賀県</a>
<a href="javascript:void(0)">中国エリア</a>
<a href="/hotel/hiroshima/">広島県</a>
<a href="/hotel/okayama/">岡山県</a>
<a href="/hotel/yamaguchi/">山口県</a>
<a href="/hotel/tottori/">鳥取県</a>
<a href="/hotel/shimane/">島根県</a>
<a href="javascript:void(0)">四国エリア</a>
<a href="/hotel/kagawa/">香川県</a>
<a href="/hotel/tokushima/">徳島県</a>
<a href="/hotel/kochi/">高知県</a>
<a href="/hotel/ehime/">愛媛県</a>
<a href="javascript:void(0)">九州・沖縄エリア</a>
<a href="/hotel/fukuoka/">福岡県</a>
<a href="/hotel/saga/">佐賀県</a>
<a href="/hotel/nagasaki/">長崎県</a>
<a href="/hotel/kumamoto/">熊本県</a>
<a href="/hotel/oita/">大分県</a>
<a href="/hotel/miyazaki/">宮崎県</a>
<a href="/hotel/kagoshima/">鹿児島県</a>
<a href="/hotel/okinawa/">沖縄県</a>
<a href="http://www.apahotelwoodbridge.com/default-ja.html" target="_blank">アメリカ</a>
<a href="/hotel/new_hotel/">新規開業ホテル</a>
<a href="/hotel/partners/">アパパートナーホテルズ一覧</a>
<a href="/hotel/renewal/">リニューアルホテル</a>
```

リストにできそうなものが取れました。
これをループさせて、 href の value を取得してURLリストを作ります。

```rb
# coding: utf-8
require 'open-uri'
require 'nokogiri'

URL = "http://www.apahotel.com/hotel"
doc = Nokogiri::HTML(open(URL), nil, 'utf-8')
doc.css(".side_hotel_search li a").each do |row|
  href_value = row.attribute("href").value
  p href_value
end
```
出力結果

```
"/hotel/hokkaido/"
"javascript:void(0)"
"/hotel/miyagi/"
"/hotel/yamagata/"
"/hotel/fukushima/"
"/hotel/aomori/"
"/hotel/iwate/"
"/hotel/akita/"
"javascript:void(0)"
"/hotel/niigata/"
"/hotel/nagano/"
"/hotel/yamanashi/"
"javascript:void(0)"
"/hotel/tokyo/"
"/hotel/kanagawa/"
"/hotel/chiba/"
"/hotel/saitama/"
"/hotel/tochigi/"
"/hotel/gunma/"
"/hotel/ibaraki/"
"javascript:void(0)"
"/hotel/aichi/"
"/hotel/gifu/"
"/hotel/shizuoka/"
"/hotel/mie/"
"javascript:void(0)"
"/hotel/ishikawa/"
"/hotel/fukui/"
"/hotel/toyama/"
"javascript:void(0)"
"/hotel/osaka/"
"/hotel/hyogo/"
"/hotel/wakayama/"
"/hotel/kyoto/"
"/hotel/nara/"
"/hotel/shiga/"
"javascript:void(0)"
"/hotel/hiroshima/"
"/hotel/okayama/"
"/hotel/yamaguchi/"
"/hotel/tottori/"
"/hotel/shimane/"
"javascript:void(0)"
"/hotel/kagawa/"
"/hotel/tokushima/"
"/hotel/kochi/"
"/hotel/ehime/"
"javascript:void(0)"
"/hotel/fukuoka/"
"/hotel/saga/"
"/hotel/nagasaki/"
"/hotel/kumamoto/"
"/hotel/oita/"
"/hotel/miyazaki/"
"/hotel/kagoshima/"
"/hotel/okinawa/"
"http://www.apahotelwoodbridge.com/default-ja.html"
"/hotel/new_hotel/"
"/hotel/partners/"
"/hotel/renewal/"
```
URL以外のものと、47都道府県以外のリンクが混じっているので、これを取り除きます。

```rb
next if !(row.attribute("href").value.include?("hotel/"))
```

"hotel/" をリンクに含まない物は取得せずに next にします。

```rb
next if !(.include?())
```

これは ()内の文字列が含まれていない場合は next です。もう少しカッコいい書き方があったら教えて下さい。m(_ _)m

```rb
# coding: utf-8
require 'open-uri'
require 'nokogiri'

URL = "http://www.apahotel.com/hotel"
hotel_urls = []

doc = Nokogiri::HTML(open(URL), nil, 'utf-8')
doc.css(".side_hotel_search li a").each do |row|
  next if !(row.attribute("href").value.include?("hotel/"))
  href_value = row.attribute("href").value
  hotel_urls << "http://www.apahotel.com/#{href_value}"
end

puts hotel_urls
p hotel_urls.count
```
href_value を抽出してアパホテルのルートURLにくっつけて配列に入れます。
一応47都道府県取れてるか確認のため、配列の中身をカウント。

```
http://www.apahotel.com//hotel/hokkaido/
http://www.apahotel.com//hotel/miyagi/
http://www.apahotel.com//hotel/yamagata/
http://www.apahotel.com//hotel/fukushima/
http://www.apahotel.com//hotel/aomori/
http://www.apahotel.com//hotel/iwate/
http://www.apahotel.com//hotel/akita/
http://www.apahotel.com//hotel/niigata/
http://www.apahotel.com//hotel/nagano/
http://www.apahotel.com//hotel/yamanashi/
http://www.apahotel.com//hotel/tokyo/
http://www.apahotel.com//hotel/kanagawa/
http://www.apahotel.com//hotel/chiba/
http://www.apahotel.com//hotel/saitama/
http://www.apahotel.com//hotel/tochigi/
http://www.apahotel.com//hotel/gunma/
http://www.apahotel.com//hotel/ibaraki/
http://www.apahotel.com//hotel/aichi/
http://www.apahotel.com//hotel/gifu/
http://www.apahotel.com//hotel/shizuoka/
http://www.apahotel.com//hotel/mie/
http://www.apahotel.com//hotel/ishikawa/
http://www.apahotel.com//hotel/fukui/
http://www.apahotel.com//hotel/toyama/
http://www.apahotel.com//hotel/osaka/
http://www.apahotel.com//hotel/hyogo/
http://www.apahotel.com//hotel/wakayama/
http://www.apahotel.com//hotel/kyoto/
http://www.apahotel.com//hotel/nara/
http://www.apahotel.com//hotel/shiga/
http://www.apahotel.com//hotel/hiroshima/
http://www.apahotel.com//hotel/okayama/
http://www.apahotel.com//hotel/yamaguchi/
http://www.apahotel.com//hotel/tottori/
http://www.apahotel.com//hotel/shimane/
http://www.apahotel.com//hotel/kagawa/
http://www.apahotel.com//hotel/tokushima/
http://www.apahotel.com//hotel/kochi/
http://www.apahotel.com//hotel/ehime/
http://www.apahotel.com//hotel/fukuoka/
http://www.apahotel.com//hotel/saga/
http://www.apahotel.com//hotel/nagasaki/
http://www.apahotel.com//hotel/kumamoto/
http://www.apahotel.com//hotel/oita/
http://www.apahotel.com//hotel/miyazaki/
http://www.apahotel.com//hotel/kagoshima/
http://www.apahotel.com//hotel/okinawa/
http://www.apahotel.com//hotel/new_hotel/
http://www.apahotel.com//hotel/partners/
http://www.apahotel.com//hotel/renewal/
50
```
一番下3つは確認したらフォーマットも違っていて問題なさそうだったので今回はスルー。
このURLの配列を、先ほどの件数取得スクリプトとくっつけます。

```rb
# coding: utf-8
require 'open-uri'
require 'nokogiri'

URL = "http://www.apahotel.com/hotel/"
doc = Nokogiri::HTML(open(URL), nil, 'utf-8')
hotel_urls = []

doc.css(".side_hotel_search li a").each do |row|
  next if !(row.attribute("href").value.include?("hotel/"))
  href_value = row.attribute("href").value
  hotel_urls << "http://www.apahotel.com/#{href_value}"
end

sum = 0
hotel_urls.each do |hotel_url|
  sleep 1
  doc = Nokogiri::HTML(open(hotel_url), nil, 'utf-8')
  hotel_number = doc.css(".number_box span").text.to_i
  p hotel_number
  sum += hotel_number
end
puts "合計"
puts sum + "件"
```
取得したURLリストのそれぞれのページからホテル件数を取ってきます。繰り返しアクセスするので、sleep を入れます。

```
18
4
2
3
7
3
2
9
6
2
43
8
7
7
5
4
4
13
2
11
4
11
3
6
18
10
1
8
1
5
2
5
3
2
1
6
2
3
4
6
4
5
2
4
5
6
3
0
0
0
合計
290件
```
これで合っているはず…。