WordPressのブログを静的サイトに書き換えてみました

WordPressで作ったブログサイトを、静的サイトに変換してみました。変換先のサイトはSphinxで作りました。

目次

  1. WordPressサイトをSphinxで作り直したい
  2. 方針
  3. WordPressからエクスポートする
  4. エクスポートしたデータから記事を取り出す
  5. reStructuredTextに変換する

WordPressサイトをSphinxで作り直したい

WordPressは超便利なCMSです。WordPressを使うと簡単にいろいろなことができます。いろいろなテーマがあって、美しいサイトを簡単に構築できます。しかも、インストール型のWordPressであれば基本的に無料で使えます。(サーバー利用料は別です。)

ただ、phpで動くCMSなので、基本的にアクセスするたびにphpが動くことになります。

また、超有名CMSなので、不正なアクセスをしようとする人も出てきます。

よく考えると、特にインタラクティブなことをするわけでもなく、複数の人が投稿するようなサイトを運営しているわけでもないし、アプリから投稿するなんてこともしてません。

あれ?静的サイトで十分なのでは?

ということで、あるWordPressサイトを静的サイトに切り替えてみることにしました。

静的サイトのジェネレーターとして、 Sphinx を使います。

方針

WordPressの記事を一つ一つコピペしてreStructuredTextに書き換えるなんていう気の遠くなるような作業は、したくありません。

ということで、WordPressから記事を一括でダウンロードして、 pandoc でreStructuredTextに書き換えて、Sphinxに投入するようにします。

WordPressからエクスポートする

WordPressにログインして、記事をエクスポートします。手順は 公式の説明 に従ってください。

また、画像などのデータをFTPでダウンロードしておきます。

エクスポートしたデータから記事を取り出す

WordPressからエクスポートした記事はXML形式のファイルになっています。ところが、このXMLの仕様がオフィシャルには公開されていません。

ということで、XMLの構造を見ながらタグ毎の内容を推測してみます。

エクスポートしたデータを 別の投稿で紹介した方法 で可視化すると、下記のようになります。

rss
     channel
             title
             link
             description
             pubDate
             language
             {http://wordpress.org/export/1.2/}wxr_version
             {http://wordpress.org/export/1.2/}base_site_url
             {http://wordpress.org/export/1.2/}base_blog_url
             {http://wordpress.org/export/1.2/}author
                     {http://wordpress.org/export/1.2/}author_id
                     {http://wordpress.org/export/1.2/}author_login
                     {http://wordpress.org/export/1.2/}author_email
                     {http://wordpress.org/export/1.2/}author_display_name
                     {http://wordpress.org/export/1.2/}author_first_name
                     {http://wordpress.org/export/1.2/}author_last_name
             # authorタグの連続
             {http://wordpress.org/export/1.2/}category
                     {http://wordpress.org/export/1.2/}term_id
                     {http://wordpress.org/export/1.2/}category_nicename
                     {http://wordpress.org/export/1.2/}category_parent
                     {http://wordpress.org/export/1.2/}cat_name
             {http://wordpress.org/export/1.2/}category
             {http://wordpress.org/export/1.2/}tag
                     {http://wordpress.org/export/1.2/}term_id
                     {http://wordpress.org/export/1.2/}tag_slug
                     {http://wordpress.org/export/1.2/}tag_name
             # tagタグの連続
             {http://wordpress.org/export/1.2/}term
                     {http://wordpress.org/export/1.2/}term_id
                     {http://wordpress.org/export/1.2/}term_taxonomy
                     {http://wordpress.org/export/1.2/}term_slug
                     {http://wordpress.org/export/1.2/}term_parent
                     {http://wordpress.org/export/1.2/}term_name
             # termタグの連続
             generator
             {com-wordpress:feed-additions:1}site
             item
                     title
                     link
                     pubDate
                     {http://purl.org/dc/elements/1.1/}creator
                     guid
                     description
                     {http://purl.org/rss/1.0/modules/content/}encoded
                     {http://wordpress.org/export/1.2/excerpt/}encoded
                     {http://wordpress.org/export/1.2/}post_id
                     {http://wordpress.org/export/1.2/}post_date
                     {http://wordpress.org/export/1.2/}post_date_gmt
                     {http://wordpress.org/export/1.2/}comment_status
                     {http://wordpress.org/export/1.2/}ping_status
                     {http://wordpress.org/export/1.2/}post_name
                     {http://wordpress.org/export/1.2/}status
                     {http://wordpress.org/export/1.2/}post_parent
                     {http://wordpress.org/export/1.2/}menu_order
                     {http://wordpress.org/export/1.2/}post_type
                     {http://wordpress.org/export/1.2/}post_password
                     {http://wordpress.org/export/1.2/}is_sticky
                     {http://wordpress.org/export/1.2/}attachment_url
                     {http://wordpress.org/export/1.2/}postmeta
                             {http://wordpress.org/export/1.2/}meta_key
                             {http://wordpress.org/export/1.2/}meta_value
                     # postmetaタグの連続
             # itemタグの連続

WordPress 4.9から出力したエクスポートデータを加工したものです。同じタグが連続しているところは省略してあります。

どうやら投稿は一つずつitemタグに収まっているようです。

そこで、itemタグの中身を見てみます。

titleタグが投稿のタイトルを、encodedタグが投稿の本文を、post_idが投稿のIDを表しているようです。また、投稿の本文は![CDATA[]]という括弧に包まれています。

ということは、各itemタグに対して、titleタグを取り出して見出しにし、encodedタグの中身を本文にし、post_idをファイル名にして出力すれば、記事ごとにファイルに分割できそうです。

ということで、下記のようなコードを書いて実行しました。

import defusedxml.ElementTree as ET

tree = ET.parse('エクスポートしたxmlファイル')

# 各記事をHTMLファイルとして出力する
files = []
for i in tree.iter(tag='item'):
    title_element = i.find('title')
    id_element = i.find('{http://wordpress.org/export/1.2/}post_id')
    content_element = i.find('{http://purl.org/rss/1.0/modules/content/}encoded')
    if content_element.text == None:
        content_text = ''
    else:
        content_text = content_element.text
    # 画像ファイルなどへのリンクの書き換え
    content_text = content_text.replace('xxx/wp-content/uploads/', './')
    content_text = '<h1>' + title_element.text + '</h1>' + content_text
    with open(id_element.text + '.html', mode='wt', encoding='utf-8') as f:
        f.write(content_text)
    files.append(id_element.text)

# pandoc用のバッチファイルの作成
pandoc_command = []
for i in files:
    p = 'pandoc ' + i + '.html -o ' + i + '.rst'
    pandoc_command.append(p)
with open('htmls2rests.bat', mode='wt', encoding='utf-8') as f:
    f.write('\n'.join(pandoc_command))

# reStructuredTextに組み込むためのファイルのリストの作成
doctree_command = []
for i in files:
    d = i + '.rst'
    doctree_command.append(d)
with open('docs.rst', mode='wt', encoding='utf-8') as f:
    f.write('\n'.join(doctree_command))

これで、記事毎のhtmlファイルと、pandoc用のバッチファイルと、ファイルの一覧ができあがります。

reStructuredTextに変換する

前述のバッチファイルを実行すると、reStructuredTextに変換されたテキストファイル(拡張子がrstのファイル)ができあがります。

あとは、sphinx-quickstartして、index.rstに各ファイルへのリンクを書き込めば、ほぼ完成です。

ただし、リンクが切れていたり、公開していない記事が入っていたりするので、公開する前に各記事を一つ一つ確認する必要はあります。

広告

作ってみたカテゴリの投稿