2010年8月 のアーカイブ

EC-CUBEの商品登録CSVデータを生成するRubyスクリプト

2010年8月31日 火曜日

こんばんは。

EC-CUBE用のテストデータを登録するためのCSVファイルを作る必要があって、簡単なスクリプト書いたので公開しておきます。

今回は、楽天ランキングAPIのデータを使ってテストデータのCSVを作成し、EC-CUBEのテストデータとして登録する手順を紹介します。
間違ってもそのまま公開しないように!

EC-CUBEのWeb管理ツールで手動でカテゴリ登録する

まず、EC-CUBEのWeb管理ツールでカテゴリを一つたとえば「ゴルフ」を手動で登録します。
登録したカテゴリのIDを管理ツール上で確認します。
ここでは「ゴルフ」のカテゴリIDが「5」だったとします。

楽天ジャンルIDの取得する

楽天のジャンル一覧で「ゴルフ」のジャンルIDを確認します。
ゴルフのジャンルIDは「101077」でした。
楽天ジャンルID(genreId)検索

必要なコードを準備

Simple JSON parser & builder
以下のサイトからJSON解析スクリプトをダウンロードし「jsonparser.rb」とします。ここにも置いておきます。
http://rubyforge.org/snippet/detail.php?type=snippet&id=148
httpclient
画像ファイルを取得するのにhttpclientを利用しているのでインストールします。

$ sudo gem install httpclient

以下のrubyスクリプトをコピーして適当な名前で保存します。
ここでは「itemgen.rb」とします。
ざっくしとした説明です。

  • setupメソッドでIDで設定を行う
  • csv_formatメソッドでCSV形式を定義する
  • rewriteメソッドでCSVの内容を定義する
$KCODE='u'
require 'rubygems'
require 'httpclient'
require 'open-uri'
require 'kconv'
require 'jsonparser.rb'
require "fileutils"
require 'jcode'
 
# 初期設定
def setup
  $developer_id = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'  # APIのためのデベロッパID
  $img_dir = 'img'                         # 画像保存ディレクトリ名
  $item_csv_filename = "item.csv"   # 商品CSVファイル名
  $genre_id = ARGV[0]                  # 楽天ジャンルID
  $category_id = ARGV[1]             # カテゴリID
  $max_page = ARGV[2]               # 取得ページ数(1ページ30商品で10ページまであるらしい)
end
 
# CVSフォーマット(HashをsortしてArray返してるので注意)
def csv_format
  {
    0 =>  "商品ID",
    1 => "商品規格ID",
    2 => "規格名1",
    3 => "規格名2",
    4 => "商品名(必須)",
    5 => "公開フラグ(1:公開 2:非公開)(必須)",
    6 => "商品ステータス(必須)",
    7 => "商品コード",
    8 => "通常価格 ",
    9 => "販売価格(必須)",
    10 =>"在庫数",
    11 =>"送料",
    12 =>"ポイント付与率(必須)",
    13 =>"購入制限",
    14 =>"メーカーURL",
    15 =>"検索ワード",
    16 =>"備考欄(SHOP専用)",
    17 =>"一覧-メインコメント(必須)",
    18 =>"一覧-メイン画像(必須)",
    19 =>"メインコメント(必須)",
    20 =>"メイン画像(必須)",
    21 =>"メイン拡大画像",
    22 =>"カラー比較画像",
    23 =>"商品詳細ファイル",
    24 =>"詳細-サブタイトル(1)",
    25 =>"詳細-サブコメント(1)",
    26 =>"詳細-サブ画像(1)",
    27 =>"詳細-サブ拡大画像(1)",
    28 =>"詳細-サブタイトル(2)",
    29 =>"詳細-サブコメント(2)",
    30 =>"詳細-サブ画像(2)",
    31 =>"詳細-サブ拡大画像(2)",
    32 =>"詳細-サブタイトル(3)",
    33 =>"詳細-サブコメント(3)",
    34 =>"詳細-サブ画像(3)",
    35 =>"詳細-サブ拡大画像(3)",
    36 =>"詳細-サブタイトル(4)",
    37 =>"詳細-サブコメント(4)",
    38 =>"詳細-サブ画像(4)",
    39 =>"詳細-サブ拡大画像(4)",
    40 =>"詳細-サブタイトル(5)",
    41 =>"詳細-サブコメント(5)",
    42 =>"詳細-サブ画像(5)",
    43 =>"詳細-サブ拡大画像(5)",
    44 =>"発送日目安",
    45 =>"おすすめ商品(1)",
    46 =>"詳細-サブコメント(1)",
    47 =>"おすすめ商品(2)",
    48 =>"詳細-サブコメント(2)",
    49 =>"おすすめ商品(3)",
    50 =>"詳細-サブコメント(3)",
    51 =>"おすすめ商品(4)",
    52 =>"詳細-サブコメント(4)",
    53 =>"おすすめ商品(5)",
    54 =>"詳細-サブコメント(5)",
    55 =>"おすすめ商品(6)",
    56 =>"詳細-サブコメント(6)",
    57 =>"商品カテゴリ(必須)"
  }.sort_by{|k,v|k}
end
 
# CSVの値を定義(フォーマットの列番号に対応。xにはAPIで取得したitemが入る)
def rewrite
  {
    4  =>lambda{|x| cut_off(x["itemName"].to_s.toutf8.gsub(/【.[^【]*/, '').gsub("楽天",''),45)}, #【】は取る
    5  =>lambda{|x| "1"},
    6  =>lambda{|x| "0"},
    7  =>lambda{|x| x["itemCode"]},
    9  =>lambda{|x| x["itemPrice"]},
    10 =>lambda{|x| "20"},
    12 =>lambda{|x| x["pointRate"]},
    17 =>lambda{|x| s = cut_off(x["itemCaption"].to_s.toutf8.gsub("楽天",'').gsub('。','。'),50) ; s == "" ? "-" : s},
    18 =>lambda{|x| image_get(x["smallImageUrl"],x["itemCode"] + "_s.gif")},
    19 =>lambda{|x| s = x["itemCaption"].to_s.toutf8.gsub("楽天",'').gsub('。','。') ; s == "" ? "-" : s},
    20 =>lambda{|x| image_get(x["mediumImageUrl"],x["itemCode"] + "_m.gif")},
    57 =>lambda{|x| $category_id}
  }
end
 
def image_get(image_url,save_file_name)
  hc = HTTPClient.new
  f = File.open("#{$img_dir}/" + save_file_name, "wb")
  f.print(hc.get_content(image_url))
  f.close
  save_file_name
end
 
def api_call(uri)
  json_string = ''
  open(uri){|f| json_string = f.read }
  parser = JsonParser.new
  parser.parse(json_string)
end
 
def cut_off(text,len)
  if text != nil
    text.jlength < len ? text : text.scan(/^.{#{len}}/m)[0] + "…"
  else
    ''
  end
end
 
setup
# ファイルを掃除しとく
FileUtils.remove_entry($img_dir,true)
FileUtils.mkdir($img_dir)
FileUtils.rm($item_csv_filename, {:force=>true})
File.open($item_csv_filename,'w') do |f|
  # ヘッダ行を追加
  f.puts(csv_format.collect{|col| "\"#{col[1]}\""}.join(','))
  (1..$max_page.to_i).each do |page|
    items = []
    ranking_api_url = "http://api.rakuten.co.jp/rws/3.0/json?developerId=#{$developer_id}&operation=ItemRanking&version=2010-08-05&genreId=#{$genre_id}&page=#{page}"
    # APIを呼び出して戻り値のアイテムをもとにCSV行を作成
    obj = api_call(ranking_api_url)
    exit unless obj["Body"]["ItemRanking"]
    rakuten_items = obj["Body"]["ItemRanking"]["Items"]["Item"]
    puts "ページ#{page} から #{rakuten_items.size} 件取得しました。"
    rakuten_items.each do |item|
      items << csv_format.collect do |col|
        i=col[0]
        rewrite[i] ? rewrite[i].call(item) : ""
      end
    end
    # 出力
    items.each do |item|
      f.puts(item.collect{|col| "\"#{col.to_s.gsub(',','')}\""}.join(','))
    end
  end
end
実行する

以下のコマンドで実行します。
パラメータは「ジャンルID カテゴリID 取得ページ数」です。

$ ruby itemgen.rb 101077 5 3
  • item.csv
  • imgディレクトリ

が生成されます。

画像を配置する

先に画像を配置しておく必要があるので、imgディレクトリ内の全画像を、
「html/upload/save_image/」に配置します。

登録する

Web管理ツールからCSVファイルを登録します。

完了

以上です。いろいろと使えそうな気がしますね。

第6回データマイニング+WEB勉強会@東京に参加してきた

2010年8月25日 水曜日

2010/08/22(日)、第6回データマイニング+WEB勉強会@東京に参加してきました。

ATND
http://atnd.org/events/7239

主催者@hamadakoichiさんによる勉強会まとめ(発表資料一覧/Togetter)
http://d.hatena.ne.jp/hamadakoichi/20100822/p1

@tyatsutaさんがまとめてくださった参加者一覧
http://d.hatena.ne.jp/yatsuta/20100824#1282636786

写真は会場提供してくださったニフティさん(大森 ベルポート)です。
今回の勉強会のテーマは「ソーシャル・広告・最適化祭り」ということもあって、
「ソーシャルアプリ業界」と「オンライン広告業界」からの参加者が多かったです。

この勉強会の特徴について

私はエンジニアで、昨今の技術勉強会ブームにのっている一人ですが、プロデューサ/マーケタ/企画の人向けの勉強会って、まだまだは少ないと感じていて、
(ノウハウやビジネスプランなど社外に出せるネタが少ないわけで、当然といえば当然なのですが)
そういう意味ではとても貴重な勉強会だったのではないでしょうか。

内容について

「広告」や「ソーシャルアプリ」はオープンなテクノロジが主流になりつつあることから、発表者や参加者の方は、公開ギリギリのかなり思い切った発表や質疑をしてくださっていたと思います。
ソーシャルアプリの運用の話が掘り下げられて行ったときは、正直ハラハラしました(笑)
資料については上記の@hamadakoichiさんのブログにまとまってます。
本当にありがとうございました!
そんな私はSIerという立場上、技術以外の話をすることができず大変申し訳ございませんw

懇親会のピザパーティも盛り上がりました

写真撮り忘れた。
立ち話ですが、両業界の共通点としてユーザーの反応がすぐに数字となって現れるという点があって、それって中の人にとってはドラッグみたいなもので、数字の恐怖や快感に一度浸かると、なかなかそこから抜けれないんじゃないかとか、そんな話をしたのが印象的でした。
また、お互いの業界への感心が深いことも感じました。
ソーシャルメディアのお仕事をしてる方が、広告エコシステムの話しをする一方で、広告エンジニアが、Zingaの指標値の話をするなど両者の交流を感じました。
皆さん、アンテナ貼ってるんすね。
そしてそれを横断するのが「データマイニング方法論」や「分散処理テクノロジー」であることであることは間違いなくて、私の勉強のモチベーションが上がったことは言うまでもありません。

最後に

今回、楽しみにしていた@mmlab_jp さんのプレゼンで印象に残った言葉で、
「周りに目を向けて、勘やバランス感覚を養い続けることの大切さ」
は、まさにこのような勉強会への参加を意味するんだと感じました。
発表者・参加者の皆さん、また会場提供してくださったニフティの皆さん
本当にありがとうございました。

次回の第7回勉強会は、9/26(日)の予定です!