晴歩雨描

晴れた日は外に出て歩き、雨の日は部屋で絵を描く

WordPress)はてなブログから移行(インポート)する手順まとめ。メディアライブラリを使わないバージョン。

自宅WindowsPCローカルにWordPressをインストールしている。

はてなブログ」からエクスポートしてWordPressにインポートしてみた。

以前、移行(インポート)する手順まとめを書いた。この時はメディアライブラリを使う前提だった。

メディアライブラリを使わないで、アイキャッチ画像表示する方法が分かったので、

今回は、メディアライブラリを使わない前提の移行(インポート)手順まとめ。

1.はてなブログエクスポートファイル加工。

はてなブログエクスポートファイルを以下の手順で加工する。

(例)はてなブログエクスポートファイル「2ndart.hatenablog.com.export.txt」

1.1 アイキャッチ画像CSV生成 ≪eyecatch-csv.jse
  • 入力:2ndart.hatenablog.com.export.txt(ファイル名固定)
  • 出力:hatena.eyecatch.csv
1.2 画像URLをローカルパスURLに変更 ≪hatena-img-chg.jse
1.3 はてなブログカード→Wordpressショートコード変換 ≪blogcard-chg.jse
  • 入力:「1.2」の出力ファイル(ドラッグ&ドロップ
  • 出力:2ndart.hatenablog.com.export-imgchg-blogcard.txt
1.4 (任意) キーワードリンク<a>タグを除去する ≪keyword-remove.jse≫
  • 入力:「1.3」の出力ファイル(ドラッグ&ドロップ
  • 出力:2ndart.hatenablog.com.export-imgchg-blogcard-remove.txt
1.5 アイキャッチ用画像挿入 ≪eyecatch-insert.jse
  • 入力:「1.3」または「1.4」の出力ファイル(ドラッグ&ドロップ
  • 出力:2ndart.hatenablog.com.export-imgchg-blogcard-remove-eyecatchtxt

上記それぞれのスクリプトの詳細は以下。

2.エクスポートファイル ⇒ インポート。

上記手順1で加工したはてなブログ「エクスポートファイル」をダッシュボードでインポートする。

※ インポートは「エクスポートファイル」2MB単位でしかできないので、分割して行う。

「ツール」の「Movable TypeTypePad」の「今すぐインストール 」を実行。

「インポーターの実行」が表示されるので実行。

Movable Type もしくは Typepad のインポート」画面が出る。

はてなブログでエクスポートしたMT(MovableType)形式のテキストファイルを選択して「ファイルをアップロードしてインポート」を実行。

※ インポートファイルは最大サイズ2MBと出るが、追加で複数ファイルをインポートできる。ちゃんと日付順に表示される。

3.画像ファイル:格納。

はてなブログの画像ファイルは、以下のツールでダウンロードする。

ダウンロードした画像ファイルを「\wp-content\uploads\hatena」に入れる。

※ 今回の方法では、メディアライブラリやWordPressアイキャッチ画像は使わないので、メディアライブラリへの登録やアイキャッチ画像の登録といった作業は不要。


以下、画像格納フォルダを年別の階層構造にした場合のJScript改訂版のソースリスト。

  • \wp-content\uploads\hatena\2019
  • \wp-content\uploads\hatena\2020
  • \wp-content\uploads\hatena\2021
  • \wp-content\uploads\hatena\2022
1.1 アイキャッチ画像CSV生成 ≪eyecatch-csv.jse≫
var adTypeText = 2;
var adSaveCreateOverWrite = 2;	// 上書き
var adReadAll = -1;		// 全行

var sr = new ActiveXObject("ADODB.Stream");
sr.Type = adTypeText;
sr.charset = "utf-8";
sr.Open();
sr.LoadFromFile("2ndart.hatenablog.com.export.txt");	// ファイル名固定
var str = sr.ReadText(adReadAll);
sr.Close();

var sw = new ActiveXObject("ADODB.Stream");
sw.type = adTypeText;
sw.charset = "utf-8";
sw.Open();

var body = false;	// BODY:
var bodyend = true;	// --------
var out = "";
var line_ary = str.split(/\n/);
for (var i=0; i<line_ary.length; i++) {
	if (!body) {
		if (line_ary[i].substring(0,10) == 'BASENAME: ') {
			var base = line_ary[i].slice(10);
			var spt = base .split('/');
			var str = spt[0] + '/' + spt[1] + '/' + spt[2] + '/' + spt[0] + '-' + spt[1] + '-' + spt[2] + '-' + spt[3];
			out = out + 'wordpress/' + str + ",";
		}
		if (line_ary[i].substring(0,7) == 'IMAGE: ') {
			var image = line_ary[i].slice(7);
			var spt = image.split('/');
			out = out + spt[7].substring(0,4) + '/' + spt[7] + '_' + spt[8] + "\n";
		}
	}
	if (line_ary[i].substring(0,5) == 'BODY:') {
		body = true;
		bodyend = false;
	}
	if (line_ary[i] == '-----') {
		bodyend = true;
		body = false;
	}
}
sw.WriteText(out);
sw.SaveToFile("hatena.eyecatch.csv",adSaveCreateOverWrite);
sw.Close();
1.2 画像URLをローカルパスURLに変更 ≪hatena-img-chg.jse≫
//	ドラッグ&ドロップしたパス情報を取得
var args = WScript.Arguments;
var inputFile = args(0);

var sr = new ActiveXObject("ADODB.Stream");
sr.Type = 2;					// adTypeText
sr.charset = "utf-8";
sr.Open();
sr.LoadFromFile(inputFile);
var str = sr.ReadText(-1);			// adReadAll
sr.Close();

var tmp = str.replace(/https:\/\/cdn-ak\.f\.st-hatena.com\/images\/fotolife\/a\/art2nd\//g,'/wordpress/wp-content/uploads/hatena/ZXZXZX');

var tmp2 = "";
var out = tmp.replace(/ZXZXZX(\d{8})\/(\d{14}\.(jpg|png|gif))/g,function() {
	tmp2 = arguments[0].replace('\/', '_').replace('ZXZXZX', '');
	return tmp2.substring(0,4) + '/' + tmp2;
});

var sw = new ActiveXObject("ADODB.Stream");
sw.Type = 2;					// adTypeText
sw.charset = "utf-8";
sw.Open();
sw.WriteText(out, 1);				// adWriteLine
sw.SaveToFile(inputFile.slice(0,-4) + "-imgchg.txt", 2);	// adSaveCreateOverWrite
sw.Close();
1.3 はてなブログカード→Wordpressショートコード変換 ≪blogcard-chg.jse≫
//	***	ドラッグ&ドロップしたパス情報を取得
var args = WScript.Arguments;
var inputFile = args(0);

var adTypeText = 2;
var adSaveCreateOverWrite = 2;	// 上書き
var adReadAll = -1;		// 全行

var sr1 = new ActiveXObject("ADODB.Stream");
sr1.Type = adTypeText;
sr1.charset = "utf-8";
sr1.Open();
sr1.LoadFromFile(inputFile);	//  はてなブログ エクスポート・ファイル

var str = sr1.ReadText( adReadAll );
sr1.Close();

var stw = new ActiveXObject("ADODB.Stream");
stw.type = adTypeText;
stw.charset = "utf-8";
stw.Open();

var out = "";
var lines = str.split(/\r?\n/);
var card = false;
for (var i=0, z=lines.length; i<z; i++) {
	card = false;
	var iframe = lines[i].match(/<iframe(.*)<\/iframe>/);
	if (iframe) {
		var src = iframe[1].match(/src="https?:\/\/hatenablog-parts.com\/embed\?url\=https?%3A%2F%2F2ndart\.hatenablog.com%2Fentry%2F(.*)" /);		// 何故か "以降も入ってくる。
		if (src) {
			var urlymd = src[1].split('"');
			if (urlymd) {
				var spt = urlymd[0] .split('%2F');
				var ymd = spt[0] + '/' + spt[1] + '/' + spt[2] + '/' + spt[0] + '-' + spt[1] + '-' + spt[2] + '-' + spt[3];
				out = out + '<p>[nmblogcard url="/wordpress/' + ymd + '/"]</p>\n';
				card = true;
			}
		}
	}
	if (!card) {
		out = out + lines[i] + "\n";
	}
}
stw.WriteText(out);
stw.SaveToFile(inputFile.slice(0,-4) + "-blogcard.txt", adSaveCreateOverWrite);
stw.Close();
1.4 キーワードリンク<a>タグを除去する ≪keyword-remove.jse≫
//	ドラッグ&ドロップしたパス情報を取得
var args = WScript.Arguments;
var inputFile = args(0);

var sr = new ActiveXObject("ADODB.Stream");
sr.Type = 2;					// adTypeText
sr.charset = "utf-8";
sr.Open();
sr.LoadFromFile(inputFile);
var str = sr.ReadText(-1);			// adReadAll
sr.Close();

var out = str.replace(new RegExp('<a[^>]+href=\"https?://d\.hatena\.ne\.jp/keyword.*?>(.*?)</a>', 'g'), '$1')

var sw = new ActiveXObject("ADODB.Stream");
sw.Type = 2;					// adTypeText
sw.charset = "utf-8";
sw.Open();
sw.WriteText(out, 1);				// adWriteLine
sw.SaveToFile(inputFile.slice(0,-4) + "-remove.txt", 2);	// adSaveCreateOverWrite
sw.Close();
1.5 アイキャッチ用画像挿入 ≪eyecatch-insert.jse≫

※ エクスポートファイルをドラッグ&ドロップで読み込む場合、他のインプットファイル(CSVファイル:hatena.eyecatch.csv)も絶対パスにしないとエラーになる。

var args = WScript.Arguments;		// ドラッグ&ドロップしたパス情報を取得
var inputFile = args(0);		// はてなブログ エクスポート・ファイル(2,3処理済み)(絶対パス)

var csvFile = "hatena.eyecatch.csv";
var fso = new ActiveXObject("Scripting.FileSystemObject");
var path = fso.getParentFolderName(WScript.ScriptFullName);	// カレントディレクトリ(絶対パス)
var csvFile = path + "\\" + csvFile;	// csvFile:絶対パスに変換
var adTypeText = 2;
var adSaveCreateOverWrite = 2;		// 上書き
var adReadAll = -1;			// 全行
// ---------------------------------
var sr1 = new ActiveXObject("ADODB.Stream");
sr1.Type = adTypeText;
sr1.charset = "utf-8";
sr1.Open();
sr1.LoadFromFile(csvFile);
var csvstr = sr1.ReadText(adReadAll);
sr1.Close();

var csvlines = csvstr.split(/\r?\n/);
var eyecatch = [];
for (var i=0; i<csvlines.length; i++) {
	eyecatch[i] = csvlines[i].split(",");
}
// ---------------------------------
var sr2 = new ActiveXObject("ADODB.Stream");
sr2.Type = adTypeText;
sr2.charset = "utf-8";
sr2.Open();
sr2.LoadFromFile(inputFile);
var str = sr2.ReadText(adReadAll);
sr2.Close();

var stw = new ActiveXObject("ADODB.Stream");
stw.type = adTypeText;
stw.charset = "utf-8";
stw.Open();

var out = "";
var lines = str.split(/\r?\n/);
var outsw = false;
var image = "";
for (var i=0; i<lines.length; i++) {
	outsw = false;
	if (lines[i].substring(0,7) == 'IMAGE: ') {
		image = lines[i].slice(7);
	}
	if (lines[i].substring(0,5) == 'BODY:') {
		if (image != "") {
			out = out + 'BODY:' + "\n" + '<img src="' + image + '" style="display:none;">' + "\n";
			outsw = true;
			image = "";
		}
	}
	if (lines[i].indexOf('<p>[nmblogcard url="/wordpress/') == 0) {
		url = lines[i].substr(21).slice(0,-7);
		if (imgfile = array2find(url, eyecatch)) {
			out = out + lines[i].slice(0,-5) + ' image_url="/wordpress/wp-content/uploads/hatena/' + imgfile + '"]</p>' + "\n";
			outsw = true;
		}
	}
	if (!outsw) {
		out = out + lines[i] + "\n";
	}
}
stw.WriteText(out);
stw.SaveToFile(inputFile.slice(0,-4) + "-eyecatch.txt", adSaveCreateOverWrite);
stw.Close();
function array2find(str, ary) {
	for (var i=0; i<ary.length; i++) {
		if (str == ary[i][0]) {
			return ary[i][1];
		}
	}
	return false;
}

※ メディアライブラリを使わない設定まとめは、以下。