はじめに
おはようございます。当ブログにアクセス頂き、ありがとうございます。日本に帰国したら、携帯キャリアは何にしようか決めかねている、たなけんです。
本エントリでは、アマゾンマーケットプレイスの出品情報の取得について記載します。
ブラウザからアクセス
アマゾンの商品詳細ページから、中古の出品リンクをクリックすると、出品情報の一覧が表示されます。その時の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から出品情報を取得するため、下記の様な関数を作成しました。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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)))) |
- condマクロ: JavaなどのCase文のようなもの
- その他工夫した点: Lispらしく、再帰を利用。次ページがあれば、結果をリストに追加して、再帰。次ペーがなければ結果を返す。
その他は、前回と同様enliveを用いて、販売者ID、販売価格、商品状態を抜き出しています。
抜き出した値は、RDBMSの取引情報テーブルに日付とともに収納しています。
今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間1時間)
0 件のコメント:
コメントを投稿