はてなブログは独自ドメインへの移行時を除いて301リダイレクトをサポートしていません。
そのため、JavaScriptなどでリダイレクトを実装する必要があります。
ところがリダイレクトしたいURLが複数ある場合、コーディングにかなりの手間がかかります。
そこで、新旧URLの対応表からリダイレクト用コードを自動生成するスクリプトをPythonで作ってみました。
※追記:本記事のJavaScriptコードで大量のページをリダイレクトする場合、ページの読み込みが非常に遅くなる可能性があります。この点を改良した軽量化・高速化バージョンを別の記事で公開しましたので、併せてご覧ください。
リダイレクト用コード
生成するJavaScript(正確にはJavaScriptを埋め込んだHTMLコード)は以下の形式です。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript" language="javascript">
// <![CDATA[
var href = window.location.href;
var re = new RegExp(".*entry/{old_url}");
if (re.test(href)) {
$(document).ready(function() {
if ($("#main-inner").children().hasClass("no-entry")) {
var content = "<p>本記事は移転しました。</p><p>約3秒後にリダイレクトします。</p><p>リダイレクトしない場合は<a href='{new_url}'>こちら</a>をクリックしてください。</p>" ;
$(".entry-footer").addClass("sorry_content");
$(".entry-footer").html(content);
}
});
var url = "{new_url}";
var link = document.getElementsByTagName("link")[0];
link.href = url;
setTimeout("redirect()", 3000);
function redirect(){
location.href = url;
}
}
// ]]>
</script>
上のコードはこちらのサイトに掲載されているものをごく一部だけ変更したものです。
http://seiritozakki.hatenablog.com/entry/hatena-custom-url
変更箇所は次の通り。
- jQueryの読み込み先を最新版に変更
- クオテーションマークをできるだけダブルに統一
- 置換箇所の明示
- 日本語文の言い回し
旧URLにアクセスすると下のようなページが表示され、自動的に新URLに転送されます。

使い方
{old_url}
を旧URLの〜entry/
以降と置換する(1箇所、例:2019/07/29/225324
){new_url}
を新URL(全体)と置換する(2箇所、例:https://www.joe-hitagi.com/entry/ksc_m11-plug
)- コードを「デザイン設定」→「ヘッダー」に貼る
リダイレクトしたいページが複数ある場合は// <![CDATA[
〜// ]]>
の部分をコピペして対応してください。
しかし、なかなかに面倒なので、HTMLコードを自動で生成するスクリプトをつくってみました。
コード生成用スクリプト
# -*- coding: utf-8 -*-
#=======================設定する変数ここから=======================
#output_dir = r'/Users/'
output_dir = r''
#出力ファイルを保存するディレクトリ(末尾に区切り文字を含む)
#空白ならこのスクリプトがあるディレクトリに出力する
output_name = r'URLtest.txt'
#出力ファイル名(拡張子含む)
#=======================設定する変数ここまで=======================
import os
import sys
import re
import pandas as pd
if output_dir == '':
output_dir = os.path.dirname(os.path.abspath(__file__)) + os.sep
#スクリプトがあるディレクトリの絶対パスを取得
script_head = '<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>\n'\
'<script type="text/javascript" language="javascript">'
script = '// <![CDATA[\n'\
' var href = window.location.href;\n'\
' var re = new RegExp(".*entry/{old_url}");\n'\
' if (re.test(href)) {\n'\
' $(document).ready(function() {\n'\
' if ($("#main-inner").children().hasClass("no-entry")) {\n'\
' var content = "<p>本記事は移転しました。</p><p>約3秒後にリダイレクトします。</p><p>リダイレクトしない場合は'\
'<a href=\'{new_url}\'>'\
'こちら</a>をクリックしてください。</p>" ;\n'\
' $(".entry-footer").addClass("sorry_content");\n'\
' $(".entry-footer").html(content);\n'\
' }\n'\
' });\n'\
' var url = "{new_url}";\n'\
' var link = document.getElementsByTagName("link")[0];\n'\
' link.href = url;\n'\
'\n'\
' setTimeout("redirect()", 3000);\n'\
' function redirect(){\n'\
' location.href = url;\n'\
' }\n'\
' }\n'\
'// ]]>'
script_foot = '</script>'
inputs = sys.argv
#コマンドライン引数を取得
if len(inputs) != 2:
print('[ERROR: 入力ファイルをコマンドライン引数で1つ指定してください]')
quit()
url_file = inputs[1]
df = pd.read_excel(url_file, header=None, index_col=None)
#エクセルファイルをdata frameとして読み込み
url_lst = []
#旧URLと新URLの組を格納するリスト
for row in df.itertuples():
#ループで各行を取得
old_url = row[1]
new_url = row[3]
if (type(old_url) is str) and ('/entry/' in old_url) and (type(new_url) is str) and re.match('https?://', new_url):
#URLが書かれているかを判定
url_lst.append([old_url, new_url])
with open(output_dir + output_name, 'w') as output_file:
print(script_head, file=output_file)
for item in url_lst:
old_entry = re.search('entry/(.*)', item[0]).group(1)
script2 = script.replace('{old_url}', old_entry)
script2 = script2.replace('{new_url}', item[1])
print(script2, file=output_file)
print(script_foot, file=output_file)
動作環境
上記コードはPython3で動きます。
ただし、追加で以下のライブラリが必要です。
- Pandas
- xlrd
ライブラリのインストールはpip
コマンドで行います。
Anacondaの場合はpip
の代わりにconda install
を使わないと故障の危険があるのでご注意。
使い方
URL対応表の用意
URLの新旧の対応を記録したエクセルファイル(.xlsx)を予め用意する必要があります。
ファイルの形式は次の通りです。

1列目に旧URLを書き、2列目を空けて3列目に新URLを書きます。
URL以外の文字が書かれたセルや空白のセルは無視されます。それを利用して項目名などを書いていただいても良いと思います。
上の図の例では、実際にスクリプトに認識されるのは2行目と4行目のみです。
スクリプトの設定
設定すべき変数はoutput_dir
とoutput_name
の2つのみです。
スクリプト内に記入例があるので参考にしてください。
スクリプトの起動方法
コマンドプロンプトに次のように入力すると、リダイレクト用のJavaScriptが書かれたテキストファイルが出力されます。
python [スクリプト.py] [URL対応表.xlsx]
環境によってはpython
ではなくpython3
などと入力しないと動かないかもしれません。
スクリプトファイルや入力ファイルがカレントディレクトリにない場合、ファイル名だけでなくパスも入力する必要があります。
ファイルをコマンドプロンプトにドラッグアンドドロップすると、自動的に絶対パスが入力されるので便利ですよ。
注意
試しに40個のURLを組み込んだJavaScriptコードを本ブログに貼り付けたところ、ページの読み込みが非常に遅くなりました。
本スクリプトを使用される場合、まずは少ないURL数で様子見してください。
※追記:冒頭にも述べたとおり、改良型を下の記事でご紹介しています。基本的な使い方は同じです。
おまけ:スクリプトのカスタマイズ
URL対応表を下図のようにし、1列目に「1」が入力されている行のURLだけリダイレクト用コードに埋め込むように改良してみました。

上の図の例では、実際にコードに埋め込まれるのは2行目と5行目です。
カスタマイズ後のコードは、前述のコードのfor
ループを以下のように書き換えたものです。
処理の一部に新たな条件分岐を加えています。
for row in df.itertuples():
#ループで各行を取得
flag = row[1]
if flag == 1:
old_url = row[2]
new_url = row[4]
if (type(old_url) is str) and ('/entry/' in old_url) and (type(new_url) is str) and re.match('https?://', new_url):
url_lst.append([old_url, new_url])
コメント
こんにちは、
ジョー・ヒタギさんはとてもプログラミングにお強いのですね。とても分かりやすい説明ですし。
せっかくこんなに詳細に図解して頂いているので実践してみないともったいないですね。撫子
撫子さん こんにちは
私のプログラムは独学・自己流ですが、IT職の方にそのように言っていただけると嬉しいような気恥かしいような気がします。
機会があればぜひご利用ください。