LoginSignup
6
7

More than 5 years have passed since last update.

nokogiriをつかってリンクを取得

Last updated at Posted at 2016-11-30

やりたいこと

エレキギター本体 ストア一覧から店舗リンクを取得したい。

実行準備

初期セットアップは参考にしたリンクを参照。

test.rake
require 'open-uri'
require 'nokogiri'

namespace :scrape do
  desc"店舗一覧ページから店舗リンクを取得テスト"
  task :scrape_shop_links => :environment do
    url = "http://shopping.yahoo.co.jp/category/2510/2327/45931/45933/stores/"
    charset = nil
    html = open(url) do |f|
      charset = f.charset
      f.read
    end

    doc = Nokogiri::HTML.parse(html, nil, charset)
    shops = doc.css(".elMain")
    #shop_list = shops.css("li")
    count = 0
    data = []
    shops.each do |shop|
      count += 1
      url = shop.css("a")[0][:href]
      name = shop.css("span.elStoreName")[0]
      puts url, name
    end
  end
end

アウトプットが

javascript:void(0);

http://store.shopping.yahoo.co.jp/aoupprcgigiwgd7i6y2ztfylwi/
<span class="elStoreName">AステージYahoo!店</span>
http://store.shopping.yahoo.co.jp/apollon/
<span class="elStoreName">あぽろんYahoo!店</span>
http://store.shopping.yahoo.co.jp/lostboys-guitars/
<span class="elStoreName">Unlimited Guitars</span>
http://store.shopping.yahoo.co.jp/unliminet/
<span class="elStoreName">UNLIMINET</span>
http://store.shopping.yahoo.co.jp/e-yoshiyagakki/
<span class="elStoreName">e-よしや楽器</span>
http://store.shopping.yahoo.co.jp/ikebe/
<span class="elStoreName">イケベ楽器店</span>
http://store.shopping.yahoo.co.jp/ikebe-revole/
<span class="elStoreName">イケベ楽器リボレ秋葉原店</span>
http://store.shopping.yahoo.co.jp/ishibashi/
<span class="elStoreName">イシバシ楽器</span>
http://store.shopping.yahoo.co.jp/ishibashi-shops/
<span class="elStoreName">イシバシ楽器 17ショップス</span>
http://store.shopping.yahoo.co.jp/illusion/
<span class="elStoreName">一期一会本舗 ギター初心者も安心</span>
http://store.shopping.yahoo.co.jp/itogakki/
<span class="elStoreName">伊藤楽器</span>
http://store.shopping.yahoo.co.jp/wizard-leather/
<span class="elStoreName">WIZARD LEATHER</span>
http://store.shopping.yahoo.co.jp/wavehouse/
<span class="elStoreName">WaveHouse</span>
http://store.shopping.yahoo.co.jp/alien-soundworks/
<span class="elStoreName">Alien Soundworks</span>
http://store.shopping.yahoo.co.jp/sgtech/
<span class="elStoreName">エスジーテクノロジーズ</span>
http://store.shopping.yahoo.co.jp/music-kingdom/
<span class="elStoreName">エレキギター 初心者セット音楽堂</span>
http://store.shopping.yahoo.co.jp/ebisound/
<span class="elStoreName">エレキギターとウクレレのEbiSound</span>
http://store.shopping.yahoo.co.jp/sound-station/
<span class="elStoreName">エレキギターのSOUND STATION</span>
http://store.shopping.yahoo.co.jp/audio-mania/
<span class="elStoreName">Audio Mania</span>
http://store.shopping.yahoo.co.jp/owariya-gakki/
<span class="elStoreName">おかげ様で創業104年オワリヤ楽器</span>
http://store.shopping.yahoo.co.jp/funhoused/
<span class="elStoreName">音楽屋ファンハウス</span>
http://store.shopping.yahoo.co.jp/sendaiguitar/
<span class="elStoreName">音色研究会</span>
http://store.shopping.yahoo.co.jp/on-you-music/
<span class="elStoreName">オンユー楽器・ヤフー店</span>
http://store.shopping.yahoo.co.jp/gakki-de-genki/
<span class="elStoreName">楽器de元気</span>
http://store.shopping.yahoo.co.jp/crossroad-oyama/
<span class="elStoreName">楽器店 CROSSROAD</span>
http://store.shopping.yahoo.co.jp/gakki/
<span class="elStoreName">楽器天国</span>
http://store.shopping.yahoo.co.jp/manmandougakki/
<span class="elStoreName">楽器店まんまん堂</span>
http://store.shopping.yahoo.co.jp/rotomusic/
<span class="elStoreName">楽器の買取販売 ロトミュージック</span>
http://store.shopping.yahoo.co.jp/okumuragakki/
<span class="elStoreName">楽器の総合デパート オクムラ楽器</span>
http://store.shopping.yahoo.co.jp/gakki-mori/
<span class="elStoreName">楽器の森</span>
http://store.shopping.yahoo.co.jp/g-monogatari/
<span class="elStoreName">楽器モノガタリ</span>
http://store.shopping.yahoo.co.jp/g-sakai/
<span class="elStoreName">楽器屋のSAKAI</span>
http://store.shopping.yahoo.co.jp/gakkiland-thanks/
<span class="elStoreName">楽器ランド サンクス</span>
http://store.shopping.yahoo.co.jp/musicgear/
<span class="elStoreName">KANAZAWA TK</span>
http://store.shopping.yahoo.co.jp/suwano/
<span class="elStoreName">株式会社 木下楽器店</span>
http://store.shopping.yahoo.co.jp/jd52k3mnwfd5sap7qlk4eugtee/
<span class="elStoreName">Guitarshopabc</span>
http://store.shopping.yahoo.co.jp/guitarplanet/
<span class="elStoreName">ギタープラネット Yahoo!ショップ</span>
http://store.shopping.yahoo.co.jp/gwnn/
<span class="elStoreName">Guitar Proshop GWNN ネットストア</span>
http://store.shopping.yahoo.co.jp/kurosawa-unplugged/
<span class="elStoreName">GUITAR MUSEUM</span>
http://store.shopping.yahoo.co.jp/cfhnjs2sr46pd23uzihqf7vtkq/
<span class="elStoreName">Good Guitars</span>
http://store.shopping.yahoo.co.jp/groovemusic/
<span class="elStoreName">グルーヴミュージックストア</span>
http://store.shopping.yahoo.co.jp/grace-music-store/
<span class="elStoreName">Graceミュージックストア ヤフー店</span>
http://store.shopping.yahoo.co.jp/kurosawashibuya/
<span class="elStoreName">クロサワ楽器店G-CLUB渋谷</span>
http://store.shopping.yahoo.co.jp/honten/
<span class="elStoreName">クロサワ楽器 日本総本店 WEBSHOP</span>
http://store.shopping.yahoo.co.jp/ksound-yh/
<span class="elStoreName">Ksound Yahoo!ショッピング SHOP</span>
http://store.shopping.yahoo.co.jp/genzovintageguitars/
<span class="elStoreName">GENZO VINTAGE GUITARS</span>
http://store.shopping.yahoo.co.jp/koeido1/
<span class="elStoreName">光栄堂楽器Yahoo!店</span>
http://store.shopping.yahoo.co.jp/koyogakki/
<span class="elStoreName">光洋楽器</span>
http://store.shopping.yahoo.co.jp/cocosoundweb/
<span class="elStoreName">COCOSOUND Yahoo!ショップ</span>
http://store.shopping.yahoo.co.jp/cosmogakki/
<span class="elStoreName">コスモ楽器</span>

javascript:void(0);をどうにかするのと、spanタグからテキストだけを摘出しなければ。。。

出力データの整形

Webスクレイピングを用いたデータ検索クローラ構築入門を参考にしながら

test.rake
require 'open-uri'
require 'nokogiri'

namespace :scrape do
  desc"店舗一覧ページから店舗リンクを取得テスト"
  task :scrape_shop_links => :environment do
    url = "http://shopping.yahoo.co.jp/category/2510/2327/45931/45933/stores/"
    charset = nil
    html = open(url) do |f|
      charset = f.charset
      f.read
    end

    doc = Nokogiri::HTML.parse(html, nil, charset)
    shops = doc.css(".elMain")
    #shop_list = shops.css("li")
    count = 0
    data = []
    shops.each do |shop|
      count += 1
      url = shop.css("a")[0][:href]
      name = shop.css("span.elStoreName").text
      puts "name: #{name}, url: #{url}"
    end
  end
end

name = shop.css("span.elStoreName")[0].text
と入力するとNoMethodError: undefined method 'text' for nil:NilClassと言われ怒られてしまう。なぜだろうか。。

上にも記述したが、name = shop.css("span.elStoreName")[0]span.elStoreNameタグのついた最初の要素を取ってくる。

<span class="elStoreName">愛曲楽器 桜山本店</span>
<span class="elStoreName">AステージYahoo!店</span>
<span class="elStoreName">あぽろんYahoo!店</span>
<span class="elStoreName">Unlimited Guitars</span>
<span class="elStoreName">UNLIMINET</span>
<span class="elStoreName">e-よしや楽器</span>
<span class="elStoreName">イケベ楽器店</span>
<span class="elStoreName">イケベ楽器リボレ秋葉原店</span>
<span class="elStoreName">イシバシ楽器</span>
<span class="elStoreName">イシバシ楽器 17ショップス</span>
<span class="elStoreName">一期一会本舗 ギター初心者も安心</span>
<span class="elStoreName">伊藤楽器</span>
<span class="elStoreName">WIZARD LEATHER</span>
<span class="elStoreName">WaveHouse</span>
<span class="elStoreName">Alien Soundworks</span>
<span class="elStoreName">エスジーテクノロジーズ</span>
<span class="elStoreName">MHJ Yahoo!店</span>
<span class="elStoreName">MGM楽器店</span>
<span class="elStoreName">エレキギター 初心者セット音楽堂</span>
<span class="elStoreName">Audio Mania</span>
<span class="elStoreName">オーディオ渡辺 ショッピング</span>
<span class="elStoreName">おかげ様で創業104年オワリヤ楽器</span>
<span class="elStoreName">音楽屋ファンハウス</span>
<span class="elStoreName">音色研究会</span>
<span class="elStoreName">オンユー楽器・ヤフー店</span>
<span class="elStoreName">楽器de元気</span>
<span class="elStoreName">楽器店 CROSSROAD</span>
<span class="elStoreName">楽器天国</span>
<span class="elStoreName">楽器店まんまん堂</span>
<span class="elStoreName">楽器の買取販売 ロトミュージック</span>
<span class="elStoreName">楽器の総合デパート オクムラ楽器</span>
<span class="elStoreName">楽器の森</span>
<span class="elStoreName">楽器モノガタリ</span>
<span class="elStoreName">楽器屋のSAKAI</span>
<span class="elStoreName">楽器ランド サンクス</span>
<span class="elStoreName">KANAZAWA TK</span>
<span class="elStoreName">株式会社 木下楽器店</span>
<span class="elStoreName">Guitarshopabc</span>
<span class="elStoreName">ギタープラネット Yahoo!ショップ</span>
<span class="elStoreName">Guitar Proshop GWNN ネットストア</span>
<span class="elStoreName">GUITAR MUSEUM</span>
<span class="elStoreName">Good Guitars</span>
<span class="elStoreName">グルーヴミュージックストア</span>
<span class="elStoreName">Graceミュージックストア ヤフー店</span>
<span class="elStoreName">クロサワ楽器店G-CLUB渋谷</span>
<span class="elStoreName">クロサワ楽器 日本総本店 WEBSHOP</span>
<span class="elStoreName">Ksound Yahoo!ショッピング SHOP</span>
<span class="elStoreName">GENZO VINTAGE GUITARS</span>
<span class="elStoreName">光栄堂楽器Yahoo!店</span>
<span class="elStoreName">光洋楽器</span>

一方でshop.css("span.elStoreName")が出すアウトプットもまるで変わりがない。

<span class="elStoreName">愛曲楽器 桜山本店</span>
<span class="elStoreName">AステージYahoo!店</span>
<span class="elStoreName">あぽろんYahoo!店</span>
<span class="elStoreName">Unlimited Guitars</span>
<span class="elStoreName">UNLIMINET</span>
<span class="elStoreName">e-よしや楽器</span>
<span class="elStoreName">イケベ楽器店</span>
<span class="elStoreName">イケベ楽器リボレ秋葉原店</span>
<span class="elStoreName">イシバシ楽器</span>
<span class="elStoreName">イシバシ楽器 17ショップス</span>
<span class="elStoreName">一期一会本舗 ギター初心者も安心</span>
<span class="elStoreName">伊藤楽器</span>
<span class="elStoreName">WIZARD LEATHER</span>
<span class="elStoreName">WaveHouse</span>
<span class="elStoreName">Alien Soundworks</span>
<span class="elStoreName">エスジーテクノロジーズ</span>
<span class="elStoreName">MHJ Yahoo!店</span>
<span class="elStoreName">MGM楽器店</span>
<span class="elStoreName">エレキギター 初心者セット音楽堂</span>
<span class="elStoreName">Audio Mania</span>
<span class="elStoreName">オーディオ渡辺 ショッピング</span>
<span class="elStoreName">おかげ様で創業104年オワリヤ楽器</span>
<span class="elStoreName">音楽屋ファンハウス</span>
<span class="elStoreName">音色研究会</span>
<span class="elStoreName">オンユー楽器・ヤフー店</span>
<span class="elStoreName">楽器de元気</span>
<span class="elStoreName">楽器店 CROSSROAD</span>
<span class="elStoreName">楽器天国</span>
<span class="elStoreName">楽器店まんまん堂</span>
<span class="elStoreName">楽器の買取販売 ロトミュージック</span>
<span class="elStoreName">楽器の総合デパート オクムラ楽器</span>
<span class="elStoreName">楽器の森</span>
<span class="elStoreName">楽器モノガタリ</span>
<span class="elStoreName">楽器屋のSAKAI</span>
<span class="elStoreName">楽器ランド サンクス</span>
<span class="elStoreName">KANAZAWA TK</span>
<span class="elStoreName">株式会社 木下楽器店</span>
<span class="elStoreName">Guitarshopabc</span>
<span class="elStoreName">ギタープラネット Yahoo!ショップ</span>
<span class="elStoreName">Guitar Proshop GWNN ネットストア</span>
<span class="elStoreName">GUITAR MUSEUM</span>
<span class="elStoreName">Good Guitars</span>
<span class="elStoreName">グルーヴミュージックストア</span>
<span class="elStoreName">Graceミュージックストア ヤフー店</span>
<span class="elStoreName">クロサワ楽器店G-CLUB渋谷</span>
<span class="elStoreName">クロサワ楽器 日本総本店 WEBSHOP</span>
<span class="elStoreName">Ksound Yahoo!ショッピング SHOP</span>
<span class="elStoreName">GENZO VINTAGE GUITARS</span>
<span class="elStoreName">光栄堂楽器Yahoo!店</span>
<span class="elStoreName">光洋楽器</span>

ということはname = shop.css("span.elStoreName")[0].textは今回のケースにおいては形式上とってこれないのではと推測するのが安全そう。

javascript:void(0);を取り除く

XPath の関数を使った Web スクレイピングに記載されているような方法も試したのですがいまいちうまくいかなかったので将来的な利便性は低いですがべた書きで取り除いていくことにしました。

test.rake
require 'open-uri'
require 'nokogiri'

namespace :scrape do
  desc"店舗一覧ページから店舗リンクを取得テスト"
  task :scrape_shop_links => :environment do
    url = "http://shopping.yahoo.co.jp/category/2510/2327/45931/45933/stores/"
    charset = nil
    html = open(url) do |f|
      charset = f.charset
      f.read
    end

    doc = Nokogiri::HTML.parse(html, nil, charset)
    shops = doc.css(".elMain")
    shops_main = shops.search('//a[starts-with(@href, "http://")]')
    count = 0
    data = []
    shops.each do |shop|
      url = shop.css("a")[0][:href]
      next if url == "javascript:void(0);"
      count += 1
      name = shop.css("span.elStoreName").text
      puts "#{count}, name: #{name}, url: #{url}"
    end
  end
end

追記

okkez@github様よりもっと短く作れるとのアドバイスをいただきました。量的には半分以下になります。ご教授頂きありがとうございました。

test.rake
require "open-uri"
require "nokogiri"

desc "scrapint testだよおおおおお"
task :test_scrape => :environment do  
  html = open("http://shopping.yahoo.co.jp/category/2510/2327/45931/45933/stores/")
  doc = Nokogiri::HTML(html)
  doc.search(".mdStoreList div.elItem > ul > li").each do |element|
    p [element.at("a.elStore")["href"], element.at("span.elStoreName").inner_text]
  end
end

参考にしたリンク

6
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7