エキブロから過去のブログを移行するツール出来た!
エキサイトブログからのデータ移行ツールを現在開発中 - インターネット時代のキャリアプランとは?というエントリを以前書いて放置していたツールですが、なんとか完成しました。
はてなへデータを取り込む時にはMT形式にするんだけど、ブログ投稿日付のフォーマットが
エキブロの場合:yyyy-mm-dd hh::mm
MT形式:mm/dd/yyyy hh:mm:ss (PM/AM)
という感じでそれぞれ異なるために、この処理をどうすればいいのかちょっと悩んだけど、Nokogiriで取得した日付の情報が文字列として内部的に保持されているようなので
_date = ParseDate::parsedate(doc.search('span[@class="TIME"]/a').text)
とすると、配列_dateには、先頭から順番にyyyy,mm,dd,hh,mm の値が格納されているのでそれをTime.local()の引数にこんな感じで与えてから、strftime()を下記のように指定して意図した通りにMT形式に変換できました。(これについては2009-05-15 - 篳篥日記がとても参考になった!)
@post_date = Time.local(_date[0],_date[1],_date[2],_date[3],_date[4],0,0,0).strftime("%m/%d/%Y %I:%M:%S %p")
後の処理は基本的にそれほど戸惑わなかったんだけど、一気に全件取得しようとすると
/opt/local/lib/ruby/1.8/tempfile.rb:61:in `initialize': Too many open files - /var/folders/Gn/GnpE+3RxF8OkkSkIlYpQok+++TI/-Tmp-/open-uri20100212-6841-oyu4w5-0 (Errno::EMFILE)
と怒られてしまい、Bug #2067: bodyが大きいエラーページをopen-uriで取得するとfdがリークしている - Ruby 1.8 - Ruby Issue Tracking Systemなんかの情報を見た感じでは、とりあえず全件まとめてではなく、小分けに処理した方が良さそうなので、最初に読み込むページと、終了ページを指定した上で処理を行う形に切り替えました。
出来たツールはこんな感じ
require 'rubygems' require 'nokogiri' require 'open-uri' require 'erb' require 'parsedate' class Exblog2MT def initialize(start_url, last_url, file_name) @start_url = start_url @last_url = last_url @file_name = file_name end attr_accessor :post_date, :html_body, :result, :title def start_parse self.move_to(@start_url) end def get_contens(url) begin doc = Nokogiri::HTML(open(url)) rescue OpenURI::HTTPError => e e.io.close end _date = ParseDate::parsedate(doc.search('span[@class="TIME"]/a').text) @post_date = Time.local(_date[0],_date[1],_date[2],_date[3],_date[4],0,0,0).strftime("%m/%d/%Y %I:%M:%S %p") @title = doc.search('//div[@class="POST_TTL"]').text @html_body = doc.search('//div[@class="POST_BODY"]').inner_html temp = File.open("exblog2MT.tmpl") { |f| f.read } @result = ERB.new(temp, nil, '-') begin f = File.open(@file_name,"a") f.puts @result.result(binding) f.close rescue OpenURI::HTTPError => e e.io.close end end def move_to(url) doc = Nokogiri::HTML(open(url)) loop do _nextlink="" self.get_contens(url) doc.search('td[align="RIGHT"][width="48%"]').map { |link| _nextlink=link.search('@href').text } if _nextlink == @last_url then exit else move_to(_nextlink) end end end end start_url = "http://dmyoh.exblog.jp/4048814/" last_url = "http://dmyoh.exblog.jp/4927299/" file_name = "exblog-xxxx.txt" exblog = Exblog2MT.new(start_url, last_url, file_name) exblog.start_parse
ERB.newで指定したテンプレートはこんな感じのものを準備しておきました
AUTHOR: h5y1m141
TITLE: <%= @title %>
STATUS: Publish
ALLOW COMMENTS: 1
CONVERT BREAKS: 1
ALLOW PINGS: 1
DATE: <%= @post_date %>
-
-
-
- -
-
-
BODY:<%= @html_body %>
-
-
-
- -
-
-
EXTENDED BODY:
-
-
-
- -
-
-
EXCERPT:
-
-
-
- -
-
-
KEYWORDS:
-
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-
-
-
-