はてなダイアリーからのトラックバックの移行(その2)

前回の続きです。

インポート開始

はてなブログ(このブログ)からのはてなダイアリーのインポートを開始しました。が、まだ終わっていません。

ただいまインポートが集中しており、記事の件数によっては完了するまでに数日以上かかる場合があります。

数日って… とりあえずその間に色々準備していきたいと思います。

ちなみにインポートしただけではダイアリーとブログが併存する状態になるようで、続けてリダイレクト設定をするまではダイアリーにアクセスできるようです。

記事件数のチェック

はてなの日記データ形式」でエクスポートした XML ファイルから、こんなスクリプトで記事の URL を抽出しました。色々手抜きですが…

#!/usr/bin/env ruby
# coding: utf-8

URL_BASE = "http://d.hatena.ne.jp/rna"
day = nil
p = 0
ARGF.each_line() { |line|
  if /^<day date="([^"]+)"/.match(line) then
    day = $1.gsub(/-/, "")
    p = 1
  elsif /^\*\*/.match(line)
    next
  elsif /^\*(([^*]+)\*)?(.*)/.match(line)
    para =  $2 ? $2 : "p#{p}"
    p += 1 unless $2
    puts "- url: #{URL_BASE}/#{day}/#{para}"
  end
}

どこが手抜きかというと、以下のようなところ。

  • XML をパースしてない。でも機械生成のファイルなのでこれでもなんとかなるでしょう…
  • 下書き記法の中のセクションもカウントしてしまう。
  • 下書きがセクションとセクションの間にある場合、無名セクションに付与するセクション名("p1" とか)が実際と異なる。
  • 同じ日にセクション名が重複したセクションが複数ある時に無名セクションに自動付与するセクション名("p1" とか)が実際と異なる。
    • これはダイアリーの archive ページでも間違えていて、archive の一覧のリンク先が別の記事になってしまっている。

幸い僕のダイアリーの場合は下書きセクションは常に日記の末尾にあったので上のバグの影響は受けませんでした。セクション名の重複によるバグは一か所ありましたが、これは手動で処理しようと思います。

上のスクリプトでカウントした記事数は 2060 件、前回のスクレイピングスクリプトで処理した記事数は 2048 件で、12 件のズレがありましたが、これは全部下書きの中のセクションがカウントされたせいでした。

が、はてなブログのインポート画面には「投稿数 2119」との表示が。71件も差があるのですがこれは… セクションの数しか数えていないので、日記の冒頭から最初のセクションまでの間に何か書いたもの(仮に匿名セクションと呼びます)がカウントされていないとか?

こんなスクリプトで確認。

#!/usr/bin/env ruby
# coding: utf-8

i = 0
date = nil
before_section = false
ARGF.each_line() { |line|
  if /^<day date="([^"]+)"/.match(line) then
    date = $1
    before_section = true
  elsif /^<\/day>/.match(line)
    before_section = false
  elsif /^<body>/.match(line)
    next
  elsif /^<\/body>/.match(line)
    next
  elsif /^\s*$/.match(line)
    next
  elsif /^\*\*/.match(line)
    next
  elsif /^\*(([^*]+)\*)?(.*)/.match(line)
    before_section = false
  elsif before_section
    i += 1
    puts "#{date}: #{line}"
    before_section = false
  end
}
puts "total: #{i}"

71件出てきました。推測通りのようです。

匿名セクションには permalink がなく、トラックバックを受け取れないので、トラックバック移行作業には影響ないと思ったのですが、idトラックバックがありますね… idトラックバックは日記単位で受信されて、その日の全エントリに表示されるので、匿名セクション由来のエントリにも表示した方がいいような…

匿名セクション用のトラックバックを抽出する

前回ダウンロードしたファイルには日記ページ(http://d.hatena.ne.jp/rna/20040226 のような)のファイルがあるので、それらを入力にして匿名セクションのある日記だけ、その日のidトラックバックデータを抽出するスクリプトを書いてみた。

2019-01-24: 以下のスクリプトにはバグがありました。その3 に修正版を掲載しました。

#!/usr/bin/env ruby
# coding: utf-8

require 'nokogiri'

def parse_diary_html_file (file)
  f = File.open(file, "r:euc-jp")
  html = f.read().encode("utf-8", { :invalid => :replace, :undef => :replace })
  f.close
  doc = Nokogiri::HTML::Document.parse(html)
  first_section = doc.css("div.body > div.section")[0]
  if first_section && first_section.css("h3").length == 0 then
    puts "- url: " + doc.css("div.day > h2 > a").attribute("href")
    doc.css("div.refererlist").each { |div|
      type = div.css("div.caption > a").attribute("name")
      puts "  idtb:"
      div.css("ul > li").each { |li|
        puts '    - ' + li.css("a").to_s
      }
    }
  end
end

ARGV.each { |file|
  begin
    parse_diary_html_file(file)
  rescue => e
    STDERR.puts "#{file}: #{e}"
  end
}

71件分抽出できたので、たぶんこれで全部取れたはず。

今後の予定

  • インポート完了を待つ…
  • リダイレクト設定
  • はてなブログライター形式でブログエントリを全件ダウンロード
  • 移行前のURLと移行後のURLの対応表を作る
    • 実際にリダイレクトさせて確認するしかない?
  • ダウンロードしたエントリファイルの末尾にトラックバックを追加
  • はてなブログライターでエントリを更新