ヤフオク等のECサイトからスクレイピング (ruby + Nokogiri)


※2019年9月時点のxpathなのでヤフオク側の変更のより取得できなくなるかもしれません。

ランサーズなどよく見るでヤフオク、amazon等のECサイトからの単純なデータ収集のお仕事。
プログラミングを使えば結構簡単にできちゃいます。
いわゆるスクレイピングっていう技術ですね。

今回は言語はruby、スクレイピングライブラリとしてNokogiriを使い、
ヤフオクの商品ページのタイトル、画像URL、価格などのデータを取得しcsvで出力します。

前提条件

rubyはインストール済み。

準備

まずNokogiri gemをインストール。

$ gem install nokogiri
Building native extensions. This could take a while...
Successfully installed nokogiri-1.10.4
Parsing documentation for nokogiri-1.10.4
Done installing documentation for nokogiri after 1 seconds
1 gem installed

続いてcsv gemをインストール

$ gem install csv
Successfully installed csv-3.1.1
Parsing documentation for csv-3.1.1
Done installing documentation for csv after 0 seconds
1 gem installed

準備完了!

rubyスクリプトを作成

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

 #取得したいURLを配列に格納する
urls = %w(
  https://page.auctions.yahoo.co.jp/jp/auction/r349735904
  https://page.auctions.yahoo.co.jp/jp/auction/v661258739
  https://page.auctions.yahoo.co.jp/jp/auction/s688301927
  https://page.auctions.yahoo.co.jp/jp/auction/j555196435
  https://page.auctions.yahoo.co.jp/jp/auction/v643884399
)

#取得したい値のxpathを格納する
xpaths = [
 '//h1[@class="ProductTitle__text"]',                      #商品名
 '//dd[@class="Price__value"]/text()',                     #現在価格
 '//dt[contains(text(),"入札件数")]/following-sibling::dd[1]/text()', #入札件数
 '//dt[contains(text(),"残り時間") and @class="Count__title"]/following-sibling::dd[1]/text()', #残り日数
 '//ul[@class="ProductImage__images"]/li[1]/div/img/@src', #画像1枚目
 '//ul[@class="ProductImage__images"]/li[2]/div/img/@src', #画像2枚目
 '//ul[@class="ProductImage__images"]/li[3]/div/img/@src', #画像3枚目
 '//ul[@class="ProductImage__images"]/li[4]/div/img/@src', #画像4枚目
 '//ul[@class="ProductImage__images"]/li[5]/div/img/@src', #画像5枚目
]

values = []
hash = {}
#csvで出力する際のヘッダーを格納
hash[0] = %w(商品名 現在価格 入札件数 残り日数 画像1 画像2 画像3 画像4 画像5)

i = 1
charset = nil
urls.each do |url|
  html = open(url) do |f|
    charset = f.charset
    f.read
  end

  doc = Nokogiri::HTML.parse(html, nil, charset)
  xpaths.each do |xp|
    node = doc.xpath(xp)
    value = node.inner_text.delete("\n").delete("円")
    values.push(value)
  end
  hash[i] = values
  i += 1
  values = []
end

 CSV.open("yahuoku.csv", "w") do |csv|
   hash.count.times do |i|
   csv.add_row(hash[i])
  end
 end

出力結果


※出力されたcsvファイルをグーグルスプレッドシートで開いています。

反省

機能はしますが、計算速度や読みやすさという点では改良の余地がかなりありますのでご了承ください。
改善点等ご指摘いただけたら大変助かります。

参考ページ

クローラ作成に必須!XPATHの記法まとめ - Qiita
Ruby + Nokogiriでスクレイピング - Qiita

補足

最近(2020/6月)このコードを実行してみたら、現在価格の取得がおかしくなってました。
おそらくヤフオク側の仕様変更だと思われます。
そのうち修正します。