0
0

【ブロガー向け】MovableType形式の.txtファイルをBlogger用XMLに変換するPythonスクリプト

Posted at

はじめに

はてなブログからエクスポートされる記事は、MovableType形式のテキストファイルとしてダウンロードされますが、GoogleのBloggerにインポートする際にはXML形式が必要です。このブログ記事では、MovableType形式の.txtファイルをBlogger用のXML形式に変換するためのPythonスクリプトを紹介します。

注意: 本スクリプトは、MovableType形式のファイルをBlogger用XMLに変換することを目的としていますが、MovableType形式やBloggerの仕様変更、特定のエクスポートファイルの形式によっては正常に動作しない場合があります。万が一のエラーや問題についてはご了承ください。

スクリプトの概要

このスクリプトは、MovableType形式の.txtファイルを読み込み、記事を解析し、Bloggerに適した形式に変換します。最終的にXMLファイルとして出力され、これをBloggerにインポートすることで簡単に記事を移行できます。

作成したコード

import re
from datetime import datetime
from xml.etree.ElementTree import Element, SubElement, ElementTree, tostring

# MovableType形式の.txtファイルを読み込む
def read_mt_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        return file.read()

# MT形式のテキストから記事ごとに分割
def split_entries(mt_text):
    return re.split(r'--------\n', mt_text)

# MT形式の各フィールドをパースして辞書にする
def parse_entry(entry_text):
    entry = {}
    patterns = {
        'author': r'AUTHOR:\s*(.*)',
        'title': r'TITLE:\s*(.*)',
        'date': r'DATE:\s*(\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2})',
        'body': r'BODY:\n(.*?)(?=\n-----|\Z)',
    }

    for key, pattern in patterns.items():
        match = re.search(pattern, entry_text, re.DOTALL)
        if match:
            entry[key] = match.group(1).strip()

    # 日付をBlogger用にフォーマット変更
    if 'date' in entry:
        entry['date'] = format_date(entry['date'])

    return entry

# 日付のフォーマットをBlogger用に変換
def format_date(date_str):
    try:
        date_str = date_str.strip()
        date_obj = datetime.strptime(date_str, '%m/%d/%Y %H:%M:%S')
        return date_obj.strftime('%Y-%m-%dT%H:%M:%S') + '+09:00'
    except ValueError as e:
        print(f"Error parsing date, attempting alternative formats: {date_str}")
        try:
            date_obj = datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
            return date_obj.strftime('%Y-%m-%dT%H:%M:%S') + '+09:00'
        except ValueError:
            raise e

# XMLの構築
def create_xml(entries):
    root = Element('feed', xmlns="http://www.w3.org/2005/Atom")
    for entry in entries:
        entry_elem = SubElement(root, 'entry')
        author_elem = SubElement(entry_elem, 'author')
        name_elem = SubElement(author_elem, 'name')
        name_elem.text = entry.get('author', 'Unknown')

        title_elem = SubElement(entry_elem, 'title')
        title_elem.text = entry.get('title', 'No Title')

        published_elem = SubElement(entry_elem, 'published')
        published_elem.text = entry.get('date', '')

        content_elem = SubElement(entry_elem, 'content', type="html")
        content_elem.text = entry.get('body', '')

    return root

# XMLをファイルに保存
def save_xml_file(root, output_path):
    tree = ElementTree(root)
    tree.write(output_path, encoding='utf-8', xml_declaration=True)

# メイン処理
def main(mt_file_path, output_xml_path):
    mt_text = read_mt_file(mt_file_path)
    entry_texts = split_entries(mt_text)

    entries = []
    for entry_text in entry_texts:
        if entry_text.strip():
            entries.append(parse_entry(entry_text))

    xml_root = create_xml(entries)
    save_xml_file(xml_root, output_xml_path)
    print(f"XMLファイルが生成されました: {output_xml_path}")

# 使用例
mt_file_path = 'input/xxx.hatenablog.com.export.txt'
output_xml_path = 'output/output_blogger.xml'
main(mt_file_path, output_xml_path)

スクリプトの説明

以下は、スクリプト全体の説明です。

最初に、必要なライブラリをインポートします。reは正規表現を使って記事を解析し、datetimeは日付のフォーマット変換、ElementTreeはXMLを生成するために使用します。

import re
from datetime import datetime
from xml.etree.ElementTree import Element, SubElement, ElementTree, tostring

MovableType形式の.txtファイルを読み込む
この関数は、MovableType形式の.txtファイルをUTF-8で読み込み、その内容を文字列として返します。

def read_mt_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        return file.read()

記事の分割と解析
記事は「--------」で区切られているので、この正規表現を使用して記事を分割します。

def split_entries(mt_text):
    return re.split(r'--------\n', mt_text)

この記事を解析し、author(著者)、title(タイトル)、date(日付)、body(本文)のフィールドを抽出します。

def parse_entry(entry_text):
    entry = {}
    patterns = {
        'author': r'AUTHOR:\s*(.*)',
        'title': r'TITLE:\s*(.*)',
        'date': r'DATE:\s*(\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2})',
        'body': r'BODY:\n(.*?)(?=\n-----|\Z)',
    }
    for key, pattern in patterns.items():
        match = re.search(pattern, entry_text, re.DOTALL)
        if match:
            entry[key] = match.group(1).strip()
    if 'date' in entry:
        entry['date'] = format_date(entry['date'])
    return entry

日付フォーマットの変換
MovableType形式の日付をBlogger用に変換するため、この関数を使用します。もし異なる日付形式が検出された場合には、バックアップフォーマットで再度試行します。

def format_date(date_str):
    try:
        date_str = date_str.strip()
        date_obj = datetime.strptime(date_str, '%m/%d/%Y %H:%M:%S')
        return date_obj.strftime('%Y-%m-%dT%H:%M:%S') + '+09:00'
    except ValueError as e:
        print(f"Error parsing date, attempting alternative formats: {date_str}")
        try:
            date_obj = datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
            return date_obj.strftime('%Y-%m-%dT%H:%M:%S') + '+09:00'
        except ValueError:
            raise e

XMLの生成
この関数では、Bloggerに対応するXML形式を生成します。それぞれの記事の著者、タイトル、本文などをXMLの要素として追加します。

def create_xml(entries):
    root = Element('feed', xmlns="http://www.w3.org/2005/Atom")
    for entry in entries:
        entry_elem = SubElement(root, 'entry')
        author_elem = SubElement(entry_elem, 'author')
        name_elem = SubElement(author_elem, 'name')
        name_elem.text = entry.get('author', 'Unknown')

        title_elem = SubElement(entry_elem, 'title')
        title_elem.text = entry.get('title', 'No Title')

        published_elem = SubElement(entry_elem, 'published')
        published_elem.text = entry.get('date', '')

        content_elem = SubElement(entry_elem, 'content', type="html")
        content_elem.text = entry.get('body', '')

    return root

XMLファイルの保存
生成されたXMLをファイルとして保存します。

def save_xml_file(root, output_path):
    tree = ElementTree(root)
    tree.write(output_path, encoding='utf-8', xml_declaration=True)

実行方法
最後に、メインの処理です。
main関数では、MovableType形式のファイルを読み込み、記事ごとに解析し、XMLファイルを生成します。

def main(mt_file_path, output_xml_path):
    mt_text = read_mt_file(mt_file_path)
    entry_texts = split_entries(mt_text)

    entries = []
    for entry_text in entry_texts:
        if entry_text.strip():
            entries.append(parse_entry(entry_text))

    xml_root = create_xml(entries)
    save_xml_file(xml_root, output_xml_path)
    print(f"XMLファイルが生成されました: {output_xml_path}")

使用例
はてなブログからエクスポートしたMovableType形式の.txtファイルをBlogger用のXMLファイルに変換し、output/output_blogger.xmlに保存します。

mt_file_path = 'input/xxx.hatenablog.com.export.txt'  # はてなブログからエクスポートした.txtファイルのパス
output_xml_path = 'output/output_blogger.xml'  # 変換後のXMLファイルの保存先
main(mt_file_path, output_xml_path)

おわりに

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0