2012年10月10日水曜日

マーケットモニタリングアプリの開発(3): 取引情報取得

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
日本に帰国したら、携帯キャリアは何にしようか決めかねている、たなけんです。
本エントリでは、アマゾンマーケットプレイスの出品情報の取得について記載します。

ブラウザからアクセス

アマゾンの商品詳細ページから、中古の出品リンクをクリックすると、出品情報の一覧が表示されます。その時のurlは下記のようなものでした。
http://www.amazon.co.jp/gp/offer-listing/4121020618/ref=dp_olp_used?ie=UTF8&condition=used
このurlからhttp://www.amazon.co.jp/gp/offer-listing/にISBNを付けると、取引情報の先頭ページにアクセスできることが予想されます。
実際に別のISBNで試した所、予想通り取引情報の先頭ページにアクセスすることができました。
また、先頭ページのhtmlを解析したところ、次ページへのリンクはa要素のidがolp_page_nextであるタグのhrefの値であることが分かりました。

プログラムからスクレイピング

上記の観察に基づき、ISBNから出品情報を取得するため、下記の様な関数を作成しました。
(defn create-used-sales-url
""
[isbn]
(str "http://www.amazon.co.jp/gp/offer-listing/" isbn))
(defn condition-convert
""
[cond-str]
(cond (= cond-str "ほぼ新品") 1
(= cond-str "非常に良い") 2
(= cond-str "良い") 3
(= cond-str "可") 4
:else 0))
(defn extract-used-sales-sub
"New products would be skipped"
[isbn entry]
(try
{:date (crc/to-sql-date (time/now))
:isbn isbn
:seller ((re-find #"seller=(.*)" (reduce get (first (html/select entry [:td :div.seller :a])) '(:attrs :href))) 1)
:price (Integer/parseInt ((re-find #"¥ ([0-9]*)" (first (:content (first (html/select entry [:td :span.price]))))) 1))
:condition (condition-convert ((re-find #"-\s(.*)\n" (first (:content (first (html/select entry [:td :div.condition]))))) 1))
:status 0}
(catch Exception _)))
(defn extract-used-sales
":isbn :seller :price :condition :status"
[isbn url]
(let [source (url-to-resource url {:as "Shift_JIS"})]
(for [entry (html/select source [:tbody.result :tr])] (extract-used-sales-sub isbn entry))))
(defn get-next-page-sub-url
[url]
(reduce get (first (html/select (url-to-resource url {:as "Shift_JIS"}) [:a#olp_page_next]))'(:attrs :href)))
(defn extract-all-used-sales
[used-sales-url isbn result]
(if (nil? used-sales-url) result
(extract-all-used-sales
(amazonise (get-next-page-sub-url used-sales-url))
isbn
(into (remove nil? (extract-used-sales isbn used-sales-url)) result))))
view raw core.clj hosted with ❤ by GitHub


  • condマクロ: JavaなどのCase文のようなもの
  • その他工夫した点: Lispらしく、再帰を利用。次ページがあれば、結果をリストに追加して、再帰。次ペーがなければ結果を返す。

その他は、前回と同様enliveを用いて、販売者ID、販売価格、商品状態を抜き出しています。
抜き出した値は、RDBMSの取引情報テーブルに日付とともに収納しています。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間1時間)

0 件のコメント:

コメントを投稿