hagino3000's blog

平成アーカイブス (更新停止)

Mixiエコーの内容をTwitterにポストするRubyスクリプト

htmlパーサーのnokogiriを試したくて書きました。

コード

require 'rubygems'
require 'time'
require 'mechanize'
require 'nokogiri'
require 'hpricot'
require 'twitter'
require 'twitter/console'
require 'yaml'
require 'json'

gem('twitter4r','0.3.0')

class MixiEchoStatus
  attr_accessor :text
  attr_accessor :time

  public
  def to_s
    return @text
  end
end

def log(msg)
  puts Time.new.to_s + ' ' + msg
end


def getClient(mode)
  begin
    config_file = File.join(File.dirname(__FILE__), 'config', 'twitter.yml')
    client = Twitter::Client.from_config(config_file, mode)
  rescue Exception => ex
    puts ex.message
    puts 'Cannot get twitter client.'
    raise
  end
  return client
end

log "start()"

system = nil
last_post_time = nil
result = "success" 

begin

  ## Open control file
  File.open( 'log/result.yml' ) do |io|
    YAML.load_documents(io){|y|
      system = y
    }
  end

  last_post_time = system["last_post_time"].to_s 


  WWW::Mechanize.html_parser = Hpricot 
  agent = WWW::Mechanize.new
  agent.user_agent_alias = 'Mac Safari'

  # login to mixi
  login_page = agent.get('http://mixi.jp/')
  login_form = login_page.forms.first

  login_form['email'] = '$EMAIL'
  login_form['password'] = '$PASSWORD'
  agent.submit(login_form)

  # get echo page
  echo_page = agent.get('$ECHO_URL') # 抽出したい人のmixiエコーのページ
  dochtml = Nokogiri::HTML(echo_page.body)

  mixi_statuses = Array.new
  dochtml.css('td.comment').each do |echo|
    status = MixiEchoStatus.new
    echo.css('div').each do |col|
      status.text = col.content if col['id'].include?('echo_body')
      status.time = col.content if col['id'].include?('echo_post_time')
    end
    if last_post_time < status.time.to_s
      puts status.to_s
      mixi_statuses.unshift(status)
    end
  end

  client = getClient('test') if mixi_statuses.size > 0

  mixi_statuses.each do |echo|
    client.status(:post, echo.to_s)
    last_post_time = echo.time.to_s
  end

rescue Exception => exp
  log "Abnormaly ended"
  log exp.to_s
  result = "error"
ensure
  system["last_exec_result"] = result 
  system["last_exec_time"] = Time.new.to_s
  system["last_post_time"] = last_post_time
  YAML.dump(system, File.open('log/result.yml', 'w'))
end

log "end()"

まず、MechanizeのHTMLパーサーをHpricotにしないとmixiログインページのform要素が取得できません。well-formedじゃないHTMLに対してnokogiriはあんまり機能してくれない感じがします。

今日はもう眠いのでここまで、続きはnokogiriをもうちょっと触ってからにします。