Big Bang

パソコンの電源を入れた時、メモリー空間に無限の宇宙が拡がる

ブログ移転で rel="canonical" は有効か?

| 8件のコメント

Yahoo!JAPANの「カスタムサーチ」のページで「内容が重複する複数のURLをまとめるよう、検索エンジンに通知」という記事を見つけました。

サイトには、URLは異なるがウェブページの内容は変わらないというケースがあります。たとえば、URLがトラッキング用のパラメータを含んでいる場合や、URLに含まれるパラメータをもとに閲覧環境によってウェブページの表示を最適化しているような場合です。

  • http://www.example.com/products?trackingid=feed
  • http://www.example.com/products?sessionid=hgjkeor2
  • http://www.example.com/products?printable=yes&trackingid=footer

このような場合、検索エンジンのインデックスに個々のURLで登録されると、同じ内容のウェブページが検索結果に表示されたり、同じ内容のウェブページであるにもかかわらず、各URLにクローラーが巡回し、サーバーに負荷をかけてしまう、また、サイト内の巡回が効率的に行われないといった不都合が発生することがあります。このようなことを避けるため、サイト管理者がウェブページのなかで<link>タグを利用して、重複を避けるように検索エンジンに通知する方法が用意されています。

具体的にはヘッダに下の様に書いたとすると「このページはhttp://www.example.com/と同じ内容です」と宣言したことになるようです。

<link rel=”canonical” href=”http://www.example.com/”>

ということは、ここでひとつの疑問が出てきます。

別のドメインでもcanonicalは適用できるのだろうか?

その回答はGoogleの「rel=”canonical” 属性について – ウェブマスター ツール ヘルプ」にありました。

rel=”canonical” 属性を使用して、まったく別のドメイン上の URL を指定できるか

リダイレクトは簡単に設定できない場合があります。たとえば、サーバーサイドのリダイレクトを作成できないウェブ サーバーを使用しているときに、新しいドメイン名に移行する場合などです。このような場合には、rel=”canonical” リンク要素を使用して、このドメインでインデックス登録の対象になる正確な URL を指定できます。rel=”canonical” リンク要素は絶対的な指示ではなく、ヒントとしてみなされますが、Google では可能な限りこの要素を追跡します。

つまり、解釈が間違っていなければ「rel=”canonical” 属性」は、次のような使い方が出来るということでしょうか?

ブログやサイトを別ドメインに移転した。今までに作ったページも新しいドメインにコピーした。今後は新ドメインで運用するが、これまでの遺産として古いドメインにも記事を残しておきたい。しかし、そうすると後から作った新しいサイトがコピーサイトとして検索エンジンに低く扱われる可能性がある。

そうならないために、今までの(古い)サイトのHTMLに「rel=”canonical” 属性」でコピー済みの新しいサイトの記事を指定しておく。そうすることで検索エンジンには、新サイトを優先するよう要望する。

そうすると「Google では可能な限りこの要素を追跡」してくれるのでしょうか?実は最近、この条件に合致した移転ブログがあります。

パート派遣主婦のぐーたら子育て生活 (長いので以下「パー…」と省略表記)

「パー…」は最近、独自ドメインを取って「ココロデザイン」というサイトに移転しました。その移転の際のリポートを「技術のタマゴ」というブログに書いています。

ということで「技術のタマゴ」を開いたら、こんな記述が見つかりました。

※rel=”canonical”で重複記事の中で、新記事を一番だと主張する
 という案もありましたが、同一ドメイン間じゃないと
 使えないということで、却下になりました。

rel=”canonical”は使わなかったようです。しかしGoogleのページには、こう書いてあります。「リダイレクトを作成できないウェブ サーバーを使用しているときに、新しいドメイン名に移行する場合などです。このような場合には、rel=”canonical” リンク要素を使用して、このドメインでインデックス登録の対象になる正確な URL を指定できます

そうであるなら「同一ドメイン間じゃないと使えない」というのは間違いじゃないでしょうか?

追記:今ご覧いただいているこのブログの移転で試したところrel=”canonical”は適用されました。尚「技術のタマゴ」の記事は訂正されています。

しかし、rel=”canonical” で新サイトを指定できるとしても、ブログで実際にどうやればいいのかという問題があります。すべての記事のヘッダにrel=”canonical”属性で、新しいURLを書き込まないといけませんが、多くの無料ブログのテンプレートでは1記事ごとに違うURLを指定する事は出来ません。

記事の中に書いたら記事毎にURLを変えられるがどうだろうか、と思い調べてみたのですが「rel=canonicalタグによくある5つの間違い | 海外SEO情報ブログ」によると「間違い その5: <body>内のrel=”canonical”」という項目で次のように書いてありました。記事の中に書いても有効化されないようです。

rel=”canonical”はHTMLドキュメントの<head>セクションだけに出現しなければならない。またHTMLの読み取りの問題を避けるために<head>の先頭にできるだけ近いほうがいい。

<body>にrel=”canonical”が出てきたときは無視する。

ファンブログハックの記事から

ファンブログハックに「「タイトルタグの重複」をjavascriptで回避する(ファンブログ、FC2)」という記事があります。JavaScriptを使ってHTMLに書いてあるのと違うタイトルに書きかえたところ、Googleには書きかえたタイトルが反映されたという内容です。

実はこのブログ(移転前の旧ブログ)は今月1日に新しいスキンに変えているんですが、「site:fanblogs.jp/ayzfqir5」をググるとおもしろい結果が出ます。このブログのスキンには、タイトルにページ番号やカテゴリー名を表示させる機能がありません。なので、JavaScriptで書き加えているんですが、スキンを変えて数日で、検索結果に反映されるようになりました。ファンブログハックの記事の通りです。

赤枠内はスクリプトで追加したものですが、見事に反映されています。

検索結果にはJavaScriptで修正したタイトルが表示されている

ヘッダにrel=”canonical” 属性を追加するスクリプト

ということは、JavaScriptで、ヘッダにrel=”canonical” 属性を追加すれば、検索に反映されるのではないだろうか?つまり、新しいサイトを優先して表示してくれるのではないだろうか?と仮定できるのです。もし、それが出来るなら「パー…」にnoindexを指定する必要はなくなります。

とは言ったものの、ページ数がたくさんある時は大変です。ちなみにページが数ページしかない時には、下のようなスクリプトで実現できると思います。

実際にスクリプトを使った処理で rel=”canonical” が適用されるかは不明です。このブログの実際の移転では、この下の「新ドメイン側の.htaccessに旧URLを渡して、振り分ける」方法を使って適用に成功しました。

前提条件として、古い記事のURLはすべて「http://old_url.com/archive/xxx」というフォーマットになっているものとします。URLの中のxxxは数字です。この数字ごとに新しいURLをヘッダに書き加えます。新しいサイトでは、記事の内容ごとに違うブログに分けていたとしても大丈夫です。

<script type="text/javascript"><!--
var urls={
	"001":"http:\/\/hoge.example.com/page_001.html",
	"002":"http:\/\/moge.example.com/page_002.html",
	"003":"http:\/\/kome.example.com/page_003.html"
};

var key=window.location.href.match(/\/archive\/([0-9]+)/);

if(key){
	document.write('\<link rel="canonical" href="'+urls[key[1]]+'"\>');
}
//-->
</script>

これをheadタグの中で、なるべく上の方に書けばいいと思います。古い記事のURLがhttp://old_url.com/archive/001なら「http://hoge.example.com/page_001.html」というように、それぞれの新URLをヘッダに追記します。

しかし、記事が何百ページもあったら上のやり方では無理があります。

新ドメイン側の.htaccessに旧URLを渡して、振り分ける

大抵の無料ブログでは.htaccessは使えないし、だからこの記事のような困りごとになるわけですが、新しいサイトでは.htaccessが使えます。だから新サイトの.htaccessにパラメータを渡してリダイレクトさせればいいわけです。

旧ブログのヘッダには次のように書き加えます。スクリプトで追記したタグが有効に作用するとは断言出来ないので完全なURLを書き込むようにしました。

<link rel=”canonical” href=”http://new_domain.com/url_converter.php?old_url={記事のURLを書き出すタグ}“>

{記事のURLを書き出すタグ}はブログによって違いますが

  • ライブドアブログなら {$ArticlePermalink$}
  • FC2ブログなら <%topentry_link>

となります。

参考:
独自タグ一覧(変数) – livedoor ブログ ヘルプセンター
FC2ヘルプ | FC2ブログ | テンプレート用 変数一覧

これで古いブログのURLが「http://old_url.com/archive/001」である記事が開かれると、ヘッダの中に次のタグが書き込まれます。URLエンコードが出来ないのが心配ですが、このブログでは無事にパラメータを渡せました。

<link rel=”canonical” href=”http://new_domain.com/url_converter.php?old_url=http://old_url.com/archive/001“>

Googleなどの検索エンジンがこのタグを読んだら、新ドメインのサーバに「http://new_domain.com/url_converter.php?old_url=http://old_url.com/archive/001」を問い合わせます。新しいサーバには古いURLがパラメータで渡されるので、それを判断材料に新しいURLに誘導すれば(リダイレクトさせれば)いいわけです。

参考記事:GET送信とは?

サーバー側のリダイレクト手順

ということで、サーバー側で.htaccessを使ってリダイレクトと書きましたが、何百個もある記事を、一定のパターンに沿って書きかえるならともかく、記事ごとに違うブログに振り分けるとなると.htaccessでは大変です。こうなると、旧URLと新URLを紐付けたデータベースを作って処理する方が簡単ではないでしょうか。作るデータベースのtableはこんな仕様になると思います。

CREATE TABLE url(
	old varchar(256),
	new varchar(256)
);

このテーブルに、URL対応表を作ってから、PHP等のインタープリタでアクセスすればいいと思います。アクセスする際は「SELECT new FROM url WHERE old=’xxx’」というクエリで新URLを取れるでしょう。

PHPの場合のソースは次のようになります。

<?php
$host='localhost';
$db='detabase_name';
$user='user_name';
$pwd='password';

$old=$_GET['old_url'];

if(empty($old)){
	header('HTTP/1.1 400 Bad Request');
	return;
}

try{
	$pdo=new PDO('mysql:host='.$host.'; dbname='.$db,$user,$pwd);
	$stmt=$pdo->query('SELECT new FROM url WHERE old="'.$old.'"');
	$row=$stmt->fetch(PDO::FETCH_ASSOC);

	if($row){
		header('HTTP/1.1 301 Moved Permanently'); 
		header('Location: '.$row['new']);
	}else{
		header('HTTP/1.1 404 Not Found'); 
	}
}catch (PDOException $e){
	header('HTTP/1.1 500 Internal Server Error');
}

$pdo=null;

余談ですがPHPコードのみからなるファイルでは、終了タグは書かない方がいいようです。
Zend Framework: Documentation: PHP ファイルの書式 – Zend Framework Manualより

PHP コードのみからなるファイルでは、終了タグ (“?>”) は決して含めてはいけません。これは必須なものではなく、 終了タグを省略することで、ファイルの最後にある空白文字が出力に影響することを防ぎます。

私はHTMLとの混合PHPの場合でも、最後がPHPの場合はいつも閉じタグを書きませんが、エラーが出たことはありません。

このブログが実際に使っているスクリプト

データベースを使わない場合は、連想配列で処理します。実際にこのブログで使っているのはデータベースを使わない以下のスクリプトです。

<?php
if(empty($_GET['old_url'])||!preg_match('|/ayzfqir5/archive/(\d+)|',$_GET['old_url'],$m)){
	header('HTTP',TRUE,400);
	exit();
}

$url_table=array(
	"826" => "1264",
	"825" => "1263",
	"824" => "1262",
	(中略)
	"12" => "587",
	"9" => "586",
	"6" => "585"
);

if(empty($url_table[$m[1]])){
	header('HTTP',TRUE,404);
	exit();
}

header('Location: http://dwm.me/archives/'.$url_table[$m[1]],TRUE,301);

$url_tableの左側のキーが旧ブログのURL、右が新しいブログのURLに当たります。

古いブログのURLは http://fanblogs.jp/ayzfqir5/archive/xxx/0 という形でした。xxx の部分だけ記事毎に違う数字です。その数字部分を正規表現で抽出してキーにします。新しいこのブログのURLは http://dwm.me/archives/xxx という形ですが、古いブログとは番号が違います。それを古いブログのキーと照らし合わせて抜き出し http://dwm.me/archives/ にくっつけて、header関数で返しています。

このブログは実際の移転でこの手法を使い、rel=”canonical”を発動させる事に成功したのですが、どのような効果を発揮したかを別記事「ブログの引越しで rel="canonical" が適用されたら検索結果とアクセス数がこう変わった」にまとめました。

8件のコメント

  1. ピンバック: 技術のタマゴ

  2. こんにちは。お世話になっております。
    現在、こちらの記事を参考に、rel=”canonical”の記述に挑戦中です。

    初歩的な質問で申し訳ありません。
    「このブログが実際に使っているスクリプト」に記載されているスクリプトは
    どこに記述すれば良いでしょうか?お手数をおかけしますが
    何卒、よろしくお願いいたします。

    • 一番最後の部分が重要なので必ずそれを見て。

      質問の答えとしては

      これはWordPressに書くのではなく、独自のファイルとして作ります。

      まず、手順の流れ。

      独自のファイルは index.php という名前以外ならなんでもいいのだけど、
      仮に moved_permanently.php という名前にしたとして説明。
      (index.phpにだけはしてはいけない)

      # 1 #
      ロリポップの public_html の真下に moved_permanently.php を配置する。

      正しく配置されていればブラウザで次のURLを指定すればアクセスできる。

      http://pointsite-de-okodukai.info/moved_permanently.php

      ただし「このブログが実際に使っているスクリプト」が書かれていると
      ブラウザは何も表示しないのでアクセスに成功しているかどうかわからない。

      # 1-2 #
      正しく配置できるか確認

      そこでテキストエディタで次の通りに書いた moved_permanently.php を
      public_html の真下に置いてブラウザでアクセスしてみる。
      「hello!」と表示されたら配置場所は正しい。

      ##### この次の行から(この行は含めない) #####

  3. お世話になっております。
    色々と悩んでみた結果、時期尚早かもしれませんが
    早く新体制に移行したいという思いから、rel=”canonical”を記述することにしました。

    つきましては、先程、Tomさんのコメントを参考に
    #4#の記述まで完了しました。(フライングしてすいません)

    その後、旧ブログの個別記事数点のソースを調べたところ
    バッチリ「rel=”canonical”」が追加されており、そのURLにアクセスすると
    新ブログの該当記事へ移動できる事を確認しました。

    それから、素人が差し出がましいようですが
    他の方の役に経つかもしれないので一応情報をば・・・

    最初、旧ブログ個別記事の
    http://pointsite-de-okodukai.info/moved_permanently.php?old_url=
    にアクセスしたところ、403エラーが出てアクセスできない状況でした。

    自分なりに原因を調べてみた結果、ロリポップのWAFが干渉していることが
    WAF履歴にて確認できたので、独自ドメインのWAFの設定を無効にしたところ
    良好にアクセスできるようになりました。

    しかしながら、素人がWAFを無効にするのは何とも心細いので
    プラグイン「All In One WP Security」をインストールして
    このプラグインのFirewallを有効にする等の対策を施してみました。

    何かの役に立てば幸いです・・・

    • 放ったらかしにしてごめん。

      今日の昼に「MONOW山分けキャンペーン」で検索したら「楽して稼ぎたい」の順序はそのままだけど
      「ポイントサイト研究所」が消えてたね。

      しばらく待てば戻ると思うけど、1位と2位が残っているので、うまく行くといいね。

      DISQUSの件も遅れていて申し訳ない。
      近いうちに送ります。

  4. はじめまして。こんばんは。かんきついろと申します。

    こちらの記事はつくってから知ったのですがcanonicalタグ追加するためのコピペコード(Javascript)をWordPressのエクスポートデータから自動生成するツールを作成しました。

    仕組みはURLとタイトルを紐づけし、Javascript埋め込みページ(呼び出し元)のページのタイトルを取得。タイトルをDB(連想配列)と線形探索、一致するものがあればCanonical出力いう簡単なものです。

    仕組みはどうであれコピペコードをだれでも簡単に作れるので、Headの書き換えができないような融通がきかないブログサービスからの移転の際にはぜひ試してみてほしい簡単ツールとなりました。以下にご紹介いたします。

    アメブロ/ウェブリブログ等用 Canonical引っ越し補助ツール
    http://happy-fox.info/titles/listup/21

    なおJavascriptからのcanonical記述の有効度は当サイトで実験、検証予定です。まだ100%有効なのかどうかは不明です。

コメントを残す

Top