今日は、プログラミング言語Rubyの話です。
Rubyは、日本人が開発したプログラミング言語として、世界的に広まって最も成功した言語であると言えると思います。
スクリプト言語として有名なものにPerlやPHPがありますが、Rubyもそれらの言語に劣らない魅力があります。
ファイルの自動編集、ネット上のデータの自動取得&解析などなど、いろいろなことに使える便利な言語で、私も最近習い始めました。
Ruby に Mechanize というライブラリを併用して、Yahoo! Japan に自動ログイン後、オークションのアクセス数を1分毎に自動記録するためのスクリプトを書きましたので、そのソースコードを公開します。
ソースコードは、自由に改変して使って頂いても構いません。
ログイン時に、Hidden タグに JavaScript で値をセットする必要があるため、JavaScript に対応していない Mechanize でログインしようとすると、画像認証のページが出てしまいます。
JavaScript を手動で解析、値を設定し、画像認証を回避するようにしました。
アクセス数は、"auction_g123456789_log.txt" といったオークション ID が入ったファイル名にタブ区切りで記録されます。
なので、ファイルをテキストエディタで開き、データをコピーして Excel に張り付けるとセルに自動配置されますので、あとはグラフを作成するなり好きにデータを利用してください。
これはアクセス数と価格の推移をエクセルでグラフ化した例です。
スクリプトは UTF-8 で保存してください。
名前は yahoo.rb などとします。
実行時に yahoo.rb とパスワードを第1引数として実行することもできます。
(指定しない場合は、入力を求められます。)
自分のオークションの URL と、ユーザー名はスクリプト内で記述してください。
スクリプトは、オークション終了時に自動終了します。
自分の好きなようにカスタマイズして、お楽しみください。
※動作検証環境
OS: Windows 7 64bit SP1
Ruby: Ver 1.9.3-p194
Mechanize: Ver 2.5.1 ("gem install mechanize" コマンドでインストール)
-----------------------------------------------
#!/usr/bin/ruby
# coding: utf-8
# The first line is shebang.
# The second line is magic comment representing a script encoding.
# スクリプトエンコーディング - Ruby スクリプトを書くのに使われているエンコーディングで、
# 非 ASCII 文字を使う場合は必ず設定する必要がある(エラーになる)。
# なお、全ての String などのオブジェクトは自身のエンコーディング情報を保持しており、
# 同じプロセスの中で異なるエンコーディングの文字列が同時に存在することができる。
$datetime_start = Time.now
# You need install Mechanize by the command, "gem install mechanize".
require 'mechanize'
# Constant variables
USERNAME = "yahoo_tarou" # ここに自分のログイン名を入れる
AUCTION_PAGE = "http://page5.auctions.yahoo.co.jp/jp/auction/e123456789" # ここに出品した自分のオークションの URL を入れる
# Regular expression test : http://rubular.com/
AUCTION_PAGE =~ /\/([a-zA-Z0-9]+$)/ # オークション ID を抜き出す - 正規表現での最後のマッチを $+ に入れる(なければ nil)
if !$+ then
puts "Failed to extract the auction ID from the URL \"#{AUCTION_PAGE}\". Please confirm."
exit
end
LOG_FILE_NAME = "auction_#{$+}_log.txt" # ex. "auction_e123456789_log.txt"
$program_name = File.basename $PROGRAM_NAME # ex. "yahoo.rb"
ACCESS_INTERVAL = 60 # アクセス頻度 in seconds
# Functions
def puts_console(*args)
datetime_now = Time.now
elapse = datetime_now - $datetime_start # Float in seconds
days = elapse.divmod(24*60*60) #=> [2.0, 45000.0]
hours = days[1].divmod(60*60) #=> [12.0, 1800.0]
minutes = hours[1].divmod(60) #=> [30.0, 0.0]
seconds = minutes[1].divmod(1)
header = sprintf("[%s] %s (", $program_name, datetime_now.strftime("%Y/%m/%d %H:%M:%S.%L")) #=> ex. "2012/08/02 15:02:05.332"
header += sprintf("%.0f ", days[0]) if days[0] > 0
header += sprintf("%02.0f:", hours[0]) if hours[0] > 0
header += sprintf("%02.0f:", minutes[0]) if minutes[0] > 0
header += sprintf("%02.0f.%03.0f) ", seconds[0], seconds[1] * 1000)
print header
puts args
end
# Main scripts
# ログを記録するためのライブラリ
# require 'logger'
puts_console "Program started."
# 引数チェック
password = ""
if ARGV.size == 0 then
puts "You can specify your password as \"#{$program_name} <password>\"."
print 'Please type your password: '
password = gets.chomp
else
password = ARGV[0]
end
agent = Mechanize.new
# agent.log = Logger.new 'mech.log'
agent.user_agent_alias = 'Windows IE 9'
# You need to set the environmental value for OpenSSL to identify the root certificates.
# set SSL_CERT_FILE=C:\Ruby193\lib\ruby\1.9.1\rubygems\ssl_certs\ca-bundle.pem
# Top page (UTF-8)
agent.get "http://www.yahoo.co.jp/"
puts_console "Opened: #{agent.page.uri.to_s}"
# File.write("yahoo_top.html", agent.page.body)
# p agent.page.meta_charset() #-> ["utf-8"]
# p agent.page.response_header_charset() #-> ["utf-8"]
# p agent.page.encodings #-> [nil, "UTF-8", "utf-8", "utf-8"]
agent.page.link_with(:href => 'r/pl1').click
puts_console "Opened: #{agent.page.uri.to_s}"
# Login page (EUC-JP)
# File.write("yahoo_login.html", agent.page.body)
formLogin = agent.page.form_with(:name => "login_form")
formLogin.field_with(:name => "login").value = USERNAME
formLogin.field_with(:name => "passwd").value = password
# JavaScript でページロード時に、hidden タグの値を書き換えている。
# これを行なわないと、画像による認証のページに飛ばされてしまう。
# <input type="hidden" name=".albatross" value="dD0vaDJFUUImc2s9UDJSa0hZcmFremh1V095aElEVkc1MGJoU2pVLQ==">
# document.getElementsByName(".albatross")[0].value = "dD1hdDJFUUImc2s9VkpGQmlZTnpYUWFEeWhqUTlacnJqOFpVdWcwLQ==";
StringJava = 'document.getElementsByName(".albatross")[0].value = "'
agent.page.body.each_line do |line|
index = line.index(StringJava)
if index then
value = line[index + StringJava.length...line.rindex('"')]
formLogin.field_with(:name => ".albatross").value = value
break
end
end
agent.submit formLogin
puts_console "Opened: #{agent.page.uri.to_s}"
# Redirect page after login
# File.write("yahoo_top2.html", agent.page.body)
# ここでは <meta http-equiv="Refresh" content="0; url=http://www.yahoo.co.jp"> によってトップページへのリダイレクトが行われている。
# 自動での追随設定も可能のようだが、ここでは手動での追随を行うこととする。
# p agent.page.meta_refresh.class
# p agent.page.meta_refresh.count
# p agent.page.meta_refresh
# p agent.page.meta_refresh[0]
# p agent.page.meta_refresh[0].uri
if agent.page.meta_refresh[0] && agent.page.meta_refresh[0].uri then
# URI::HTTP クラスではなく String を渡さないと動かないようだ。
agent.get(agent.page.meta_refresh[0].uri)
else
puts_console "Failed to log in as \"#{USERNAME}\". Please confirm the password."
exit
end
puts_console "Opened: #{agent.page.uri.to_s}"
# Top page after login
# File.write("yahoo_top3.html", agent.page.body)
# ここでようやくログイン後のトップページに到達する。
# 以下のメッセージを探して、ログインに成功したかどうかを判定する。
# <h3 id="pbhello">こんにちは、<span>yahoo_tarou</span>さん</h3>
if !agent.page.at("h3[@id='pbhello']/span") || USERNAME != agent.page.at("h3[@id='pbhello']/span").inner_text then
puts_console "Failed to log in as \"#{USERNAME}\". Please confirm the password."
exit
end
puts_console "Succeeded in logging in as \"#{USERNAME}\"."
# 現在の価格:722 円
# 残り時間 :終了 (詳細な残り時間)
# 入札件数 :8 (入札履歴)
#
# このオークションの統計情報
#
# アクセス総数 : 79
# ウォッチリストに追加された数 : 11
# 友だちにメールを送られた数 : 0
# 違反商品の申告をされた数 : 0
#
# アフィリエイト経由
# アフィリエイト報酬率 :1%
# アクセス総数 : 12
# ウォッチリストに追加された数 : 4
# 入札件数 : 0
statics = Array::new
statics << ['price', 0, '//*[@id="modPdtInfo"]/div[2]/table[1]/tr/td[2]/div[2]/table/tr[1]/td[2]/p']
statics << ['time_remaining', "", '//*[@id="modPdtInfo"]/div[2]/table[1]/tr/td[2]/div[2]/table/tr[2]/td[2]/b'] # 即決価格がある場合は tr[2] ではなく tr[3] となる
statics << ['bid', 0, '//*[@id="modPdtInfo"]/div[2]/table[1]/tr/td[2]/div[2]/table/tr[3]/td[2]/b']
statics << ['viewed', 0, '//*[@id="modSellInfo"]/div[2]/div/table/tr[1]/td']
statics << ['watch_listed', 0, '//*[@id="modSellInfo"]/div[2]/div/table/tr[2]/td']
statics << ['emailed', 0, '//*[@id="modSellInfo"]/div[2]/div/table/tr[3]/td']
statics << ['violated', 0, '//*[@id="modSellInfo"]/div[2]/div/table/tr[4]/td']
statics << ['viewed_af', 0, '//*[@id="modSellInfo"]/div[4]/div/table/tr[2]/td']
statics << ['watch_listed_af', 0, '//*[@id="modSellInfo"]/div[4]/div/table/tr[3]/td']
statics << ['bid_af', 0, '//*[@id="modSellInfo"]/div[4]/div/table/tr[4]/td']
# Output header to the log file
log_header = "time"
statics.each { |item|
log_header += "\t" + item[0]
}
if FileTest.exist?(LOG_FILE_NAME) then
puts_console "Opened \"#{LOG_FILE_NAME}\"."
else
puts_console "Created \"#{LOG_FILE_NAME}\"."
File.open(LOG_FILE_NAME, 'a') { |f|
f.puts log_header
}
end
puts_console log_header
flag_break = false
while true
datetime_access = Time.now
begin
agent.get(AUCTION_PAGE)
rescue => exception
# 以下のようなエラーが発生したことがあるので例外をハンドルしないとプログラムがストップしてしまう:
# C:/Ruby193/lib/ruby/gems/1.9.1/gems/net-http-persistent-2.7/lib/net/http/persistent.rb:770:
# in `rescue in reset': connection refused: page5.auctions.yahoo.co.jp:80 (Net::HTTP::Persistent::Error)
# from C:/Ruby193/lib/ruby/gems/1.9.1/gems/net-http-persistent-2.7/lib/net/http/persistent.rb:763:in `reset'
# from C:/Ruby193/lib/ruby/gems/1.9.1/gems/net-http-persistent-2.7/lib/net/http/persistent.rb:503:in `connection_for'
# from C:/Ruby193/lib/ruby/gems/1.9.1/gems/net-http-persistent-2.7/lib/net/http/persistent.rb:806:in `request'
# from C:/Ruby193/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize/http/agent.rb:258:in `fetch'
# from C:/Ruby193/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize.rb:407:in `get'
# from C:/scripts/yahoo_auction.rb:189:in `<main>'
puts_console exception.to_s
else
# File.write("yahoo_auction.html", agent.page.body)
puts_console "Opened: #{agent.page.uri.to_s}"
# XPath は Chrome のデベロッパーツールで取得できるが、<tbody> など実際にはソースにないタグが勝手に付け加えられていることがあるので要注意。
statics.each { |item|
if agent.page.at(item[2]) then
value = agent.page.at(item[2]).inner_text # ex. ": 32"
if item[0] == 'time_remaining' then
# "残り時間" に関しては何も処理をしない
# agent.page.at が返す Nokogiri::XML::Text は EUC-JP のページでも UTF-8 で文字データを保持するようだ。
item[1] = value
if value == "終了" then
flag_break = true # オークションが終了したのでプログラムを終了する
end
else
value =~ /([0-9,]+)/ # 数字部分だけを取り出す - 正規表現での最後のマッチを $+ に入れる(なければ nil)
item[1] = $+.gsub(/,/, "") if $+ # 桁区切りのコンマがあれば除く
end
end
}
# Output data to the log file
log_data = datetime_access.strftime("%Y/%m/%d %H:%M:%S.%L") #=> ex. "2012/08/02 15:02:05.332"
statics.each { |item|
log_data += "\t" + item[1].to_s
}
puts_console log_data
File.open(LOG_FILE_NAME, 'a') { |f|
f.puts log_data
}
if flag_break then
break
end
ensure
# Sleep with time adjustment - 1 回のアクセスに 260 - 296 msec 程度かかるのでそれを補正
elapse = Time.now - datetime_access # Float in seconds
sleep_duration = ACCESS_INTERVAL - elapse
if sleep_duration > 0 then
puts_console sprintf("Sleep for %.3f seconds...", sleep_duration)
sleep sleep_duration
end
end
end
puts_console sprintf("The auction ended.")
--------------
たのしいRuby 第3版/ソフトバンククリエイティブ
![](https://img-proxy.blog-video.jp/images?url=http%3A%2F%2Fecx.images-amazon.com%2Fimages%2FI%2F41t7GQ3peRL._SL160_.jpg)
¥2,730
Amazon.co.jp
Rubyは、日本人が開発したプログラミング言語として、世界的に広まって最も成功した言語であると言えると思います。
スクリプト言語として有名なものにPerlやPHPがありますが、Rubyもそれらの言語に劣らない魅力があります。
ファイルの自動編集、ネット上のデータの自動取得&解析などなど、いろいろなことに使える便利な言語で、私も最近習い始めました。
Ruby に Mechanize というライブラリを併用して、Yahoo! Japan に自動ログイン後、オークションのアクセス数を1分毎に自動記録するためのスクリプトを書きましたので、そのソースコードを公開します。
ソースコードは、自由に改変して使って頂いても構いません。
ログイン時に、Hidden タグに JavaScript で値をセットする必要があるため、JavaScript に対応していない Mechanize でログインしようとすると、画像認証のページが出てしまいます。
JavaScript を手動で解析、値を設定し、画像認証を回避するようにしました。
アクセス数は、"auction_g123456789_log.txt" といったオークション ID が入ったファイル名にタブ区切りで記録されます。
なので、ファイルをテキストエディタで開き、データをコピーして Excel に張り付けるとセルに自動配置されますので、あとはグラフを作成するなり好きにデータを利用してください。
これはアクセス数と価格の推移をエクセルでグラフ化した例です。
スクリプトは UTF-8 で保存してください。
名前は yahoo.rb などとします。
実行時に yahoo.rb
(指定しない場合は、入力を求められます。)
自分のオークションの URL と、ユーザー名はスクリプト内で記述してください。
スクリプトは、オークション終了時に自動終了します。
自分の好きなようにカスタマイズして、お楽しみください。
※動作検証環境
OS: Windows 7 64bit SP1
Ruby: Ver 1.9.3-p194
Mechanize: Ver 2.5.1 ("gem install mechanize" コマンドでインストール)
-----------------------------------------------
#!/usr/bin/ruby
# coding: utf-8
# The first line is shebang.
# The second line is magic comment representing a script encoding.
# スクリプトエンコーディング - Ruby スクリプトを書くのに使われているエンコーディングで、
# 非 ASCII 文字を使う場合は必ず設定する必要がある(エラーになる)。
# なお、全ての String などのオブジェクトは自身のエンコーディング情報を保持しており、
# 同じプロセスの中で異なるエンコーディングの文字列が同時に存在することができる。
$datetime_start = Time.now
# You need install Mechanize by the command, "gem install mechanize".
require 'mechanize'
# Constant variables
USERNAME = "yahoo_tarou" # ここに自分のログイン名を入れる
AUCTION_PAGE = "http://page5.auctions.yahoo.co.jp/jp/auction/e123456789" # ここに出品した自分のオークションの URL を入れる
# Regular expression test : http://rubular.com/
AUCTION_PAGE =~ /\/([a-zA-Z0-9]+$)/ # オークション ID を抜き出す - 正規表現での最後のマッチを $+ に入れる(なければ nil)
if !$+ then
puts "Failed to extract the auction ID from the URL \"#{AUCTION_PAGE}\". Please confirm."
exit
end
LOG_FILE_NAME = "auction_#{$+}_log.txt" # ex. "auction_e123456789_log.txt"
$program_name = File.basename $PROGRAM_NAME # ex. "yahoo.rb"
ACCESS_INTERVAL = 60 # アクセス頻度 in seconds
# Functions
def puts_console(*args)
datetime_now = Time.now
elapse = datetime_now - $datetime_start # Float in seconds
days = elapse.divmod(24*60*60) #=> [2.0, 45000.0]
hours = days[1].divmod(60*60) #=> [12.0, 1800.0]
minutes = hours[1].divmod(60) #=> [30.0, 0.0]
seconds = minutes[1].divmod(1)
header = sprintf("[%s] %s (", $program_name, datetime_now.strftime("%Y/%m/%d %H:%M:%S.%L")) #=> ex. "2012/08/02 15:02:05.332"
header += sprintf("%.0f ", days[0]) if days[0] > 0
header += sprintf("%02.0f:", hours[0]) if hours[0] > 0
header += sprintf("%02.0f:", minutes[0]) if minutes[0] > 0
header += sprintf("%02.0f.%03.0f) ", seconds[0], seconds[1] * 1000)
print header
puts args
end
# Main scripts
# ログを記録するためのライブラリ
# require 'logger'
puts_console "Program started."
# 引数チェック
password = ""
if ARGV.size == 0 then
puts "You can specify your password as \"#{$program_name} <password>\"."
print 'Please type your password: '
password = gets.chomp
else
password = ARGV[0]
end
agent = Mechanize.new
# agent.log = Logger.new 'mech.log'
agent.user_agent_alias = 'Windows IE 9'
# You need to set the environmental value for OpenSSL to identify the root certificates.
# set SSL_CERT_FILE=C:\Ruby193\lib\ruby\1.9.1\rubygems\ssl_certs\ca-bundle.pem
# Top page (UTF-8)
agent.get "http://www.yahoo.co.jp/"
puts_console "Opened: #{agent.page.uri.to_s}"
# File.write("yahoo_top.html", agent.page.body)
# p agent.page.meta_charset() #-> ["utf-8"]
# p agent.page.response_header_charset() #-> ["utf-8"]
# p agent.page.encodings #-> [nil, "UTF-8", "utf-8", "utf-8"]
agent.page.link_with(:href => 'r/pl1').click
puts_console "Opened: #{agent.page.uri.to_s}"
# Login page (EUC-JP)
# File.write("yahoo_login.html", agent.page.body)
formLogin = agent.page.form_with(:name => "login_form")
formLogin.field_with(:name => "login").value = USERNAME
formLogin.field_with(:name => "passwd").value = password
# JavaScript でページロード時に、hidden タグの値を書き換えている。
# これを行なわないと、画像による認証のページに飛ばされてしまう。
# <input type="hidden" name=".albatross" value="dD0vaDJFUUImc2s9UDJSa0hZcmFremh1V095aElEVkc1MGJoU2pVLQ==">
# document.getElementsByName(".albatross")[0].value = "dD1hdDJFUUImc2s9VkpGQmlZTnpYUWFEeWhqUTlacnJqOFpVdWcwLQ==";
StringJava = 'document.getElementsByName(".albatross")[0].value = "'
agent.page.body.each_line do |line|
index = line.index(StringJava)
if index then
value = line[index + StringJava.length...line.rindex('"')]
formLogin.field_with(:name => ".albatross").value = value
break
end
end
agent.submit formLogin
puts_console "Opened: #{agent.page.uri.to_s}"
# Redirect page after login
# File.write("yahoo_top2.html", agent.page.body)
# ここでは <meta http-equiv="Refresh" content="0; url=http://www.yahoo.co.jp"> によってトップページへのリダイレクトが行われている。
# 自動での追随設定も可能のようだが、ここでは手動での追随を行うこととする。
# p agent.page.meta_refresh.class
# p agent.page.meta_refresh.count
# p agent.page.meta_refresh
# p agent.page.meta_refresh[0]
# p agent.page.meta_refresh[0].uri
if agent.page.meta_refresh[0] && agent.page.meta_refresh[0].uri then
# URI::HTTP クラスではなく String を渡さないと動かないようだ。
agent.get(agent.page.meta_refresh[0].uri)
else
puts_console "Failed to log in as \"#{USERNAME}\". Please confirm the password."
exit
end
puts_console "Opened: #{agent.page.uri.to_s}"
# Top page after login
# File.write("yahoo_top3.html", agent.page.body)
# ここでようやくログイン後のトップページに到達する。
# 以下のメッセージを探して、ログインに成功したかどうかを判定する。
# <h3 id="pbhello">こんにちは、<span>yahoo_tarou</span>さん</h3>
if !agent.page.at("h3[@id='pbhello']/span") || USERNAME != agent.page.at("h3[@id='pbhello']/span").inner_text then
puts_console "Failed to log in as \"#{USERNAME}\". Please confirm the password."
exit
end
puts_console "Succeeded in logging in as \"#{USERNAME}\"."
# 現在の価格:722 円
# 残り時間 :終了 (詳細な残り時間)
# 入札件数 :8 (入札履歴)
#
# このオークションの統計情報
#
# アクセス総数 : 79
# ウォッチリストに追加された数 : 11
# 友だちにメールを送られた数 : 0
# 違反商品の申告をされた数 : 0
#
# アフィリエイト経由
# アフィリエイト報酬率 :1%
# アクセス総数 : 12
# ウォッチリストに追加された数 : 4
# 入札件数 : 0
statics = Array::new
statics << ['price', 0, '//*[@id="modPdtInfo"]/div[2]/table[1]/tr/td[2]/div[2]/table/tr[1]/td[2]/p']
statics << ['time_remaining', "", '//*[@id="modPdtInfo"]/div[2]/table[1]/tr/td[2]/div[2]/table/tr[2]/td[2]/b'] # 即決価格がある場合は tr[2] ではなく tr[3] となる
statics << ['bid', 0, '//*[@id="modPdtInfo"]/div[2]/table[1]/tr/td[2]/div[2]/table/tr[3]/td[2]/b']
statics << ['viewed', 0, '//*[@id="modSellInfo"]/div[2]/div/table/tr[1]/td']
statics << ['watch_listed', 0, '//*[@id="modSellInfo"]/div[2]/div/table/tr[2]/td']
statics << ['emailed', 0, '//*[@id="modSellInfo"]/div[2]/div/table/tr[3]/td']
statics << ['violated', 0, '//*[@id="modSellInfo"]/div[2]/div/table/tr[4]/td']
statics << ['viewed_af', 0, '//*[@id="modSellInfo"]/div[4]/div/table/tr[2]/td']
statics << ['watch_listed_af', 0, '//*[@id="modSellInfo"]/div[4]/div/table/tr[3]/td']
statics << ['bid_af', 0, '//*[@id="modSellInfo"]/div[4]/div/table/tr[4]/td']
# Output header to the log file
log_header = "time"
statics.each { |item|
log_header += "\t" + item[0]
}
if FileTest.exist?(LOG_FILE_NAME) then
puts_console "Opened \"#{LOG_FILE_NAME}\"."
else
puts_console "Created \"#{LOG_FILE_NAME}\"."
File.open(LOG_FILE_NAME, 'a') { |f|
f.puts log_header
}
end
puts_console log_header
flag_break = false
while true
datetime_access = Time.now
begin
agent.get(AUCTION_PAGE)
rescue => exception
# 以下のようなエラーが発生したことがあるので例外をハンドルしないとプログラムがストップしてしまう:
# C:/Ruby193/lib/ruby/gems/1.9.1/gems/net-http-persistent-2.7/lib/net/http/persistent.rb:770:
# in `rescue in reset': connection refused: page5.auctions.yahoo.co.jp:80 (Net::HTTP::Persistent::Error)
# from C:/Ruby193/lib/ruby/gems/1.9.1/gems/net-http-persistent-2.7/lib/net/http/persistent.rb:763:in `reset'
# from C:/Ruby193/lib/ruby/gems/1.9.1/gems/net-http-persistent-2.7/lib/net/http/persistent.rb:503:in `connection_for'
# from C:/Ruby193/lib/ruby/gems/1.9.1/gems/net-http-persistent-2.7/lib/net/http/persistent.rb:806:in `request'
# from C:/Ruby193/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize/http/agent.rb:258:in `fetch'
# from C:/Ruby193/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize.rb:407:in `get'
# from C:/scripts/yahoo_auction.rb:189:in `<main>'
puts_console exception.to_s
else
# File.write("yahoo_auction.html", agent.page.body)
puts_console "Opened: #{agent.page.uri.to_s}"
# XPath は Chrome のデベロッパーツールで取得できるが、<tbody> など実際にはソースにないタグが勝手に付け加えられていることがあるので要注意。
statics.each { |item|
if agent.page.at(item[2]) then
value = agent.page.at(item[2]).inner_text # ex. ": 32"
if item[0] == 'time_remaining' then
# "残り時間" に関しては何も処理をしない
# agent.page.at が返す Nokogiri::XML::Text は EUC-JP のページでも UTF-8 で文字データを保持するようだ。
item[1] = value
if value == "終了" then
flag_break = true # オークションが終了したのでプログラムを終了する
end
else
value =~ /([0-9,]+)/ # 数字部分だけを取り出す - 正規表現での最後のマッチを $+ に入れる(なければ nil)
item[1] = $+.gsub(/,/, "") if $+ # 桁区切りのコンマがあれば除く
end
end
}
# Output data to the log file
log_data = datetime_access.strftime("%Y/%m/%d %H:%M:%S.%L") #=> ex. "2012/08/02 15:02:05.332"
statics.each { |item|
log_data += "\t" + item[1].to_s
}
puts_console log_data
File.open(LOG_FILE_NAME, 'a') { |f|
f.puts log_data
}
if flag_break then
break
end
ensure
# Sleep with time adjustment - 1 回のアクセスに 260 - 296 msec 程度かかるのでそれを補正
elapse = Time.now - datetime_access # Float in seconds
sleep_duration = ACCESS_INTERVAL - elapse
if sleep_duration > 0 then
puts_console sprintf("Sleep for %.3f seconds...", sleep_duration)
sleep sleep_duration
end
end
end
puts_console sprintf("The auction ended.")
--------------
たのしいRuby 第3版/ソフトバンククリエイティブ
![](https://img-proxy.blog-video.jp/images?url=http%3A%2F%2Fecx.images-amazon.com%2Fimages%2FI%2F41t7GQ3peRL._SL160_.jpg)
¥2,730
Amazon.co.jp