Amazonで欲しい物がありました。
その商品は値段の乱高下激しく、ある時は6,000円台、またある時は4,000円台の事もある商品でした。
そこで僕は底値を探るべく、値段が下がった事を知らせてくれるシステムを作ろうと考えました。
という事で今回作ったシステムの概要を説明します。
■ システム概要
1. 欲しい商品のhtmlを取得。
2. 価格の部分を抜き出す。
3. 過去と現在の価格を比較して処理
という仕様を組みました。
■ 1.欲しい商品のhtmlを取得
まずは欲しい商品のhtmlを取得する際に使ったプログラムを示します。
プログラミングに使う言語はPythonを使いましたよ。
ちなみに欲しかった商品はコレ
import urllib2
f = urllib2.urlopen('http://www.amazon.co.jp/%E3%82%A2%E3%83%87%E3%82%A3%E3%83%80%E3%82%B9-adidas-FORUM-G1654900-%E3%83%9B%E3%83%AF%E3%82%A4%E3%83%88/dp/B003TJ91L8/ref=wl_it_dp_o_piT1_nS_nC?ie=UTF8&colid=2NPMF5TUB79UB&coliid=ISBLWHXEIDBUX')
html = f.read()
htmlの取得には”urllib2″というモジュール(ライブラリ)を使います。こいつをimportしてからurllib2のurlopen()関数を使用。結果を変数fに格納。
f.read()で変数htmlに該当Amazonページのhtmlソースが格納されてます。
■ 2.価格の部分を抜き出す
まずはソースを
import re
targetCol = re.search(r'priceLarge.*',html)
matchPrice = re.search(r'\d,\d+',targetCol.group(0))
nowPrice = matchPrice.group(0).replace(",","")
価格の部分を抜き出す為に、「正規表現」を用います。正規表現とは記号と文字で表現されたパターンを用いて文字列を検索する仕組みです。
正規表現を使うためには”re”というモジュールをimportします。
抜き出したい価格の部分は、htmlを調査してみると
<span class="priceLarge">¥ 3,905 - ¥ 6,615 </span>
の部分である事がわかりました。
と言う事で2行目では、パターンを使って文字列を検索するsearch()関数を使ってこの部分を抽出しています。
文字列の前にrをつけているのは、次の文字列はraw stringであるという事の宣言です。raw stringはエスケープシーケンスを無効にします。
正規表現では文字列中にエスケープ文字である”\”(バックスラッシュ)を多用しますので、通常の文字列だと正規表現で数字を表す”\d”を”\\d”としなければならず、冗長になるので最初からエスケープシーケンスを無効にしています。
正規表現のパターンとマッチした文字列はtargetColのMatch Objectにセットされます。こいつを取り出すにはgroup()関数を用います。引数の数値は複数のマッチが在った場合何番目のマッチ文字列を取り出すかの指定に使います。’priceLarge.*’パターンを使って
priceLarge">�� 3,905 - �� 6,615
を取り出します。さらにこの結果に対して’\d,\d+’のパターンを使って”3,905″を抜き出してカンマを削除して3905という数字を取り出しました。
これで価格を抜き出す事に成功です。
■ 3.過去と現在の価格を比較して処理
import commands
oldPrice = commands.getoutput('tail -1 /var/log/amazon/priceLog.txt')
mailCmd = 'echo "now price %s" | mail -s "price is changing" example@gmail.com' %nowPrice
logCmd = 'echo %s >> /var/log/amazon/priceLog.txt' %nowPrice
if int(nowPrice) < int(oldPrice):
commands.getoutput(mailCmd)
commands.getoutput(historyCmd)
ここでは価格を比較して、最新の価格が依然の価格よりやすかったらメールを発送するという処理を行います。
これらの実行にはLinuxシェルを使うのが簡単なので”commands”モジュールをimportします。
まず’/var/log/amazon/priceLog.txt’を作って、そこに今の価格を手入力します。
これを踏まえて、2行目ではoldPriceにpriceLogの最後の行の価格がはいってきます。
mailCmdにはLinuxでメールを送る用のコマンドを予めセット。
(Linux上でメールを使う方法は後日記事にアップします)
logCmdも同様、スクレイピングした価格をlogに追記する用のコマンドをセット。
7行目では現在価格が前回の価格よりも安ければ携帯にメールを送信。
最後に、価格をpriceLog.txtにセットしてます。
あとは30分毎にでも実行するようにcronにセットしてやれば、価格が下がった時にメールでお知らせが来るようになります。
最後にソース全文を置いておきます。
import urllib2
f = urllib2.urlopen('http://www.amazon.co.jp/%E3%82%A2%E3%83%87%E3%82%A3%E3%83%80%E3%82%B9-adidas-FORUM-G1654900-%E3%83%9B%E3%83%AF%E3%82%A4%E3%83%88/dp/B003TJ91L8/ref=wl_it_dp_o_piT1_nS_nC?ie=UTF8&colid=2NPMF5TUB79UB&coliid=ISBLWHXEIDBUX')
html = f.read()
import re
targetCol = re.search(r'priceLarge.*',html)
matchPrice = re.search(r'\d,\d+',targetCol.group(0))
nowPrice = matchPrice.group(0).replace(",","")
import commands
oldPrice = commands.getoutput('tail -1 /var/log/amazon/priceLog.txt')
mailCmd = 'echo "now price %s" | mail -s "price is changing" example@gmail.com' %nowPrice
logCmd = 'echo %s >> /var/log/amazon/priceLog.txt' %nowPrice
if int(nowPrice) < int(oldPrice):
commands.getoutput(mailCmd)
commands.getoutput(historyCmd)
余談:Ubuntuではファイルの作成日時がわからないのでアレなんですが2ヶ月くらい前から監視してて、最高価格6,615円の日がありましたが、最終的に3,900円くらいでゲットしました。
end
Very good feedback, i seriously enjoy this website , i am joyful to bookmarked and inform it to my pal, thanks for your personal sharing.
Mr.蓝晶绿洲
Thank you for coming here ,and your feed.
do you read Japanese?
I wanna write these articles in English version.
but I can’t write English not so well…uh~
have fun :)
そのコメント、スパムじゃないかと思うんです。
そうだったんですか・・・。切ない。。
PythonでwebスクレイピングAmazonの商品価格監視システムを作った » WisdomTrees.net
あの、この記事、完全にアマゾンの規約に違反した内容なんですけど。
アマゾンの一般頁にロボットやクローラーでアクセスすることは利用規約に明白に反しています。
そうした用途のためにapiが用意されてるんですから、正々堂々とAPIを利用しましょう。
まーそのAPIがまともに動けばね・・
API使い倒すとわかりますけど、ソートが出来ない項目や表記ゆれと誤字、あとインデクシングがおかしくてひっぱれないとか、PublicationDateへの日付入力漏れとか、kindle指定したらOR指定できないとか、スクレイピングして自前のDBに突っ込まないと出来ないことが多すぎって解りますよ。
Amazonは規約にスクレイピング禁止って書く前にAPIちゃんと動くようにして欲しい。。。って横からすみません。。さっきからずっとAmazon APIと格闘してるのでほとんどただの愚痴です
こんにちは。モノレートも勝手にスクレイピングしてるんですかね?
今のAmazonには使えなかった。
仕様変わってるんですかね?
もう随分仕様は変わっていると思われますね・・・