Home

週刊(月刊?)プレカリアート

ミルカさんボット

ベクトルってつぶやきに反応してこっそり「…ヴェクタ」とつぶやくbotとかいないかな

という要望があったので作ってみた。

基本

ほとんどの手順は株ニュースと同じ。今回はTwitter::Searchを使う。結果をHashie::Meshで受け取るので、必要なものだけ取り出す。一度RTしたものには反応しないことにする。

以下ソース。

#!/opt/local/bin/ruby -Ku
require 'rubygems'
require 'mechanize'
require 'nokogiri'
require 'kconv'
require 'logger'

require 'oauth'
require 'twitter'

#---------------------------------------------------------------------------
# 定数
#---------------------------------------------------------------------------

CONSUMER_KEY = "きー"
CONSUMER_SECRET = "しーくれっと"
ACCESS_TOKEN = "とーくん"
ACCESS_TOKEN_SECRET = "とーくんしーくれっと"

#---------------------------------------------------------------------------
# Retweet
#---------------------------------------------------------------------------
def retweet( r )

	user = r["from_user"]
	text = r["text"]
	id = r["id"].to_s

	# もともと「ヴェクタ」を喋るものには反応しない
	return if text.include?("ヴェクタ")

	# 手抜き
	f = open("recent_tweet.txt", "a")
	f.close

	# 過去にRTしているか調べる
	f = open("recent_tweet.txt", "r")
	while recent_id = f.gets
		if recent_id.include?(id) then
			f.close
			return
		end
	end

	# RTする
	f = open("recent_tweet.txt", "a")
	f.puts(id)
	consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET, :site => "http://twitter.com")
	oauth = Twitter::OAuth.new(CONSUMER_KEY, CONSUMER_SECRET)
	oauth.authorize_from_access(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
	twitter_client = Twitter::Base.new(oauth)

	tweet = "...ヴェクタ QT @#{user} #{text}"
	twitter_client.update(tweet, {:in_reply_to_status_id => id})
#	twitter_client.update(tweet)
	$log.info("Twitterに投稿しました:" + tweet)
	f.close

end

#---------------------------------------------------------------------------
# main
#---------------------------------------------------------------------------
def main

	Twitter::Search.new('ベクトル').each do |r|

		if r.class == Hashie::Mash then
			retweet(r)
		end
	end
end

#---------------------------------------------------------------------------
# エントリポイント
#---------------------------------------------------------------------------

#$log = Logger.new("log.txt")
$log = Logger.new(STDOUT)
$log.level = Logger::INFO

main

Rubyでmixiの日記をバックアップする

  • 2010-05-05 (水)
  • Ruby

mixiを退会すると日記は消えてしまいます。その日記を手っ取り早く手元に残しておきたいとき、1つずつ手作業でやっていると大変です。ここではそれを自動化します。

準備

まず普通にWebブラウザでmixiにログインして日記を見ます。FirefoxだとFirebugが便利です。

FirebugでDOMツリーを見ていくと該当の部分が青く反転するので、必要な場所を絞り込んでいきます。最後に、右クリックをして「XPathをコピー」を選んでやると、XPathを入手できます。

xpathを入手したら、これを利用して解析していきます。ただし、Firefoxではtbodyタグを勝手に挟むため、これを除去します。

コード

#!/usr/local/bin/ruby -Ku
require 'rubygems'
require 'mechanize'
require 'nokogiri'
require 'kconv'

# 簡易待ち付きget
def get(url)
	sleep(10)
	$agent.get(url);
	$agent.page.encoding = "UTF-8"
end

#変数
owner_id = mixiのID
diary_url = "http://mixi.jp/list_diary.pl?id=#{owner_id}"

# mixiのトップページにアクセス
$agent = Mechanize.new
$agent.get("http://mixi.jp/")
$agent.page.encoding = "UTF-8"

# ログイン
$agent.page.form_with(:name => "login_form" ) do |f|
	f.field_with(:name => 'email').value = "めーるあどれす"
	f.field_with(:name => 'password').value = "ぱすわーど"
	f.click_button
end

puts "ログインしました"

# 日記トップを取得
get(diary_url)
parser = Nokogiri::HTML.parse($agent.page.body, nil)
diary = parser.xpath("/html/body/div/div[2]/div/div[3]/div[2]/div[2]").to_html.toutf8
diaries = diary.scan(/
  • .*?\"(.*?)\".*?\"(.*?)\".*?li>/) diaries.each do |d| each_diary = "http://mixi.jp/#{d[0]}" puts "#{d[1]}を処理" Dir::mkdir(d[1]) Dir::chdir(d[1]) get(each_diary) parser = Nokogiri::HTML.parse($agent.page.body, nil) diary_list = parser.xpath('//*[@id="bodyMainAreaMain"]').to_html.toutf8 entrirs = diary_list.scan(/
    .*?\"(view_diary.*?)\">(.*?)" f.puts "" f.puts '' f.puts "" f.puts "" f.puts contents f.puts "" f.puts "" f.close end Dir::chdir("../") end
  • RubyでSBIランキングの売り越し額を調べる

    • 2010-05-05 (水)
    • Ruby

    SBI証券は個人投資家が多く使っている証券会社です。通常は個人投資家は機関投資家に搾取されるようにできています。株価が暴落すると個人投資家は飛びつき、下げ止まらないとどんどんナンピン買いをして損を膨らませていきます。投資のスタイルは人それぞれですが、個人が買い越している間は手を出さずに売り越しに転じた辺りで買うというのもよいと思っています。

    これを毎日、前場と後場にランキングを見て、買い代金と売り代金を比較してソートするのは面倒ですので、これを自動でやらせます。

    方針

    いつものようにMechanizeで該当のページを読み、xpathで必要な部分だけ取り出して解析します。

    売りと買いを配列に入れて1つずつ照合、同じコードを持つもので買い代金と売り代金の差を取って新しい配列に入れます。これをソートして出力すればOK。

    実装例

    #!/usr/bin/ruby -Ku
    require 'rubygems'
    require 'nokogiri'
    require 'mechanize'
    require 'logger'
    require 'kconv'
    
    SBI_RANKING = "https://trading1.sbisec.co.jp/ETGate/?_ControlID=WPLETmgR001Control&_DataStoreID=DSWPLETmgR001Control&burl=search_market&dir=ranking%2F&file=et_trading_value.html&cat1=market&cat2=ranking&getFlg=on"
    
    BUY_XPATH = "/html/body/div[@id='middleArea']/div[@id='middleAreaM']/table/tr/td[1]/div[@id='main']/table[2]/tr/td[2]/table[4]/tr/td[1]/table"
    SELL_XPATH = "/html/body/div[@id='middleArea']/div[@id='middleAreaM']/table/tr/td[1]/div[@id='main']/table[2]/tr[1]/td[2]/table[4]/tr/td[3]/table"
    DATE_XPATH = "/html/body/div[@id='middleArea']/div[@id='middleAreaM']/table/tr/td[1]/div[@id='main']/table[2]/tr[1]/td[2]/table[3]/tr/td[1]/b"
    TIME_XPATH = "/html/body/div[@id='middleArea']/div[@id='middleAreaM']/table/tr/td[1]/div[@id='main']/table[2]/tr[1]/td[2]/table[3]/tr/td[2]"
    
    #---------------------------------------------------------------------------
    # main
    #---------------------------------------------------------------------------
    def main
    
    	agent = Mechanize.new
    	log = Logger.new(STDOUT)
    #	log = Logger.new("sbi_ranking.log")
    	log.level = Logger::INFO
    	agent.get(SBI_RANKING)
    	agent.page.encoding = "Shift_JIS"
    
    	html = agent.page.body
    	parser = Nokogiri::HTML.parse(html, nil)
    
    	# 時刻
    	ranking_time = parser.xpath(TIME_XPATH)
    	/(\d{2,2}):(\d{2,2})<\/td>$/ =~ ranking_time.to_html.toutf8
    	sbi_hour = $1
    	sbi_min = $2
    
    	# 日付
    	ranking_date = parser.xpath(DATE_XPATH)
    	/.*?(\d{1,2})\/(\d{1,2})/ =~ ranking_date.to_html.toutf8
    	sbi_month = $1
    	sbi_day = $2
    
    	buy_code = []
    	buy_name = []
    	buy_trading_value = []
    
    	sell_code = []
    	sell_name = []
    	sell_trading_value = []
    
    	for i in 3..22 do
    		buy = parser.xpath(BUY_XPATH + "/tr[#{i}]")
    		e = buy.to_html.toutf8.gsub("\n", "")
    		/stock_sec_code_mul=(\d{4,4}).*?exchange_code.*?>(.*?)<.*?([\d,]+?)<\/div>/ =~ e
    		buy_code << $1
    		buy_name << $2
    		buy_trading_value << $3.gsub(",", "")
    	end
    
    	for i in 3..22 do
    		sell = parser.xpath(SELL_XPATH + "/tr[#{i}]")
    		e = sell.to_html.toutf8.gsub("\n", "")
    		/stock_sec_code_mul=(\d{4,4}).*?exchange_code.*?>(.*?)<.*?([\d,]+?)<\/div>/ =~ e
    		sell_code << $1
    		sell_name << $2
    		sell_trading_value << $3.gsub(",", "")
    	end
    
    	result = []
    	for i in 0..buy_code.size - 1 do
    		for j in 0..sell_code.size - 1 do
    			if buy_code[i] == sell_code[j] then
    				result.push( [buy_code[i], buy_name[i], ( buy_trading_value[i].to_i - sell_trading_value[j].to_i )] )
    			end
    		end
    	end
    
    	result = result.sort{ |a, b| a[2] <=> b[2] }
    
    	for i in 0..result.size - 1 do
    		puts "#{result[i][0]}, #{result[i][1]}, #{result[i][2]}"
    	end
    end
    
    #---------------------------------------------------------------------------
    # エントリポイント
    # 単にmainを呼ぶだけ
    #---------------------------------------------------------------------------
    main
    

    Home

    Search
    Feeds
    Meta

    Page Top