はてなブログのカテゴリーを一括再構成

ブログを書き続けますと後からカテゴリーを再構成したくなることはありませんか?

と思っても、過去記事が大量になりますとカテゴリーをつけ直すなんてことは現実的ではありません。その試みと結果です。



試みの具体例

このサイトです。

www.movieimpressions.com


映画のレビューを書いている別サイトで、現在、1181記事あります。元ははてなダイアリーからのものですので、当時カテゴリーというものがあったかどうかも記憶にありませんが、現在は「映画」「DVD」「recommend」3つに分類しているだけで現実的には意味がありません。


それで5年前に五十音順で分類できないか試みて、カテゴリー分けではなく別途五十音順の一覧をつくる方法は成功しています。



サイトの右上の「五十音順メニュー」がその成果です。現在は記事を書く毎に一覧に追加しています。


はてなブログの記事をまるごと入れ替える

その当時やったことは、記事をエクスポートし、phpでタイトルだけ取り出し、Yahoo!APIの「ルビ振り」というWebサービスを利用してふりがなを振り、五十音順にソートして一覧をつくるというものです。

なぜそれをカテゴリーにしなかったかは、記事をまるごと入れ替える方法を思いつかなかったからです。つまり、当時は記事の全削除(全選択)がページごと(だったと思う)でしたので現実的ではなかったということです。


で、今あらためて見てみましたら、現在は「記事の管理」で「次の記事」をクリックしていきますと20記事づつ追加されていきますので、可能かどうかはわかりませんが、1181/20≒60回クリックすれば全記事を選択し削除することは可能かも知れません。

また、「チェックした記事にカテゴリーを追加」という機能も追加されていますが、これも記事が大量になりますと現実的ではありません。


独自ドメインのブログを変更することは可能!

ある時ひらめきました(笑)。

独自ドメインを利用しているブログに限定されますが、カテゴリーを再構成した同じ内容のブログをつくり、そのブログに独自ドメインを設定すればいいんじゃないかと思います。


まだ、と言いますより、その方法ではカテゴリー内の記事が五十音順には並びませんので結果として試みていませんが、多分問題ないとは思います。


で、管理画面の「インポート」をよく見てみましたらこんな記載がありました。

f:id:ausnichts:20210425103624j:plain


他のブログシステムからはてなブログに移転した場合に関する記載ですが、はてなブログ内でも同じことで、独自ドメインであれば、記事をエクスポートして、カテゴリーを再構成し、インポートして新たにブログを作成し、そのブログに独自ドメインを設定すれば過去の記事のカテゴリーを一括して再構成できるということになります。


今ごろ気づいたの? ということなのかも知れません。


Yahoo! API を使って記事タイトルから五十音順カテゴリーをつくる

上に書きましたように、記事を五十音順のカテゴリーに振り分けたとしてもカテゴリーページが新しい記事順にしか並ばないということと、1ページが30記事に固定されていることから今回の場合は希望の結果は得られません。ですので途中で断念したんですが、1181記事を五十音順カテゴリーに振り分けるところまではやりましたのでそのプログラムを載せておきます。


このプログラムだけでは汎用性はありませんが、何かの参考になればという程度です。また、1回こっきりのプログラムですので成功すればOKということで細かいチェックはしていません。

ブログのエクスポートファイルを読み込み、「残したいカテゴリー」以外のカテゴリーを全て削除し、五十音順(あ、い、う、…)のカテゴリーを追加します。



<?php
$file_name = "エクスポートしたテキストファイル";
$flag = TRUE;
$patterns1 = array('/TITLE: /', '/「/', '//.*/', '/\/.*/', '/\r\n/', '/\r/', '/\n/');
$api = 'http://jlp.yahooapis.jp/FuriganaService/V1/furigana';
$appid = '取得したアプリケーション ID';
$indexes = array(
    "数字" => "[0-9]", "英字" => "[a-zA-Z]",
    "あ" => "[あ]", "い" => "[い]", "う" => "[うヴ]", "え" => "[え]", "お" => "[お]",
    "か" => "[かが]", "き" => "[きぎ]", "く" => "[くぐ]", "け" => "[けげ]", "こ" => "[こご]",
    "さ" => "[さざ]", "し" => "[しじ]", "す" => "[すず]", "せ" => "[せぜ]", "そ" => "[そぞ]",
    "た" => "[ただ]", "ち" => "[ちぢ]", "つ" => "[つづ]", "て" => "[てで]", "と" => "[とど]",
    "な" => "[な]", "に" => "[に]", "ぬ" => "[ぬ]", "ね" => "[ね]", "の" => "[の]",
    "は" => "[はばぱ]", "ひ" => "[ひびぴ]", "ふ" => "[ふぶぷ]", "へ" => "[へべぺ]", "ほ" => "[ほぼぽ]",
    "ま" => "[ま]", "み" => "[み]", "む" => "[む]", "め" => "[め]", "も" => "[も]",
    "や" => "[や]", "ゆ" => "[ゆ]", "よ" => "[よ]",
    "ら" => "[ら]", "り" => "[り]", "る" => "[る]", "れ" => "[れ]", "ろ" => "[ろ]",
    "わ" => "[わ]", "ん" => "[ん]",
    "その他" => ".*"
);

$array = file($file_name);
$new_array = array();

for( $i = 0; $i < count($array); ++$i ) {
    if(strpos($array[$i], 'CATEGORY') === FALSE){
        $new_array[] = $array[$i];
        if (strpos($array[$i], 'TITLE') !== FALSE) { $title_line = $array[$i]; }
        if (strpos($array[$i], '--------') !== FALSE) { $flag = TRUE; }
    }else{
        if(strpos($array[$i], '残したいカテゴリー') !== FALSE){
            $new_array[] = $array[$i];
        }elseif($flag){
            $title = preg_replace($patterns1, '', $title_line);
            $params = array(
                'sentence' => $title
            );
            $ch = curl_init($api.'?'.http_build_query($params));
            curl_setopt_array($ch, array(
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_USERAGENT      => "Yahoo AppID: $appid"
            ));
            $result = curl_exec($ch);
            curl_close($ch);

            $furigana = '';
            $xml = simplexml_load_string($result);
            foreach ($xml->Result->WordList as $WordList) {
                foreach ($WordList->Word as $Word) {
                    if (isset($Word->Furigana)) {
                        $furigana .= (string)$Word->Furigana;
                    } else {
                        $surface= (string)$Word->Surface;
                        if (preg_match("/^[ァ-ヶー]+$/u", $surface)) {
                            $surface = mb_convert_kana($surface, 'c');
                        }
                        $furigana .= $surface;
                    }
                }
            }

            $char = mb_substr( $furigana, 0, 1);
            foreach ( $indexes as $index => $pattern ) {
                if (preg_match("/^" . $pattern . "/u", $char)) {
                    $category = $index;
                    break;
                }
            }

            $new_array[] = "CATEGORY: " . $category . PHP_EOL;
            $flag = FALSE;
        }
    }
}

$new_file = implode("", $new_array);
$new_file_name = "書き出すファイル名";
file_put_contents($new_file_name, $new_file);
?>