Hatena::Grouprubyist

今日も元気にrubyist

2008-09-05

[]bloombergからWTI原油の価格を取得するスクリプト 16:12 bloombergからWTI原油の価格を取得するスクリプト - 今日も元気にrubyist を含むブックマーク はてなブックマーク - bloombergからWTI原油の価格を取得するスクリプト - 今日も元気にrubyist bloombergからWTI原油の価格を取得するスクリプト - 今日も元気にrubyist のブックマークコメント


# 2008/09/04 bloombergのいろいろな指数を取得するスクリプト

require 'mechanize'
require 'kconv'

# 0.初期設定
agent = WWW::Mechanize.new

def write(arr)
  f = open("C:/share/03_scr/bloomberg/bloomberg.txt", "a") 
  f.write(arr.join("\t"))
  f.write("\n")
  f.close
end

# 1.bloombergにアクセス
page = agent.get('http://www.bloomberg.com/markets/commodities/energyprices.html')
#page = agent.get('http://www.bloomberg.com/markets/asia_index.html')

arr = []
# 1.span classで回す
(page/"span").each do |text|
  # 2.tbl_txtクラスかつ最後の一文字が英文字かどうか←(前日と価格が変わらなかったときの対策)
  if text.to_html =~ /<span class="tbl_txt">.*/ && text.inner_text =~ /^.*\w$/
    # 1.今まで溜まっている単語列が5個かどうか?
    if arr.size < 5
      # 1.4個以下なら不正な行としてその行を削除
      arr = []
      arr << text.inner_text
    elsif arr.size == 5
      # 2.5個なら結果出力
      write(arr)
      arr = []
      arr << text.inner_text
    else
      # 3.6個以上なら6番目以降の要素を削って出力
      arr = arr.slice(0..4)
      write(arr)
      arr = []
    end
  else
    # 3.それ以外のクラスなら配列に代入
    arr << text.inner_text
  end
end

Webアクセスまでは楽勝だけど、その後の文字整形(成型?)が大変。

ちゃんとタグ分けされてないのでまずspanクラスを全部取り出す。

その中で指数クラスが所属するtbl_txtクラスをキーにして整形。

ただしその他の要素にも同じタグが使われてるので

指数,価格,前日比,前日比(%),データと5つの要素が揃ったときのみ

ファイルに書き出すようにした。

まぁめんどくさいといっても30分くらいで出来上がったのだが、

力技なので充実感とか知的好奇心が満たされたって感じはないなぁ。

あ、bloombergのサイトは全部同じ形式なので

アドレス変えれば日経平均やダウ平均も取得できると思います。

2008-08-06

[]auの料金明細を取得するスクリプト 16:10 auの料金明細を取得するスクリプト - 今日も元気にrubyist を含むブックマーク はてなブックマーク - auの料金明細を取得するスクリプト - 今日も元気にrubyist auの料金明細を取得するスクリプト - 今日も元気にrubyist のブックマークコメント

rubyスクリプトを書いてなかったわけではないが投稿は久しぶり。

毎月auの料金明細を手動で確認するのが面倒なのでスクリプトを書いてみた。


# 2008/08/06 auの料金明細を取得するスクリプト

require 'mechanize'
require 'kconv'

# 0.初期設定
username = 'ユーザー名'
password = 'パスワード'
agent = WWW::Mechanize.new

# 1.MYPAGEにログイン
page = agent.get('https://ryokin.au.kddi.com/au-ryokin1/SNK1100')
form = page.forms[0]
form.fields.find {|f| f.name == 'K1100AA'}.value = username
form.fields.find {|f| f.name == 'K1100AB'}.value = password
mypage = agent.submit(form, form.buttons.first)
# puts mypage.body.tosjis

# 2.請求内訳を取得
# 2番目のフォーム(2か月分の請求内訳)にフォーカス
form = mypage.forms[1]
seikyu = agent.submit(form, form.buttons.first)
# tdタグのうち"tsize9"というクラスを検索
(seikyu/"td.tsize9").each do |text|
  puts text
  # puts text.xpath
end

実はこれまだ未完成で、上記スクリプトを実行すると不要な情報がいくらか出てくる。

ので、絞り込まないといけないのだけど、適切なID/クラス名が割り振られてないから

こちらで文字列判断して分岐作らないといけないんです。au終わってる。

文字列部分は契約しているプランによって違うので

このスクリプトの利用者がそれぞれ作りこむ必要がある。

そんなに難しいものじゃないと思うので、このまま投稿します。

MikelMikel2011/09/07 22:29Created the greatest artiecls, you have.

fixstcndiszfixstcndisz2011/09/08 17:05Gaat0R <a href="http://cqhpmiaermwv.com/">cqhpmiaermwv</a>

jqfqzoolpsjqfqzoolps2011/09/08 21:0896pZof , [url=http://wmjtnltmsvzq.com/]wmjtnltmsvzq[/url], [link=http://ynqxeurwdoeu.com/]ynqxeurwdoeu[/link], http://busoelvnpxrp.com/

ghvpgvzepkghvpgvzepk2011/09/09 17:34q9Mr8D <a href="http://oprigqmxmlfs.com/">oprigqmxmlfs</a>

jjxosnjjxosn2011/09/10 23:01I6UMhj , [url=http://lgpxfydcogwr.com/]lgpxfydcogwr[/url], [link=http://snujjwvgtfgp.com/]snujjwvgtfgp[/link], http://xlhxurxczbtb.com/

AustinAustin2013/01/14 03:50Hey hey hey, take a gaendr at what' you've done

xxqkvvpxxqkvvp2013/01/14 22:17ZW981a <a href="http://zebxnlstfwbb.com/">zebxnlstfwbb</a>

wwyiwcejkpwwyiwcejkp2013/01/14 22:176u3xr2 <a href="http://fdnfbryarsjr.com/">fdnfbryarsjr</a>

oedzzboedzzb2013/01/16 17:43nSSTzo , [url=http://juqhgadwcdwn.com/]juqhgadwcdwn[/url], [link=http://dobpuwnrmjrc.com/]dobpuwnrmjrc[/link], http://aieldappdvgl.com/

oedzzboedzzb2013/01/16 17:43nSSTzo , [url=http://juqhgadwcdwn.com/]juqhgadwcdwn[/url], [link=http://dobpuwnrmjrc.com/]dobpuwnrmjrc[/link], http://aieldappdvgl.com/

2007-06-28

[][]rubyのベンチマーク-benchmark.rb- 20:43 rubyのベンチマーク-benchmark.rb- - 今日も元気にrubyist を含むブックマーク はてなブックマーク - rubyのベンチマーク-benchmark.rb- - 今日も元気にrubyist rubyのベンチマーク-benchmark.rb- - 今日も元気にrubyist のブックマークコメント

rubyスクリプト中の特定の処理の実行時間を知りたいと思ったことはありませんか?(ありまーす!)

ということでbenchmark.rb

プログラミング言語 Ruby リファレンスマニュアル

です。benchmark.rbを使用することで特定ブロックの実行時間を計測することができます。使い方はこんな感じ。

require 'benchmark'

Benchmark.bm do |x|
  x.report do
    10000.times do
      str = "test"
    end
  end
end

#=>
      user     system      total        real
  0.016000   0.000000   0.016000 (  0.016000)

sqlite3とArrayのパフォーマンスを比べてみる

僕はとあるアプリでsqlite3を使ってデータを保存しています。sqlの行数は200行です。しかしデータを取り出すときはsqlの全てのデータを配列に入れてから、rubyの構文を使ってデータを取り出しています。なぜなら

  • SQL文の書き方が良く分からない(SQL初心者)
  • 配列に入れたほうがピュアrubyで早くね?

からです。つまり**根拠のない理由**です。今回は僕の理由を検証するためbenchmark.rbを使ってsqlite3とArrayのパフォーマンスを計測してみることにしました。

require 'sqlite3'
require 'benchmark'

@arr_entry = Array.new
dbfile = "newsing.db"
@db = SQLite3::Database.new(dbfile)
@db.execute('select * from entry_tbl') do |row|
  @arr_entry << row
end

n = 10

# 単純実行
Benchmark.bm do |x|
  # SQL
  x.report("sql:") do
    n.times do
      @db.execute('select * from entry_tbl') do |row|
      end
    end
  end
  # 配列
  x.report("arr:") do
    n.times do
      @arr_entry.each do |elem|
      end
    end
  end
end

n = 1000

# 条件指定
Benchmark.bm do |x|
  # SQL
  x.report("sql_where:") do
    n.times do
      @db.execute(%Q[select * from entry_tbl where url = 'http']) do |row|
      end
    end
  end
  # 配列
  x.report("arr_if:") do
    n.times do
      @arr_entry.each do |elem|
        if elem[0] == "http"
        end
      end
    end
  end
end

#=>
      user     system      total        real
sql:  0.906000   0.000000   0.906000 (  0.906000)
arr:  0.000000   0.000000   0.000000 (  0.016000)
      user     system      total        real
sql_where:  0.250000   0.031000   0.281000 (  0.328000)
arr_if:  0.532000   0.000000   0.532000 (  0.531000)

単純実行の場合は配列の方が圧倒的に早かったですが、条件を指定するとSQLの方が早いです。今回は200行ですが、行数が多くなればもっと明確な差が出るかもしれません。

SQLの場合はブロックに渡す前のSQL文の実行で絞込みが終わっているのに対し、配列は取りあえず全てをブロックに渡しているからでしょう。全てに要素を取り出してif文実行すりゃ遅くなりますよね。配列もブロックに渡す前に何らかの方法で削ればいいのですが、多元配列の場合は条件指定が難しくそれこそSQL文覚えた方がよいと思います。

ということで、配列からデータを取り出している僕のアプリは見直しが必要ということが分かりました。今はアクセス数が少ないですが、将来的にはパフォーマンスを改善したいところです。

2007-06-22

[](小ネタ)Hpricotを使って人狼BBSの参加者リストを作成する。 11:17 (小ネタ)Hpricotを使って人狼BBSの参加者リストを作成する。 - 今日も元気にrubyist を含むブックマーク はてなブックマーク - (小ネタ)Hpricotを使って人狼BBSの参加者リストを作成する。 - 今日も元気にrubyist (小ネタ)Hpricotを使って人狼BBSの参加者リストを作成する。 - 今日も元気にrubyist のブックマークコメント

人狼BBSのアクティブユーザー、ヘビーユーザーの割合が知りたかったので

参加者リストを取得しIDを抜き出すスクリプトを作成しました。

require 'hpricot'
require 'open-uri'

#uptoメソッドetcを使用して繰り返し実行(今はしない)
#501.upto(1300) do |i|
doc = Hpricot(open(%Q[http://ninjin002.x0.com/wolff/index.rb?vid=1132]))

#エピローグのURLを取得
elem = (doc/%Q[//a]).each do |elem|
  @url = "http://ninjin002.x0.com/wolff/" + elem.to_html.sub(%Q[<a href="],"").sub(%r/">.*/,"") if elem.inner_text == "エピローグ"
end

#エピローグにアクセスし、参加者リストを取得
#http://ninjin002.x0.com/wolff/index.rb?vid=1132&meslog=1132_party_6
doc = Hpricot(open(@url))
elem = (doc/%Q[div.announce]).each do |elem|
  @entry = elem.inner_text if elem.inner_text =~ /^楽天家 ゲルト/
end

#参加者リストをパースしてIDを抜き出す
puts @entry.scan(%r[((.*?))])

作成時間30分(これでも遅いと思う)。マジHpricotは神だなー。

あとはDBに入れて見せ方を考えればOK。

[](小ネタ続き)取得した人狼BBS参加者リストを解析 15:48 (小ネタ続き)取得した人狼BBS参加者リストを解析 - 今日も元気にrubyist を含むブックマーク はてなブックマーク - (小ネタ続き)取得した人狼BBS参加者リストを解析 - 今日も元気にrubyist (小ネタ続き)取得した人狼BBS参加者リストを解析 - 今日も元気にrubyist のブックマークコメント

参加者IDをこんな感じでテキストファイルに保存。

=====501村=====
master
knight
・
・
・
seena
totoro
=====502村=====
master
yamadayama
・
・
・
bdheki
turugi

これを以下のスクリプトで解析

require 'benchmark'
puts Benchmark.measure {
  file = File.open("C:/share/jinro_list.txt")
  @arr = Array.new
  file.each_line do |line|
    line = line.chomp!
    next if line =~ /=====/
    if @arr.assoc(line)
      elem = @arr.assoc(line)
      @arr.delete(@arr.assoc(line))
      @arr << [line,elem[1] + 1]
    else
      @arr << [line,1]
    end
  end
}

@arr.each do |elem|
  puts elem.join("\t")
end

@arrは2重配列でデータベース的役割を果たす。

1回目に登場したIDは[ID名、1]の形式で@arrに入力。

2回目以降は[ID名、登場回数]を[ID名、登場回数+1]とする。

最後にお約束のarr.eachで出力して終了。

#assocは2重配列を処理するのにすごぶる便利な関数です。

#assocは2重配列の0番目の要素を検索し、ヒットすると配列を返す。

# ID,参加回数の形式で収納
arr = [
["master",5],
["teraco",1],
["dolp",8],
["namayo",13],
["aiko",2]
]

# xの参加回数を調べる場合
p arr.assoc("namayo") #=> ["namayo", 13]
p arr.assoc("namayo")[1] #=> 13

欠点は最初にヒットした要素しか返さないこと。0番目の要素をキーとしユニークとなる配列を組む必要がある。

2重配列の1番目の要素を検索し、ヒットすると配列を返す#rassocメソッドもご参考。

kenaxtkenaxt2007/10/11 02:12hpricot面白そうですね。
所で、一覧作成にはHashを使っても良いのでは?
変更する場合は、@arrは、@hashくらいの名前にした方が吉分かりやすいかと思います。


diff bench.rb bench2.rb
4c4
< @arr = Array.new
---
> @arr = Hash.new(0)
8,14c8
< if @arr.assoc(line)
< elem = @arr.assoc(line)
< @arr.delete(@arr.assoc(line))
< @arr << [line,elem[1] + 1]
< else
< @arr << [line,1]
< end
---
> @arr[line] += 1

teracoteraco2008/02/20 17:08アドバイスありがとうございます!
早速試します♪

QueenieQueenie2011/09/08 19:09Yeah that's what I'm tlaikng about baby--nice work!

owhrvajgowhrvajg2011/09/09 00:29SFqsTa <a href="http://xwhfraecqhoh.com/">xwhfraecqhoh</a>

qyolyfrqyolyfr2011/09/09 21:10xSVTRR , [url=http://kmwbomxmvacv.com/]kmwbomxmvacv[/url], [link=http://kergceolgqvw.com/]kergceolgqvw[/link], http://dpxraocgprqn.com/

bjooufdibjooufdi2011/09/11 23:504lB1fH <a href="http://slpdzalsaxuw.com/">slpdzalsaxuw</a>

uibzqwecquibzqwecq2011/09/12 18:57CLYzBj , [url=http://flcavihyaevy.com/]flcavihyaevy[/url], [link=http://jsxtnanzpizt.com/]jsxtnanzpizt[/link], http://tbxpbtcwtzkt.com/

2007-06-13

ruby for linux 10:48 ruby for linux - 今日も元気にrubyist を含むブックマーク はてなブックマーク - ruby for linux - 今日も元気にrubyist ruby for linux - 今日も元気にrubyist のブックマークコメント

ということで自鯖作成計画の一環で右も左も分からないlinuxrubyを導入してみる。

取りあえず

# yum install ruby

でruby1.8.5をインストールした後rubygemsを導入。

RubyGems の使い方 - WebOS Goodies

…なぜかwgetダウンロードしたパッケージが壊れてたので、firefoxからDLしたものを

tar zxvf rubygems-0.9.2.tgz
cd rubygems-0.9.4
ruby setup.rb

して導入完了。そんでgem install hpricotしてmswin32版ではなくruby版を選択(…ぶっちゃけ違い分かってないが、linuxならruby版でいいんだろうという安易な考え。)すると

ruby extconf.rb install hpricot
can't find header files for ruby.

つーエラーが発生。エラーコードからぐぐると以下のページを発見。どうやらruby-develってのを入れないといけないらしい。なんじゃそれ?


LunaTear: ruby extconf.rbでエラー

# yum install ruby-devel
Loading "installonlyn" plugin
Loading "fastestmirror" plugin
Setting up Install Process
Setting up repositories
base                      100% |=========================| 1.1 kB    00:00     
updates                   100% |=========================|  951 B    00:00     
addons                    100% |=========================|  951 B    00:00     
extras                    100% |=========================| 1.1 kB    00:00     
(省略)

よーし導入できたぜ!リトライ

gcc -I. -I. -I/usr/lib/ruby/1.8/i386-linux -I.  -fPIC -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -Wall  -fPIC  -c hpricot_scan.c
make: gcc: コマンドが見つかりませんでした
make: *** [hpricot_scan.o] エラー 127
(中略)

なんとgccyやらmakeやらが入ってなかったようです(すんませんここらへんログ取ってないんであいまいです。)

# yum install gcc

# yum install make

してやっとこさhpricotインストールできましたとさ。

sqlite3導入にはまた一苦労。

よーしこの勢いでsqlite3も導入するぜ!gem install sqlite3!

エラーorz。以下のページを見るとsqlite-develが必要らしい。だからdevelてなんやねん!

404エラー|Ameba(アメーバブログ)

とにかく力を貸してくれたWeb上のみなさんありがとうございました。