LoginSignup
26
21

More than 5 years have passed since last update.

【Ruby】 gem Nokogiri を使ったスクレイピングのやり方

Last updated at Posted at 2015-12-17

Nokogiri便利ですね。
今回は某コンビニののホームページから店舗名と住所をcsvに書き出す処理を行いたいと思います。
今回は基本的な使い方だと思います。

gem 「Nokogiri」のインストール

gem install nokogiri

まずは正しく読み込めるか確認

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

url = "http://store.lawson.co.jp/store/243168/" # 対象店舗のURL
doc = Nokogiri::HTML(open(url)) # urlの読み込み

p doc.css('h3#pr_store').inner_text # 店舗名の出力
p doc.css('td#pr_address').inner_text # 住所の出力

無事にサンプルに選んだ店舗名と住所が出力されました。
cssセレクタやXPath(今回は未使用ですが)については下記ページが参考になりました。
Nokogiri の基本(翻訳版)

csvへの書き込み

test2.rb
require 'open-uri'
require 'nokogiri'
require 'csv'

CSV.open("list.csv", "w") do |csv|
  url = "http://store.lawson.co.jp/store/243168/" # 対象店舗のURL
  doc = Nokogiri::HTML(open(url)) # urlの読み込み

  p doc.css('h3#pr_store').inner_text # 店舗名の出力
  p doc.css('td#pr_address').inner_text # 住所の出力
  csv << [shop, address] # csvへの書き込み
end

サンプルに選んだ店舗名と住所がcsvファイルに書き込みされることが確認できました。
最後に、全店舗をcsvに書き出す方法も考えてみたいと思います。

全店舗をcsvに出力

[重要]コメントで数点ご指摘を頂いているので、必ずご確認ください
[重要]特にsleep処理が行われていないので、下記のままコードを使用しないでください

URLの最後の6桁がそれぞれの店舗ページへのパスになっています。
ただし、000000から999999までの全てにリンクがあるわけではなく、404ページも存在するため、繰り返しに加えて例外処理も記載します。

scraping.rb
require 'open-uri'
require 'nokogiri'
require 'csv'

CSV.open("list.csv", "w") do |csv|
  for path in 000000..999999 do # 繰り返し処理
    url = "http://store.lawson.co.jp/store/#{path}/" 
    # 例外処理
    begin
      html = Nokogiri::HTML(open(url))
    rescue
      next
    end

    shop =  html.css('h3#pr_store').inner_text
    address = html.css('td#pr_address').inner_text
    csv << [shop, address]
  end
end

これで、全店舗の店舗名と住所がcsvに出力されました。

[追記]下記の方が望ましい処理だと思われます

require 'open-uri'
require 'nokogiri'
require 'csv'

CSV.open("list.csv", "w") do |csv|
  for path in 100000..150000 do 
    url = "http://store.lawson.co.jp/store/#{path}/"
    begin
      _html = open(url)
    rescue OpenURI::HTTPError
      sleep 1
      next
    end
    doc = Nokogiri::HTML(_html)

    shop =  doc.css('h3#pr_store').inner_text
    address = doc.css('td#pr_address').inner_text
    csv << [shop, address]
    sleep 1
  end
end

おわりに

例外処理の部分で、多分もっと高速な書き方があるはず。
今回は妥協します。

26
21
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
26
21