69
62

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

IKEAの在庫情報をRubyで取り出す

Last updated at Posted at 2019-05-04

#概要
IKEA在庫管理のURLから取得したXMLを処理して情報を抽出します。簡単。

#背景
最近、巷で人気(多分今も)のIKEAのサメが欲しかったが、在庫はいつも品切れ・・・今日も在庫確認の為にサイトをポチポチ・・・
ある日手が滑ってたまたまChromeの検証を押してしまいたまたまNetworkを見てたらIKEAの製品の在庫数がわかるURLを発見したので、IKEAのサメの在庫監視サイトを作りました。題してIKEAの在庫わかる君

#作ってみる

###事前準備
nokogiriをインストール(rails環境なら既にある)
$ gem install nokogiri

###とりあえずサンプル
ここのIKEAのサメの在庫情報にアクセスするとこんな感じでXMLが得られます。

image.png

CLIで在庫情報や次回入荷日(再補充日?)を抽出します

ikea.rb
require 'nokogiri'
require 'open-uri'
# url末尾の8桁の数字は商品番号
url = 'https://www.ikea.com/jp/ja/iows/catalog/availability/10373589'

xml = Nokogiri::XML(open(url).read)

STORE_NAME = { "447" => "船橋", "448" => "港北", "887" => "新三郷",
               "486" => "神戸", "392" => "仙台", "509" => "長久手",
               "496" => "鶴浜", "189" => "福岡新宮", "359" => "立川" }

# XMLのルートのノードから探して一致したNodeSetオブジェクトを返す→9店舗分のlocalStoreを取得
item_nodes = xml.xpath('//availability/localStore')

item_nodes.each do |item|
  # attribute('xx')でlocalStoreのxx属性の属性値を取得
  store_code = item.attribute('buCode').text
  puts "店名:#{STORE_NAME[store_code]}(#{store_code})"
  # localStore以下のstockノードを探してNodeSetで返す
  item.xpath('stock').each do |store|
    puts '在庫数:' + store.xpath('availableStock').text
    if store.xpath('restockDate').any?
      puts '次回入荷日:' + store.xpath('restockDate').text
    else
      puts '次回入荷日:不明'
    end
  end
  puts "-------------------------"
end

動かしてみる
image.png

できた!!

#簡単に解説
open(url).readでurlのレスポンスのボディ部分を文字列で取得

Nokogiri::XML(open(url).read)でボディ部分の文字列から
Nokogiri::XML::Documentオブジェクトを生成

xml.xpath('//availability/localStore')Nokogiri::XML::NodeSetという配列のようなオブジェクトを取得。これで処理したい対象のデータ達を抽出できた

image.png

また、xpathメソッドの使い方は、今回のようにxpath('//hoge')で大元からデータを探し、NodeSetオブジェクトに対しさらにxpath('piyo')をすると、一段下のpiyo要素が得られる

NodeSetの中にはNokogiri::XML::Elementオブジェクトが格納されている

> item_nodes[1].class
=> Nokogiri::XML::Element

Elementオブジェクトに対してattribute('buCode')で属性名と属性が格納されたAttrオブジェクトを取得し、Attrにtextメソッドを呼び出すと属性値が取り出せる

> item_nodes[1].attribute('buCode')
=> #(Attr:0x3663e58 { name = "buCode", value = "448" })
> item_nodes[1].attribute('buCode').text
=> "448" #店舗コード

同様に、Elementにtextメソッドを呼び出すとタグ内の値を呼び出せる

> item_nodes[0].xpath('stock')[0].xpath('availableStock').text
=> "73" #執筆時のIKEA船橋店のサメの在庫数

#終わりに
後でQiitaで検索してみるとIKEAの在庫確認している記事がけっこう見つかりました。考えることは一緒ですね。
そして自分は未だにIKEAのサメをお迎えできていません。。。

10/28日追記

この前IKEAのサメちゃんをおうちに迎え入れることができました🦈🎉

#参考サイト
https://dev.classmethod.jp/tool/xmlnokogiri-xml-parse/
http://d.hatena.ne.jp/fre_oik/20110609/1307627018

69
62
1

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
69
62

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?