BLOG

ブログ

WordPressの記事をmicroCMSへ移行する4ステップ

こんにちは!長谷です。

たったの4ステップでWordPressの記事をmicroCMSに移行する方法を解説します!

Pythonを使用しますが、Pythonを使ったことが無い方もインストール方法も書いているので参考にしてみてください!

STEP01 WordPressの管理画面から記事の情報をエクスポートする

WordPressの管理画面を開き、[ツール]→[エクスポート]で以下の画面が表示されます。

このメニューが表示されていない場合はユーザーの権限を確認してみてください。
(権限が[管理者]なら表示されましたが、[編集者]では表示されませんでした。)

[エクスポートファイルをダウンロード]でXMLファイルがダウンロードされます。
今回は公開済みのページのみ移行するため、ステータスは[公開済み]を選択しました。

STEP02 microCMSのAPIの追加と設定

WordPressに合わせてmicroCMSのAPIを作成し、APIスキーマを設定します。

今回は「タイトル」「カテゴリー」「内容」「公開日」が移行対象なので、これに沿ってAPIスキーマを設定しました。

カテゴリーは複数選択できるように[複数コンテンツ参照]にしてます。

カテゴリーのAPIを作成し、こちらもAPIスキーマを設定します。

カテゴリーAPIにはあらかじめカテゴリーを追加しておきます。

STEP03 microcms用にデータを加工

STEP01でダウンロードしたXMLファイルから必要な情報を抽出し、microCMSにPOSTできる形に加工します。

Pythonのインストール

Homebrewを使ったPythonのインストール

Homebrewを使用してPythonをインストールするには、ターミナルに以下のコマンドを入力します。

brew install python

インストールが成功したかどうかを確認するには、以下のコマンドを使用します。

python3 --version

「Python 3.9.6」のようにPythonのバージョンが表示されたら、インストールは成功です!

実際にコードを書いていきます。
このファイルと、STEP01でエクスポートしたxmlファイルを同じディレクトリに保存してください。

必要なライブラリのインストール

requestsライブラリを使用しますので、以下のコマンドでインストールします。

pip3 install requests
import xml.etree.ElementTree as ET
import requests
import json
from datetime import datetime

# 設定
xml_file_path = 'wp.xml'  # WordPressのエクスポートファイルのパス
api_key = 'XXXXXXXXXXXXXXXXX'  # microCMSのAPIキー
posts_endpoint = 'https://XXXXX.microcms.io/api/v1/XXXXX'  # 記事をPOSTするエンドポイント
category_endpoint = 'https://XXX.microcms.io/api/v1/XXXXX'  # カテゴリー情報を取得するエンドポイント
headers = {'Content-Type': 'application/json', 'X-API-KEY': api_key}

# microCMSからカテゴリーデータを取得してカテゴリー名からIDをマッピング
category_response = requests.get(category_endpoint, headers=headers)
if category_response.status_code == 200:
    categories = category_response.json()['contents']
    category_name_to_id = {cat['name']: cat['id'] for cat in categories}
else:
    category_name_to_id = {}

# XMLファイルを解析
tree = ET.parse(xml_file_path)
root = tree.getroot()

# 各記事について処理
for item in root.findall('channel/item'):
    title = item.find('title').text
    content_encoded_element = item.find('content:encoded', namespaces={'content': 'http://purl.org/rss/1.0/modules/content/'})
    if content_encoded_element is None or content_encoded_element.text is None:
        continue
    content_encoded = content_encoded_element.text

    # 記事の日付をISOフォーマットに変換
    pub_date = item.find('pubDate').text
    pub_date_iso = datetime.strptime(pub_date, '%a, %d %b %Y %H:%M:%S %z').isoformat()

    # 記事に関連するカテゴリーを抽出しIDを取得
    article_categories = [category.text for category in item.findall('category')]
    article_category_ids = [category_name_to_id.get(cat) for cat in article_categories if cat in category_name_to_id]

    # 記事データを作成してPOST
    post_data = {
        'title': title,
        'content': content_encoded,
        'published_at': pub_date_iso,
        'categories': article_category_ids
    }
    response = requests.post(posts_endpoint, headers=headers, data=json.dumps(post_data))

処理ごとに解説していきます!

import xml.etree.ElementTree as ET
import requests
import json
from datetime import datetime

必要なライブラリをインポートしてます。
こちらのライブラリは、XMLの解析(xml.etree.ElementTree)、HTTPリクエストの送信(requests)、JSONの操作(json)、日付と時間の操作(datetime)に使用します。

xml_file_path = 'wp.xml'  # WordPressのエクスポートファイルのパス
api_key = 'XXXXX'  # microCMSのAPIキー
posts_endpoint = 'https://XXXXX.microcms.io/api/v1/XXXXX'  # 記事をPOSTするエンドポイント
category_endpoint = 'https://XXX.microcms.io/api/v1/XXXXX'  # カテゴリー情報を取得するエンドポイント
headers = {'Content-Type': 'application/json', 'X-API-KEY': api_key}

WordPressのエクスポートファイルのパス、microCMSのAPIキー、記事をPOSTするエンドポイント、カテゴリー情報を取得するエンドポイント、リクエストヘッダーを設定しています。

category_response = requests.get(category_endpoint, headers=headers)
if category_response.status_code == 200:
    categories = category_response.json()['contents']
    category_name_to_id = {cat['name']: cat['id'] for cat in categories}
else:
    category_name_to_id = {}

microCMSのAPIを使用してカテゴリー情報を取得し、その情報を用いてカテゴリー名からIDへのマッピングを作成します。

tree = ET.parse(xml_file_path)
root = tree.getroot()

xml.etree.ElementTreeライブラリを使用してXMLファイルを解析し、そのルートエレメントを取得します。このルートエレメントは、後の処理で各記事の情報を取得するために使用します。

for item in root.findall('channel/item'):

XMLのルートエレメントから各記事の情報を含むエレメントを見つけ、ループ処理を行います。

title = item.find('title').text

各記事エレメントからtitleエレメントを見つけ、その記事のタイトルを取得します。

content_encoded_element = item.find('content:encoded', namespaces={'content': 'http://purl.org/rss/1.0/modules/content/'})
if content_encoded_element is None or content_encoded_element.text is None:
    continue
content_encoded = content_encoded_element.text

各記事エレメントからcontent:encodedエレメントを見つけます。
namespaces={'content': '<http://purl.org/rss/1.0/modules/content/>'}という部分は、content:encodedエレメントが特定の名前空間(http://purl.org/rss/1.0/modules/content/)を使用していることを指定しています。
content:encodedエレメントのテキスト内容が存在していたらそのテキスト内容(記事の本文)を取得します。

pub_date = item.find('pubDate').text
pub_date_iso = datetime.strptime(pub_date, '%a, %d %b %Y %H:%M:%S %z').isoformat()

各記事エレメントからpubDateエレメントを見つけ、そのテキスト内容(記事の公開日)を取得し、ISO 8601形式に変換します。

article_categories = [category.text for category in item.findall('category')]
article_category_ids = [category_name_to_id.get(cat) for cat in article_categories if cat in category_name_to_id]

各記事エレメントからcategoryエレメントを全て見つけ、そのテキスト内容(記事のカテゴリー)を取得し、それらを対応するIDに変換します。

post_data = {
    'title': title,
    'content': content_encoded,
    'published_at': pub_date_iso,
    'categories': article_category_ids
}
response = requests.post(posts_endpoint, headers=headers, data=json.dumps(post_data))

取得した記事のタイトル、本文、公開日、カテゴリーIDを用いてPOSTデータを作成し、 そのデータをmicroCMSに送信します。

STEP04 microCMSにPOSTする

microCMSのAPIキーの権限を変更します。

※外部からの書き込みが可能になってしまうため、取り扱いにはご注意ください。

STEP03で作成したコードを実行する

python 保存したファイル名.py

microCMSの管理画面を見ると、記事が入稿されていました!

最後に

WordPressからmicroCMSへの記事移行の方法をご紹介しました!

microCMSはCSVファイルによるコンテンツのインポート機能もありますが、記事が0の状態でのみ実行できたり、自分がかなり躓いてしまいなかなかスムーズに移行できなかったため、同じように悩んでいる方はぜひ試してみてください!

補足ですが、microCMSの公式でWordPressからの移行アシストツールが実装予定のようです!
microCMS 開発ロードマップ

楽しみにしつつ、それまではこちらの方法等で試してみてください!

RELATED ARTICLE