mixiで全文検索するプログラムをRubyで作ってみた
移転しました。
基本的には、http://d.hatena.ne.jp/con_mame/20080726でのソースを参考にさせていただきました。ありがとうございます。
しかし、そのままでは、日記の本文を取得できなかったため四苦八苦・・・。超応急処置で乗りきりました。
$body[date] = ($agent.get(BASE_URL+"view_diary.pl?id=#{list}&owner_id=#{id}")).search('#diary_body').inner_text
ちょうどこの部分。search('hogehoge')でid=hogehogeの部分を探し、inner_textでその中身を読み取る。
これで、昔、日記書いたけどいつだったかなぁ?ってときに検索することができます。
# -*- coding: utf-8 -*- require 'rubygems' require 'mechanize' require 'hpricot' require 'kconv' $KCODE = 'UTF8' BASE_URL = 'http://mixi.jp/' NIKKI_LIST = BASE_URL + 'list_diary.pl' DEFO = "自分のmixi_id" MAIL = "hoge@hoge.jp" PASS = "PASSWORD" #ファイル関係を処理 def create_data_file(id) $file_name = "diary-#{id}.dump" if File.exist?($file_name) puts "LOADING..." $title = Marshal.load(open($file_name, "rb"))[0] $body = Marshal.load(open($file_name, "rb"))[1] $newest = Marshal.load(open($file_name, "rb"))[2][0].to_i else puts "NEW FILE" $title = {} $body = {} $newest = 0 end end #ログイン処理 def login $agent = WWW::Mechanize.new $agent.max_history = 1 $agent.user_agent_alias = 'Windows IE 6' login = $agent.get(BASE_URL) login_form = login.forms[0] login_form["email"] = MAIL login_form["password"] = PASS $agent.submit(login_form) end #日記の取得 def get_nikki(id, page=1) flag = false print "id:#{id}の#{page}ページ目を取得開始します\n" nikki_list = Kconv.toutf8($agent.get(NIKKI_LIST+"?page=#{page}&id=#{id}").body) lists = nikki_list.scan(/view_diary.pl\?id=(\d+)&owner_id=\d+/).uniq #intに直す $listsi = [] lists.each do |list| $listsi << list[0].to_i end #各日記の本文などを取得 $listsi.each do |list| if list[0].to_i > $newest flag = true nikki = Kconv.toutf8($agent.get(BASE_URL+"view_diary.pl?id=#{list}&owner_id=#{id}").body) #日付をi取得 date = nikki.scan(/<dd>(\d{4})年(\d{2})月(\d{2})日(\d{2}:\d{2})<\/dd>/).join("/") #タイトルを取得 $title[date] = nikki.scan(/\[mixi\] (.+)<\/title>/)[0] #本文を取得 # $body[date] = nikki.scan(/\"diary_body\">([\s\S]+)<\div>\n<script/)[0] # $body[date] = nikki.scan(/\[mixi\] (.+)<\/title>/)[0] $body[date] = ($agent.get(BASE_URL+"view_diary.pl?id=#{list}&owner_id=#{id}")).search('#diary_body').inner_text sleep 2 end end $body.keys.each do |key| begin $body[key] = $body[key][0].gsub("<br />", "\n") rescue #エラー end end if !flag puts "変更なし" return elsif flag && $newest != 0 $newest = $listsi.max puts "更新しました->#{$newest}" elsif nikki_list.scan(/<a href="list_diary.pl?.*">次を表示<\/a>/)[0] sleep 1 get_nikki(id, page+1) else $newest = $listsi.max puts "最新をセット->#{$newest}" end end #いろいろ検索 def search(num) if num == "1" print "yyyy/mm/ddを入力してください:" date = gets.chop hits = 0 $title.keys.each do |key| if key.rindex(date) hits = hits+1 puts key.to_s + " , " + $title[key][0] puts $body[key] end end puts "#{hits}件ヒットしました" elsif num == "2" print "検索文字列を入力してください: " word = gets.chop hits = 0 $title.keys.each do |key| next if $title[key].nil? if $title[key].rindex(word) || $body[key].rindex(word) hits = hits+1 puts key.to_s + " , " + $title[key][0] puts $body[key] end end puts "#{hits}件ヒットしました" elsif num == "3" hits = 0 $title.keys.sort.each do |key| puts key.to_s + " , " + $title[key][0] puts $body[key] end elsif num == "4" exit else puts "えらーーーーーーーー" end end print "誰を探す?: " mixiid = gets.chop mixi_id = (mixiid == "")? DEFO : mixiid create_data_file(mixi_id) login get_nikki(mixi_id) #シリアライズ nikkis = [$title, $body, $newest] File.open($file_name,"wb"){|f| Marshal.dump(nikkis, f) } while(1) print "\n1:指定日の日記 2:全文検索 3:全日記表示 4:終了\n" print "# " input = gets.chop search(input) end