public_timeline で情報収集・・・失敗

twitterのpublic_timelineを取得しようかとおもったのですが、

  • 20件しか表示してくれない
  • 1分に1度しか更新してくれない
  • 一晩まわしてたら、アクセス制限されたぽ!

以下、60秒毎にpublic_timelineを取得するために、作成したプログラムなど。public_htmllineをjsonで取得してsqliteに入れてます。DB内の文字数とか、適当です。DBに保存するだけなのに、RailsActiveRecordを使っています ^^;

CREATE TABLE tweets (
        'id' INTEGER PRIMARY KEY NOT NULL,
        'user_id' INTEGER,
        'favorited' VARCHAR(255),
        'truncated' VARCHAR(255),
        'text' TEXT, 
        'message_id' INTEGER, 
        'in_reply_to_status_id' INTEGER,
        'in_reply_to_user_id' INTEGER,
        'source' VARCHAR(1024),
        'created_at'
);

CREATE TABLE users (
        'id' INTEGER PRIMARY KEY NOT NULL,
        'name' VARCHAR(255),
        'url' VARCHAR(1024),
        'user_id' INTEGER,
        'description' TEXT,
        'protected' BOOLEAN,
        'screen_name' VARCHAR(255),
        'followers_count' INTEGER,
        'location' VARCHAR(255),
        'profile_image_url' VARCHAR(1024)
);
  • tweets.sqlite という名前のDBを作成。
% sqlite3 tweets.sqlite < createdb.sql 
  • 必要なrubyのライブラリをインストール

% sudo gem install sqlite3-ruby -v=1.2.1
% sudo gem install json
% sudo gem install rails

  • public_getter.rb
#!/usr/bin/env ruby

require 'rubygems'
require 'json'
require 'net/http'
require 'open-uri'
require 'active_record'
require 'logger'

ActiveRecord::Base.logger = Logger.new("debug.log")
ActiveRecord::Base.establish_connection(
  :adapter => 'sqlite3',
  :dbfile => 'tweets.sqlite'
)

class User < ActiveRecord::Base
  belongs_to :tweet
end

class Tweet < ActiveRecord::Base
  has_one :user
end

class Twitter
  def initialize
    @tweet_ary = Array.new
    @data
  end

  def read(from_date = nil)
    @data = open("http://twitter.com/statuses/public_timeline.json").read
    return self
  end

  def parse()
    return if @data.nil?
    result = JSON.parse(@data)
    result.each do |post|
      user = User.new do |u|
        u.name=post["user"]["name"]
        u.url=post["user"]["url"]
        u.user_id=post["user"]["id"].to_i
        u.description=post["user"]["description"]
        u.protected=post["user"]["protected"]
        u.screen_name=post["user"]["screen_name"]
        u.followers_count=post["user"]["followers_count"].to_i
        u.location=post["user"]["location"]
        u.profile_image_url=post["user"]["profile_image_url"]
      end
      user.save

      tweet = Tweet.new do |t|
        t.user_id=user.id
        t.favorited=post["favorited"]
        t.truncated=post["truncated"]
        t.text=post["text"]
        t.message_id=post["id"].to_i
        t.in_reply_to_status_id=post["in_reply_to_status_id"].to_i
        t.in_reply_to_user_id=post["in_reply_to_user_id"].to_i
        t.source=post["source"]
        t.created_at=post["created_at"]
      end
      tweet.save

      @tweet_ary << [tweet, user]
    end
    return self
  end
  def print
    n = 0
    @tweet_ary.each do |tweet, user|
      n += 1
      puts [n, tweet.message_id, user.name].join("\t")
    end
  end
end

prev_time = Time.now
while true
  puts Time.now
  t = Twitter.new
  begin
    r = t.read()
    r.parse()
    r.print()
  rescue 
    puts "Read or parse error. skip."
  end
  step_time = 60 - (Time.now - prev_time).to_i
  step_time = 0 if step_time < 10
  puts "SLEEP: #{step_time}s"
  sleep(step_time)
  prev_time = Time.now
end
  • んで、実行。60秒ごとに再接続して、public_timelineをゲットします。
% public_getter.rb

現実逃避でした。