AmazonベストセラーのRSSを読み込んでJSONファイルに出力する
RubyでRSSを読み込んでJSONファイルに出力する方法です。
読み込むのはAmazonベストセラーのRSSです。毎回RSSを読み込むと時間がかかるのでDBやファイルとしてローカルに保存するのが普通だと思いますが、今回はJSONファイルに読み込んだデータを格納します。
流れとしてはopen-uriを使って指定したURLへアクセスし、読み込んだXMLをNokogiriで解析します。
また、「https」でアクセスする場合、上記だけでは証明書の検証に失敗してファイルを読み込めないようなので、opensslの「ssl_verify_mode」を切り替えて実行します。詳しくはこちら([Ruby] open-uri の HTTPS リクエストで certificate verify failed | mofu犬blog)を参照。
目次
- Nokogiriのインストール
- コード
- 実際に出力されるデータ
- 参考リンク
Nokogiriのインストール
opne-uriとopnesslは標準ライブラリに含まれているので、Nokogiriだけインストールします。
gem install nokogiri
コード
以下は、Amazonベストセラーの「バイクヘルメット」と「バイクウェア、プロテクション」の2つのRSSを読み込んで、それぞれを別のJSONファイルとして出力するコードです。
require 'nokogiri'
require 'open-uri'
require 'openssl'
require 'json'
rss_list = [
{:category => 'helm', :url => 'https://www.amazon.co.jp/gp/rss/bestsellers/automotive/2045145051/ref=zg_bs_2045145051_rsslink'}, # バイクヘルメット
{:category => 'wear', :url => 'https://www.amazon.co.jp/gp/rss/bestsellers/automotive/2045156051/ref=zg_bs_2045156051_rsslink'}, # バイクウェア、プロテクション
]
rss_list.each do |rss|
# RSSの読み込み
rss_xml = Nokogiri::XML(open(rss[:url], :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE).read)
data = {}
channel = rss_xml.xpath('/rss/channel')
data[:title] = channel.xpath('title').text
data[:link] = channel.xpath('link').text
data[:public_date] = channel.xpath('pubDate').text
data[:last_build_date] = channel.xpath('lastBuildDate').text
products = []
rss_xml.xpath('//item').each do |item|
product = {}
content = item.xpath('description').text
# 商品URL
product[:url] = item.xpath('link').text.strip
# 商品名
product[:name] = ''
matches = content.match(/<span class\=\"riRssTitle\"><a href\=\".*?\">(.*?)<\/a><\/span>/);
if (matches && matches.size > 1)
product[:name] = matches[1]
end
# 投稿者
product[:contributor] = ''
matches = content.match(/<span class\=\"riRssContributor\">(.*?)<\/span>/);
if (matches && matches.size > 1)
product[:contributor] = matches[1].strip
end
# レビュースコア、件数
product[:review_score_url] = ''
product[:review_count] = ''
matches = content.match(/<span class\=\"riRssContributor\">.*?<\/span>.*?<img src\=\"(.*?)\".*?\/>(.*?)<br \/>/);
if (matches && matches.size > 2)
product[:review_score_url] = matches[1]
product[:review_count] = matches[2]
end
# 元々の価格
product[:price_org] = ''
matches = content.match(/<strike>(.*?)<\/strike>/);
if (matches && matches.size > 1)
product[:price_org] = matches[1]
end
# 実際の価格
product[:price_act] = ''
matches = content.match(/<font.*?><b>(.*?)<\/b><\/font>/);
if (matches && matches.size > 1)
product[:price_act] = matches[1]
end
# イメージURL
matches = content.match(/<a class\=\"url\".*?<img src=\"(.*?)\"/)
if(matches && matches.size > 1)
product[:image_url] = matches[1]
end
products.push(product)
end
data[:products] = products
# JSONファイルの作成
file_path = "/var/www/example/bestseller/" + rss[:category] + ".json"
File.open(file_path, "w") do |file|
file.puts(data.to_json(:root => false))
end
end
実際に出力されるデータ
上記のコードを実行すると以下のようなJSONファイル(helm.json)が作成されます。
{
"title": "Amazon.co.jp: 車&バイク > ヘルメットのベストセラー",
"link": "https://www.amazon.co.jp/gp/bestsellers/automotive/2045145051/ref=pd_zg_rss_ts_auto_2045145051_c",
"public_date": "Tue, 4 Apr 2017 05:48:58 GMT",
"last_build_date": "Tue, 4 Apr 2017 05:48:58 GMT",
"products": [{
"url": "https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%89%E5%B7%A5%E6%A5%AD-%E3%83%90%E3%82%A4%E3%82%AF%E3%83%98%E3%83%AB%E3%83%A1%E3%83%83%E3%83%88-%E3%83%9E%E3%83%83%E3%83%88%E3%83%96%E3%83%A9%E3%83%83%E3%82%AF-61~62cm%E6%9C%AA%E6%BA%80-RE41/dp/B00LAQ76R8/ref=pd_zg_rss_ts_auto_2045145051_1",
"name": "リード工業 バイクヘルメット ハーフ シールド付 マットブラック LLサイズ 61~62cm未満 RE41",
"contributor": "LEAD",
"review_score_url": "https://images-fe.ssl-images-amazon.com/images/G/09/detail/stars-4-0._CB192252995_.gif",
"review_count": "(56)",
"price_org": "¥ 6,804",
"price_act": "¥ 3,790",
"image_url": "https://images-fe.ssl-images-amazon.com/images/I/41AUvMsye-L._SL160_.jpg"
},
...
]
}