ahokaiクローラ修正

atomから本文を取ってたんだけど、なぜかrssからじゃないとfeed-normalizerがエラーを出すようになったのでrssに切り替えた。


ついでに、せっかくだから引数を受ける部分も手を加えた。


こうしてARGVを加工すると

# 保存するpageを引数で指定
pages = ARGV.map{|arg|
  nums = arg.scan(/([1-9]+[0-9]*)/).map{|i|i.first.to_i}.sort
  if nums.size > 1
    result = Array.new
    for i in nums[0]..nums[1] do
      result << i
    end
  else
    result = nums.first.to_i
  end
  result
}.flatten.uniq.delete_if{|i|i==nil}
pages = 1,2,3 if pages.size < 1
store.rb 1 5-10 20-22

と実行時引数を与えると、変数pagesに配列[1,5,6,7,8,9,10,20,21,22]が入る。個別ページ指定や範囲指定ができる。

store.rb 10
だけだったら[10]だけになるし、1 2 3だと[1,2,3]になる。
5-30 20-40とか重複する範囲指定をしてしまっても、ちゃんと5から40までの配列になる。

これをページ番号リストとしてforeachで回して、
http://twitter.com/statuses/user_timeline/#{user}.rss?page=#{page}
にアクセスして本文を取ってくるようにした。



http://bitbucket.org/shokai/bot-ahokai/src/b9aee4dad99f/store.rb

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'rubygems'
require 'active_record'
require 'feed-normalizer'
require 'open-uri'
require 'kconv'
require 'yaml'
require File.dirname(__FILE__) + "/model_post.rb"

config = YAML::load open(File.dirname(__FILE__)+'/config.yaml')

user = config["usernum"] # twitterID
if user == nil
  puts 'Error!: usernum not Found on config.yaml'
  exit(1)
end

ActiveRecord::Base.establish_connection(
                                        :adapter => 'sqlite3',
                                        #:dbfile => ':memory:',
                                        :database => File.dirname(__FILE__) + '/db',
                                        :timeout => 30000
                                        )

# 保存するpageを引数で指定
pages = ARGV.map{|arg|
  nums = arg.scan(/([1-9]+[0-9]*)/).map{|i|i.first.to_i}.sort
  if nums.size > 1
    result = Array.new
    for i in nums[0]..nums[1] do
      result << i
    end
  else
    result = nums.first.to_i
  end
  result
}.flatten.uniq.delete_if{|i|i==nil}
pages = 1,2,3 if pages.size < 1

errors = Array.new
pages.each{|page|
  sleep 10 if page != pages.first
  uri = "http://twitter.com/statuses/user_timeline/#{user}.rss?page=#{page}"
  begin
    if(config["user"] != nil && config["pass"] != nil)
      feed = FeedNormalizer::FeedNormalizer.parse open(uri, :http_basic_authentication => [config["user"], config["pass"]])
    else
      feed = FeedNormalizer::FeedNormalizer.parse open(uri)
    end
    
  rescue
    puts "feed fetch error! page:#{page} - #{uri}"
    errors.push(page)
    next
  end
  
  puts uri
  feed.entries.each{ |e|
    if Post.find_by_uri(e.url) == nil
      post = Post.create(:uri => e.url,
                         :message => e.content.toutf8,
                         :time => e.last_updated.to_s)
      puts post
    end
  }
  puts "-----page:#{page} (page#{ARGV.join(',')}) finished-----"
}

if errors.size > 0
  print "feed fetch error at page:"
  puts errors.join(' ')
end