• SIS Lab
  • >
  • Blog
  • >
  • mixiで全文検索するプログラムをRubyで作ってみた

mixiで全文検索するプログラムをRubyで作ってみた

更新日:2017.12.18 作成日:2009.07.29

基本的には、 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 = "[email protected]"
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

Related contents