前回はlivedoorブログからWordPressにブログを移転するにあたり、Let’s Encryptで常時SSL化したり、PHP7の導入について書きました。今回はlivedoorブログからの過去記事の移動について書きたいと思います。

詳しい移転方法については、こちらのブログ記事「ライブドアブログからWordPressへ失敗しないで引越しする手順」を参考にさせていただきました。移転を検討されている方はまずは、このリンク先ページを参考にしていただくのが良いと思います。このブログでは、補足的な部分について書いています。

旧ブログの仕様(livedoorブログ)

【URL】http://blog.xe.bz/
【パーマリンク】/archives/****.html
【画像ファイル置き場】http://livedoor.blogimg.jp/xxxxx/imgs/*/*/****.jpg

新ブログの仕様(WordPress)

【URL】https://akibabara.com/blog/
【パーマリンク】/****.html
【画像ファイル置き場】/wp-content/uploads/imgs/

旧ブログでエクスポートする

livedoorブログにはエクスポート機能があり、記事やコメントを一括して取得することができます。これを新しいブログに読み込ませれば引越完了!と言いたいところですが、なかなかそう簡単にはいかないのです。なぜかというと、全てのデータがエクスポートされるわけではなく、インポートしても新しいブログに合わせて構築されるわけではないからです。livedoorブログからエクスポートできるデータは次のとおりです。

  • 記事のタイトル、本文、日時、カテゴリ、URLのパス
  • コメント、日時

一方、エクスポートされないデータは次のとおりです。

  • 画像ファイル

画像ファイルをダウンロードする

画像ファイルの一括ダウンロードは紹介したページに説明があるので、普通はこの方法で問題ないでしょう。今回は画像をダウンロードするとともに、新しいブログでのURLに書き換える処理を一括して行うために、次のようなスクリプトを作成してみました。

#!/usr/bin/php
<?php
$outdir = "imgs";
$new_baseurl = "https://YourBlogURL/wp-content/uploads/".$outdir;

$infile = $argv[1];
if(! is_dir($outdir)) mkdir($outdir, 0755);
if(! is_file($infile)) die("no file\n");

foreach (explode("\n",file_get_contents($infile)) as $line) {
    $line = preg_replace_callback('/(<img [^>]+>)/i', function($m){
        return preg_replace_callback('/src=(["\'])([^"\'?]+)\??[^"\']*(["\'])/i', function($mm){
            return 'src='.$mm[1]. downloadimg($mm[2]) .$mm[3];
        }, $m[1]);
    }, $line);
    $line = preg_replace_callback('/(<a [^>]+>)/i', function($m){
        return preg_replace_callback('/href=(["\'])([^"\'?]+)\.(jpg|jpeg|png|gif)\??[^"\']*(["\'])/i', function($mm){
            return 'href='.$mm[1]. downloadimg($mm[2].'.'.$mm[3]) .$mm[4];
        }, $m[1]);
    }, $line);
    echo $line."\n";
}
exit;

function downloadimg($url) {
    global $outdir, $new_baseurl;
    if(preg_match("~\Ahttps?://~", $url)) {
        $buff = @file_get_contents($url);
        if(strlen($buff) > 0) {
            for ($i=0; $i<100; $i++) {
                $newname = (($i>0) ? $i.'_' : '') . basename($url);
                $outpath = $outdir.'/'. $newname;
                if(! is_file($outpath)) {
                    file_put_contents($outpath, $buff);
                    $url = $new_baseurl.'/'.$newname;
                    break;
                }
            }
        }
    }
    return $url;
}
?>

このプログラムにエキスポートしたMT形式のデータを読み込ませると、画像ファイルのダウンロードと、URLの書き換えが行われます。

$ ./ldblog_img_convert.php backup.txt > backup_new.txt

WordPressにインポートする

まずはダウンロードした画像ファイルのフォルダ imgs/ をWordPressのディレクトリへコピーします。次に記事データ backup_new.txt をWordPressへインポートするわけですが、紹介したページとはちょっと違う手順を踏みました。紹介したページではパーマリンクの設定を「カスタム」にして /archives/%postname%.html としています。こうすることでlivedoorブログと全く同じパスになり移行が容易です。

しかし私は %postname% を使いたくありません。%postname% にすると、今後新しく投稿する記事のURLが長くなり、タイトルが変わるとリンク切れが起こってしまいます。(ですよね??)せっかくドメイン名も短いので、なるべく短くなるように /%post_id%.html にすることにしました。

backup_new.txt をWordPressへインポートすると、今までの記事のURLは新しく採番されてしまいます。こうした場合に困るのが、旧URLにアクセスから単純に新URLにリダイレクトできないことです。記事のIDが変わってしまうのですから仕方ありません。そこで旧URLの旧IDから新URLの新IDに変換するプログラムを作りました。

<?
include("/Path/to/Your/WordPress/wp-config.php");

$blogcaturl = "https://YourDomain/blog/category";	//カテゴリのURL
$cat2new = array(	//旧カテゴリIDと新カテゴリの対応表
	10000000 => "/make",	//【Make】 (17)
	10001000 => "/make/3d-printer",	//3Dプリンタ (2)
);

$name = $rcode = 0;
$newurl = "";
if(preg_match("#\A/([0-9]+)\.html#", $_SERVER['PATH_INFO'], $mm)) {
	$name = $mm[1];
	if($name > 0) {
		$pdo = new PDO( 'mysql:dbname='.DB_NAME.';host='.DB_HOST, 
			DB_USER, DB_PASSWORD,
			array(
		    	PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
				PDO::ATTR_EMULATE_PREPARES => false,
			)
		);
		$stmt = $pdo->prepare("SELECT id,post_name,guid FROM `wp_posts` WHERE post_type='post' and post_status='publish' and post_name=?");
		$stmt->bindValue(1, $name, PDO::PARAM_INT);
		$stmt->execute();
		$rowcnt = $stmt->rowCount();
		if($rowcnt == 1) {
			$result = $stmt->fetch(PDO::FETCH_ASSOC);
			$newurl = $result['guid'];
			$rcode = 301;
		}
	}
} else if(preg_match("#\A/cat_([0-9]+)\.html#", $_SERVER['PATH_INFO'], $mm)) {
	$name = $mm[1];
	if(isset($cat2new[$name])) {
		$newurl = $blogcaturl."$cat2new[$name]";
		$rcode = 301;
	}
}

if(! empty($newurl) && preg_match("#\Ahttps?://#", $newurl)) {
	if($rcode == 301) {
		header("HTTP/1.1 301 Moved Permanently");
	}
	header("Location: $newurl");
	exit;
} else {
	header("HTTP/1.0 404 Not Found");
	//exit;
}

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<TITLE>このURLは存在しません</TITLE>
<meta http-equiv="refresh" content="3;URL=https://YourDomain/blog/">
</HEAD>
<BODY>

<h2>このURLは存在しません</h2>
3秒後にトップ画面にジャンプします。<br>
ジャンプしない場合は、下記のURLをクリックしてください。<br>
<br>
<a href="https://YourDomain/blog/">https://YourDomain/blog/</a>

</BODY>
</HTML>

これが正しいやり方かはわかりません。MariaDBのWordPressのデータベースを眺めていたら、wp_postsテーブルにpost_nameというカラムがあり、ここに旧ブログの記事IDが入っていることがわかりました。そしてguidに新ブログのURLが入ってました。そこで旧URLの  archives/****.html にアクセスがあったら、記事ID **** で検索して、新に301リダイレクトするようにしました。301リダイレクトは「恒久的な移転」です。

カテゴリーについては対応表を作り、旧URLの  archives/cat_****.html にアクセスがあったら、対応する新URLにリダイレクトするようにしました。

画像の反映

最後に仕上げとして、画像をブログに反映させましょう。今の状態でも記事のURLを開けば画像は表示されます。しかしWordPressには認識されていないので、記事一覧などに表示されるアイキャッチ画像として扱われません。具体的な手順は、紹介したページと同じなので、詳しくはそちらを見てください。

WordPressにアップロードした画像ファイルを認識させるには「Media from FTP」プラグインを使います。続いて「Auto Post Thumbnail」プラグインで、各記事のアイキャッチ画像を生成します。

実はその後気付いたのですが、Auto Post Thumbnailが取得できない画像があり、ソースを見ていたら、SSL証明書が正しくないサーバーからのダウンロードが失敗していることがわかりました。証明書の検証をしないようにプラグインを修正してうまくいったのですが、あれ、アイキャッチ画像ってダウンロードしてるの?もしかしてMedia from FTPやらなくてよくない??ということに気付いてしまいました。もしかしたらMedia from FTPは不要かもしれないです。(^^;;

最後にDNSを変更

新ブログの準備が終わったら、DNSのIPアドレスを新しいサーバーのものに変更しましょう。これで無事、livedoorブログからWordPressへの移転が完了しました!

LINEで送る
Pocket