shtaxxx日記

コンピュータアーキテクチャについて研究している研究者の日記や技術紹介

rubyで名言集botを作ってみた

先日の飲み会で話題に上がった,電気科名言集botを作成しました.
@denkika_meigen

mixiコミュニティのトピックに投稿されている名言の中からランダムでひとつをtwitterにつぶやくrubyスクリプトです.
MacOS 10.6 と CentOS 5.5の2つの環境で動作を確認.
# CentOSの方では最後に例外が発生するけど動作する,要注意rubygemsにてjson 1.4.6を導入することで解決

rubyのバージョン
rubyライブラリにはrubygemsを使用
  • rubygems 1.3.7
    • twitter (1.0.0)
    • mechanize (1.0.0)
    • hpricot (0.8.3)
    • (追記) json (1.4.6) : multi_json (0.0.5)ではダメ


手順

mixiコミュニティのトピックから投稿を持ってくる

ログインの仕方などはこちらを参考にさせていただきました.
mixiコミュニティのカテゴリ取得 - 皇帝ペンギン飼育係りも

hpricotと正規表現で成形する

hpricotの使い方はこちらを参考にさせていただきました.
HTMLパーサ Hpricot - pylori*style wiki

  • dl class="commentContent01"下のdd要素に各コメントがあるので,それ以外の部分を取り除く
  • コメントが140字以上だとTwitterに投稿できないので,適切に分割する
ランダムで1つ選ぶ
  • rand(maxnum)
TwitterにOAuthで接続しつぶやく

本家っぽいサイトを参照しました.
Ruby Twitter Gem by John Nunemaker

cronに登録する
  • 0 * * * * /usr/local/bin/ruby /home/shtaxxx/meigen/meigen.rb

ソースコード

#!/usr/bin/env ruby
require 'rubygems'
gem 'twitter'
require 'twitter'
require 'mechanize'
require 'hpricot'
require 'kconv'
require 'time'
require 'date'

# mixi
username = 'mixi username'
password = 'mixi password'
# Twitter: Key and Password
consumer_key = "Consumer_Key"
consumer_secret = "Consumer_Secret"
access_token_key = "Token_Key"
access_token_secret = "Token_Secret"

# Open mixi Page
agent = Mechanize.new
agent.user_agent_alias = 'Mac Safari'
page = agent.get('http://mixi.jp')
form = page.forms[0]
form.fields.find{|f| f.name == 'email'}.value = username
form.fields.find{|f| f.name == 'password'}.value = password
form.fields.find{|f| f.name == 'next_url'}.value = '/home.pl'
results = agent.submit(form)
url = "http://mixi.jp/view_bbs.pl?id=[アカウントID]&comm_id=[コミュニティID]&page=all"
bbs = agent.get(url)
htmldoc = Hpricot(bbs.body)

# Parse
maxnum = 0
$KCODE = "UTF-8"
ls = []
(htmldoc/"dl.commentContent01").each{|e|
  src = e.inner_html.toutf8.gsub(/<dd>/,"").gsub(/<\/dd>/,"").gsub(/<dt>.+<\/dt>/m,"").gsub(/<br \/>/,"\n").gsub(/<!--.+-->/m,'').gsub(/<.+?>/m,'').gsub(/\r/,"").gsub(/\n+/,"\n")
  if !(src=~/\A\s*\Z/) then
    str = src
    while str.split(//u).length > 140 do
      str=~/\A(.{100,}?)\n/m
      str = $'
      ls << $1
      maxnum+=1
    end
    ls << str
    maxnum+=1
  end
}
sel = rand(maxnum)

# Twitter Setting
Twitter.configure do |config|
  config.consumer_key = consumer_key
  config.consumer_secret = consumer_secret
  config.oauth_token = access_token_key
  config.oauth_token_secret = access_token_secret
end
# Login
client = Twitter::Client.new

# Post
#puts ls[sel]
now = Time.now
begin
  client.update(ls[sel])
rescue
  puts "Post Error"
  open("post.log","a"){|f| f.puts "#{now} : Post Error"}
  #exit(1)
end

open("post.log","a"){|f| f.puts "#{now} : #{ls[sel]}"}
# Get Timeline
#puts client.home_timeline.first.text