« Bloggerへデータを移行する方法 (Googleのツールを使用) | トップページ | [検索エンジン比較] Googleへの疑問 - BingやDuckDuckGoとの違い »

2021年8月13日 (金)

[無料ブログの移転] 個別記事ごとにcanonical付与とリダイレクトを行う方法 [JavaScript]

ブログ移転に際して、ページランクを引き継ぐにはまず301リダイレクトが推奨されますが、無料ブログなどではそれが出来ません。
その場合はcanonicalを付与し、新しいページを正規ページとして指定する方法(正規化)があります。
canonicalは移行元のブログ記事のhead内に以下のように記述しますが、head内を直接弄れるブログは多く無いと思います。
<link rel="canonical" href="新しいページのURL">
この記事では、JavaScriptを用いて個別記事ごとにcanonicalを設定する方法を解説します。また、ブログ移転を知らせる文と新URLへのリンクを記事本文へ挿入するコードも記載しています。
ただし私はJavaScriptは素人であるため参考程度にしてください。
JavaScriptを一か所に記述すればブログ内の全ページに適用できることが条件です。例えばサイドバーやブログのサブタイトル(説明)は、どの記事ページを開いても常に表示される要素であるため、それらの中を編集できるようになっていればJavaScriptをそこに入れて動作させられる可能性が高いと思います。

canonicalをJavaScriptによって付与してもGoogleのクローラーはそれを正常に認識できるという情報があります。→JavaScript挿入したrel=canonicalをGoogleは処理できる

また、canonicalによる正規化に加えてJavaScriptによるリダイレクト処理についても触れます。正規化は必須事項ですが、リダイレクト処理を行うべきかどうかは判断が分かれるようです。まず正規化のみで試してみて、うまく引き継げないようであればリダイレクトも併用するという方法もあります。
リダイレクトに関してはmeta refreshを用いたものもありますが、これは非推奨となっているようです。
ちなみに私はココログ(ブログサービス)からの移行を検討しているのですが、ココログではリダイレクト処理が禁止となっているため、canonicalによる正規化のみを行うことになります。

canonicalは個別記事ごとに付与しないと意味がありませんが、それにはひと手間必要です。
旧URLと新URL中のファイル名が別である場合は、旧URLと新URLの対照表を作成する必要がありそうです。
ファイル名が同じ場合で、それより上の階層のみ異なる場合は、対照表は作成しなくてもJavaScriptで正規表現を用いることで実現はできます。
この記事ではどちらにも対応できる、対照表を使用する方法を解説します。

対照表の作成にあたり、記事数が少ない場合は手作業で対照表を作成すれば良いと思います。
対照表は、Excelなどの表計算ソフトに例えば「記事タイトル」「旧URL」「新URL」といった列を作りそこに記述します。
一方で、対照表を自動で作成するには私は「Website Explorer」というウェブサイト解析ツールを使わせて頂きました。
このツールでは、ブログの記事タイトルとそれに対するURLの一覧を取得できます。新・旧ブログでこの一覧を取得し、「記事タイトル」を一致させることによりURL対照表を作ります。なので、記事タイトルが新旧ブログで同じことが条件です。
対照表に記載するURLについては、フルパスを記載しても良いのですが容量の節約のためにドメインより下の部分のみ記載する方法をこの記事では取ることにします。

ブログのURLにはwww有りと無し、httpとhttpsで混在している場合があります。
新ブログのURLにwww有りと無しが混在する場合は、どちらかを正規URLとして決めます。httpとhttpsがある場合は、httpsを正規にすれば良いと思います。canonicalでこの正規URLを指定し、検索エンジンに正規URLとして認識させることになります。

新・旧ブログのトップページのURLをWebsite Explorerに入力して解析します。
以下が、私がサイトを解析した結果です。
Websiteexplorer

「サイト内ページ」の項目を使用します。ここで「HTML形式で保存」というボタンがありますのでそれをクリックして保存します。
CSV形式での保存も出来ますが、私が試したところCSVでは一部がエスケープ文字に変換されていましたのでHTMLでの出力のほうが良いと思います。
Excelがあれば、「Excelに出力」でも良いと思いますが同じく文字が変になっていないか確認してください。
また「サイト内ページ」には、同じページでもURLにパラメータ付きのもの(?から始まる語句がURLの後尾にあるもの)が混ざっていたり、カテゴリやアーカイブページなどが混ざっていたりします。これらは新旧対照表には入れませんので(カテゴリページも新旧対応させるなら別ですが)、後で削除しますが、パラメータ付きのものについては初めから検出対象に入れない設定もできます。
保存したHTMLファイルをブラウザで開き、タイトルとURLを含んだ列を表計算ソフトへコピーします。この時、貼り付け方は次のようにします。私は表計算ソフトとしてLibreOfficeを使用していますのでその例になりますが、Excelなどでも参考にできると思います。
LibreOfficeでは「形式を選択して貼り付け」→「書式設定されていないテキスト」でテキストインポートダイアログが出ますので、以下のように設定してインポートします。
Textimport

次に、余計なページを削除します。これにはフィルター機能を用いるのが良いと思います。
まずはパラメータ付きのURLの行を削除するため、URLの後ろが「.html」で終わるもの以外をソートするなどし、その結果の行を削除します。
カテゴリページやアーカイブページ、その他不要なページもソートして削除します。標準のソート機能では難しい場合は、正規表現を使用することも出来ます。

これを新・旧のブログで行います。そして「記事タイトル」を元にURLのマッピングを行う訳ですが、Website Explorerで出力された一覧は元々タイトルが名前順に並んでいます。そのため、特別な操作を行わなくても新・旧ブログのURL一覧を横に並べると一致する可能性が高いと思います。ただし記事タイトル名の後ろにブログタイトルが挿入されている場合、その部分についてはブログごとに記述が異なりますので修正したほうが良いかもしれません(修正しなくても並びが一致していれば大丈夫ですが)。「検索と置換」で修正できると思います。修正後、記事タイトル列を昇順か降順でソートします。
一致したら、以下のように対照表として統合します。
Urlmapping_20210813123601

URLの短縮化も行います。ドメイン以上の部分を削除します。「検索と置換」を用い、以下のように設定して置換します。ドメイン名の後ろの「/」は削除せず残します。
Shortenurl

これで対照表が完成しました。これをJavaScriptへ読み込ませるのですが、簡単な方法として、この対照表をJavaScriptの連想配列形式にして、JavaScriptのコード内に直接記述する方法を解説します。
連想配列形式は、{"旧URL1":"新URL1", "旧URL2":"新URL2", ...}という記述になります。
この記述方法へ表計算ソフト内で変換できます。
そのためには、新しい列(右隣りの列など)に以下の数式を入れます。
=""""&旧URLセル&""":"""&新URLセル&""","
例えば上記の画像内の行2には、以下の数式が入ります。
=""""&B2&""":"""&C2&""","
この数式では、「"」「:」「,」をそれぞれのURLに挿入しています。
これを、URL一覧の全行にオートフィルで適用させます。
次に、適当な別のセルに以下の数式を入れます。
=CONCAT("{", 上記範囲, "}")
上記範囲には先ほど数式を適用した範囲を指定します。
この数式で、上記範囲にあるURL(調整後)を結合し、更に先頭に「{」、後尾に「}」を加えています。
このCONCAT関数ですが、古い表計算ソフトでは利用できない可能性があります。
LibreOfficeの最近のバージョンでは利用でき、かつ無料なのでこれを利用できます。
このセルの内容をコピーし、JavaScriptのコードに直接貼り付けることになります。

JavaScriptのコードは以下になります。
まずリダイレクト無しのコードを挙げますが、ここで基本的な説明をします。

リダイレクト無し
<script>
document.addEventListener('DOMContentLoaded', function(){
    let dic = {旧URL:新URL, ...};
    let path = location.pathname;
    if (dic.hasOwnProperty(path)){
        let newUrl = '新URLのドメイン以上の部分' + dic[path];
        let head = document.getElementsByTagName('head')[0];
        let link = head.querySelector('link[rel="canonical"]');
        if (link) {
            link.href = newUrl;
        }else{
            link = document.createElement('link');
            link.rel = 'canonical';
            link.href = newUrl;
            head.appendChild(link);
        }
//ここから記事本文へ文を挿入するコード
        let entryBody = document.getElementsByClassName('クラス名')[0];
        entryBody.insertAdjacentHTML('afterbegin', '<p>※ブログ移転しました。この記事の新しいページはこちらです。<a href="'+newUrl+'">'+newUrl+'</a></p>');
    }
});
</script>

青文字の部分を置き換えます。
{旧URL:新URL, ...} には、用意した連想配列を貼り付けます。
新URLのドメイン以上の部分 には、新ブログの正規URLのドメイン以上の部分を入力します。例えばhttps://example.comです。
クラス名 についてですが、ここには旧ブログの記事本文のclass属性の値を指定します。
旧ブログの記事ページを開き、Google Chromeの場合は「右クリック」→「ページのソースを表示」でHTMLのコードが見られます。
以下はココログのHTMLです。
Htmlsource

ここで記事本文は<div class="entry-body">の要素の中にあることが分かりますので、クラス名はentry-bodyとなります。
この場合、文全体は以下になります。
let entryBody = document.getElementsByClassName('entry-body')[0];
ちなみに、はてなブログの場合は<div class="entry-content">の中に記事本文があります。ライブドアブログの場合は<div class="main">でした。
もしこの要素にclassでは無くidが指定されていたら(<div id="entry-body">のように)、
let entryBody = document.getElementById('id名');
としてください。
また、スマホ用の表示とPC用の表示で、記事本文のclass属性の値が異なることがあります。
スマホで記事のHTMLソースを見るには、chromeの場合だとURL欄に「view-source:」に続けてURLを入力して続行します。
パソコンで確認するには、デベロッパーツールを使用します。
chromeの場合は「Ctrl + Shift + I」で開けます。以下の画像の赤矢印が示す部分をクリックするとスマホ表示に切り替わります。
Console_20210915055001
更にページを更新させます。そしてElementsタブでHTMLを確認できます。
クラス名がスマホとPCで異なる場合はlet entryBody = document.getElementsByClassName('クラス名')[0];の部分を以下のように変更すれば良いと思います。

let entryBody = document.getElementsByClassName('クラス名')[0]; 
if (!entryBody) {
    entryBody = document.getElementsByClassName('もう一つのクラス名')[0];
}

私のコードでは、記事本文中の一番初めにブログ移転を知らせる文章を挿入しています。

次に、リダイレクト処理をする場合のコードは以下になります。

すぐにリダイレクト
<script>
{
    let dic = {旧URL:新URL, ...};
    let path = location.pathname;
    if (dic.hasOwnProperty(path)){
        let newUrl = '新URLのドメイン以上の部分' + dic[path];
        let head = document.getElementsByTagName('head')[0];
        let link = head.querySelector('link[rel="canonical"]');
        if (link) {
            link.href = newUrl;
        }else{
            link = document.createElement('link');
            link.rel = 'canonical';
            link.href = newUrl;
            head.appendChild(link);
        }
        location.replace(newUrl); //リダイレクトのコード
    }
}
</script>

記事本文へ文を挿入するコードを削除し、代わりにリダイレクトのコードを入れています。
このコードでは、待ち時間無しでリダイレクトします。
そのほうがウェブサイト訪問者にとって利便性が高いのでは無いかと考えたからですが、もし待ち時間を設定する場合は代わりに以下のコードにします。

待ち時間を設定してリダイレクト
<script>
document.addEventListener('DOMContentLoaded', function(){
    let dic = {旧URL:新URL, ...};
    let path = location.pathname;
    if (dic.hasOwnProperty(path)){
        let newUrl = '新URLのドメイン以上の部分' + dic[path];
        let head = document.getElementsByTagName('head')[0];
        let link = head.querySelector('link[rel="canonical"]');
        if (link) {
            link.href = newUrl;
        }else{
            link = document.createElement('link');
            link.rel = 'canonical';
            link.href = newUrl;
            head.appendChild(link);
        }
//ここからリダイレクトのコード
        setTimeout("redirect()", 5000); //リダイレクトまで5秒待つ
        function redirect(){
            location.href = newUrl;
        }
//ここから記事本文へリダイレクトを知らせる文を挿入するコード
        let entryBody = document.getElementsByClassName('クラス名')[0];
        entryBody.insertAdjacentHTML('afterbegin', '<p><strong>ブログ移転しました。新しいページへ約5秒後に転送します→</strong><a href="'+newUrl+'">'+newUrl+'</a></p>');
    }
});
</script>

コードは以上となります。
これを旧ブログの、どのページを開いても常に表示される領域に貼り付けます。
そしてcanonicalを付与するように意図したページにてブラウザのデベロッパーツールを開き、正常に以下のタグがhead内に入っていることを確認します。
<link rel="canonical" href="新しいページのURL">

また、Google Search Consoleでは旧ブログ・新ブログ両方登録し、新URLのほうが正規ページと認定されるかどうか随時確認します。
「URL検査」のページにて、「ユーザーが指定した正規URL」に新しいURLが記載されれば成功です。

« Bloggerへデータを移行する方法 (Googleのツールを使用) | トップページ | [検索エンジン比較] Googleへの疑問 - BingやDuckDuckGoとの違い »

ブログ」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

« Bloggerへデータを移行する方法 (Googleのツールを使用) | トップページ | [検索エンジン比較] Googleへの疑問 - BingやDuckDuckGoとの違い »