nipeblog

はてなブログの記事をmicroCMSに移行する

個人ブログをはてなブログからmicroCMSにお引越ししました。 実際に使った移行スクリプトを含めてステップバイステップの手順を説明しているので、microCMSにデータを移行したい人の参考になれば嬉しいです。

はてなブログの記事をmicroCMSに移行する流れ

はてなブログの記事をmicroCMSに移行する流れは次のとおりです。

はてなブログからmicroCMSに移行する流れ
  1. はてなブログから記事をエクスポート
  2. エクスポートしたデータをJSON形式に変換
  3. microCMSのAPIで記事データを登録

2と3ではそれぞれChatGPTにスクリプトを作成したこともあり、トータル30分ぐらいで移行ができました。

ステップ1. はてなブログから記事をエクスポート

はてなブログのエクスポート機能を使って記事データをダウンロードします。

注意点として、はてなブログのエクスポート機能では、エクスポートできるのは記事本文とコメントのテキストデータのみで、写真やイラストなどはエクスポートできないようです。

エクスポート画面から記事データをMT(Movable Type)形式でダウンロードできます。

はてなブログのエクスポート画面

ダウンロードされたファイルは次のようなテキストデータとして出力されます。

AUTHOR: はてなアカウント名
TITLE: 記事タイトル
BASENAME: 記事のパス
STATUS: Publish
ALLOW COMMENTS: 1
CONVERT BREAKS: 0
DATE: 10/21/2024 12:00:00
CATEGORY: カテゴリー
IMAGE: サムネイル画像のURL
-----
BODY:
<p>記事本文</p>
-----
--------
...次の記事に続く...

ステップ2. エクスポートしたデータをJSON形式に変換

記事データの取り扱いをしやすくするために、エクスポートしたMT形式テキストファイルをJSON形式のテキストファイルに変換します。

変換スクリプトは、ChatGPTにRubyスクリプトとして作成してもらいました。スクリプトの内容としては、MT形式のテキストファイルから、「記事タイトル」と「本文」を抽出して、JSON形式に変換しています。

サムネイル画像も抽出してmicroCMSに登録もできますが、サムネイルを設定している記事が少なかったので今回は実施しませんでした。

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

entries = []
current_entry = {}
in_metadata = true
reading_body = false

unless ARGV.size == 1
  STDERR.puts "Usage: ruby #{$0} input.mt"
  exit 1
end

filename = ARGV[0]
lines = File.read(filename, encoding: 'UTF-8').lines.map(&:chomp)

lines.each do |line|
  case line
  when '--------'
    # エントリ終了
    unless current_entry.empty?
      # aタグを除外する処理
      current_entry["BODY"] = current_entry["BODY"].gsub(/<a class=\"keyword\".*?>(.*?)<\/a>/, '\1').gsub(/<a .*? class=\"keyword\">(.*?)<\/a>/, '\1')
      entries << {
        "title" => current_entry["TITLE"] || "",
        "content" => current_entry["BODY"] || ""
      }
    end
    current_entry = {}
    in_metadata = true
    reading_body = false

  when '-----'
    # セクション切り替え
    if in_metadata
      # メタ情報ブロック終了、次にBODY部が来る可能性
      in_metadata = false
    elsif reading_body
      # BODY部終了
      reading_body = false
    else
      # BODY開始前後での余分な区切りは特に処理しない
    end

  else
    # 通常行の処理
    if in_metadata
      # メタ情報行処理
      if line =~ /^TITLE:\s*(.*)$/
        current_entry["TITLE"] = $1
      elsif line =~ /^BODY:\s*(.*)$/
        # BODY開始行
        in_metadata = false
        reading_body = true
        current_entry["BODY"] = ($1 && !$1.empty?) ? $1 + "\n" : ""
      end
      # 他のメタ情報は無視可能

    elsif reading_body
      # BODY読み込み中
      current_entry["BODY"] ||= ""
      current_entry["BODY"] << line + "\n"
    else
      # メタ情報終了後、BODY開始前に行がある場合(通常想定外)は無視
      if line =~ /^BODY:\s*(.*)$/
        reading_body = true
        current_entry["BODY"] = ($1 && !$1.empty?) ? $1 + "\n" : ""
      end
    end
  end
end

# 最終エントリがあり、'--------'で閉じていない場合も追加
unless current_entry.empty?
  # aタグを除外する処理
  current_entry["BODY"] = current_entry["BODY"].gsub(/<a class=\"keyword\".*?>(.*?)<\/a>/, '\1').gsub(/<a .*? class=\"keyword\">(.*?)<\/a>/, '\1')
  entries << {
    "title" => current_entry["TITLE"] || "",
    "content" => current_entry["BODY"] || ""
  }
end

puts JSON.pretty_generate(entries)

このスクリプトを次のコマンドで実行するとJSON形式のテキストファイルに変換できます。

ruby mt2json.rb <エクスポートしたテキストファイル> > articles.json

作成したJSON形式のテキストファイルは次のようになります。

「記事タイトル」と「本文」が抽出できていることが確認できます。

[
  {
    "title": "記事タイトル",
    "content": "<p>本文</p>"
  },
  {
    // 次の記事 ...
  }
]

ステップ3. microCMSのAPIで記事データを登録

microCMSの POST /api/v1/{endpoint} を使うことで、簡単にmicroCMSに記事を登録することができます。

このAPIを使うには、APIキーで「POST」の権限を有効にしておく必要があります。※APIの権限変更は扱いに注意が必要なので、自信がない方は ヘルプページのAPIキー を読むことをおすすめします。

APIキーでPOSTの権限を有効化させる

microCMS上のAPIスキーマは次のように titlecontent を用意しておきます。

microCMSのAPIスキーマ

この「コンテンツ(API)」に作成したJSONファイルの内容を登録していきます。

ここでも、ChatGPTでRubyの移行スクリプトを作成しました。少しだけ手直ししていますが、内容としてはJSONを読み込んで POST /api/v1/{endpoint} をリクエストして記事を登録しています。

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

require 'net/http'
require 'uri'
require 'json'

# MicroCMSのAPIキー
microcms_api_key = ENV['MICROCMS_API_KEY']
if microcms_api_key.nil?
  STDERR.puts "MICROCMS_API_KEY is not set."
  exit 1
end

service_id = ENV['MICROCMS_SERVICE_ID']
if service_id.nil?
  STDERR.puts "MICROCMS_SERVICE_ID is not set."
  exit 1
end

endpoint = ENV['MICROCMS_ENDPOINT']
if endpoint.nil?
  STDERR.puts "MICROCMS_ENDPOINT is not set."
  exit 1
end


# 入力JSONファイルの読み込み
unless ARGV.size == 1
  STDERR.puts "Usage: ruby #{$0} input.json"
  exit 1
end

json_data = File.read(ARGV[0])

# ヘッダー情報
headers = {
  'X-MICROCMS-API-KEY' => microcms_api_key,
  'Content-Type' => 'application/json'
}

# JSONデータを配列として解析
data = JSON.parse(json_data)

# 配列の各レコードをループして送信
data.each do |record|
  # APIへのリクエストを構築
  uri = URI.parse("https://#{service_id}.microcms.io/api/v1/#{endpoint}")
  request = Net::HTTP::Post.new(uri, headers)
  request.body = record.to_json  # 各レコードを送信

  # HTTPリクエストの実行
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true  # HTTPSを使用する場合
  response = http.request(request)

  # レスポンスを表示
  puts "Response code: #{response.code}"
  puts "Response body: #{response.body}"
end

作成したRubyスクリプトを実行します。

MICROCMS_API_KEY=<APIキー> \
MICROCMS_SERVICE_ID=<サービスID> \
MICROCMS_ENDPOINT=<エンドポイント名> \
ruby json2microcms.rb articles.json

スクリプトが成功すると、microCMSで記事が登録されていることが確認できるはずです🎉

まとめ

今回は、はてなブログの記事をmicroCMSに移行する方法を紹介しました。

流れとしては次の3ステップです。

  1. はてなブログから記事をエクスポート
  2. エクスポートしたデータをJSON形式に変換
  3. microCMSのAPIで記事データを登録

30分ぐらいで移行ができるので、興味がある方はぜひ試してみてください。

補足で、microCMSではテンプレートが用意されているので簡単に綺麗な画面を作ることも可能です。

microCMSのテンプレート