リダイレクトという言葉をご存じでしょうか?
Web上におけるリダイレクトとは、「URLを変更すること = 別のURLへジャンプさせること」を指します。
(厳密には、HTTPリダイレクトである場合がほとんどですが、リダイレクトと省略されることが多いようです。)
ProxomitronはURLヘッダ(便宜上のヘッダ)を変更することで、リダイレクトさせることが出来ます。
ProxomitronでURLヘッダを扱う人は、「認証ページ」や「URL転送ページ」をスキップする使い方をする事が多いようです。
他にも、CGIを使ったWebページでは、URLを変更することによって、ある程度は自分の好きなようにコンテンツを変更することが可能です。
非常に便利なので、是非使いこなしてみて下さい。
2ちゃんねるで http://
から始まるURLテキストを書き込むと、http://ime.nu/
から始まるURLにリンクが貼られます。
この転送用のページをスキップするフィルタを考えてみましょう。
まずは、URL転送ページのURL規則の解読から始めます。
2chのスレッドからいくつかのリンクを踏んでみて下さい。
「転送先URL」と「転送ページのURL」の関係に何らかの規則性があるはずです。
http://ime.nu/www.google.co.jp/
は http://www.google.co.jp/
にリダイレクトする。
もう、お分かりですね。
どうやら、「http://ime.nu/
以降の文字列」の先頭に http://
を付与したURLにリダイレクトしているようです。
ここまで解れば、後はURLに http://ime.nu/
を見つけたときに、Proxomitronが転送先URLにリダイレクトするようにフィルタを作るだけです。
さっそく、フィルタを作成してみましょう。
次のステップで [ヘッダフィルタ] の編集画面を出して下さい。
ヘッダフィルタの上の方にある入力欄は(Key)は、Webページフィルタの「フィルタ名」と似て非なるものです。
例えば、Key の先頭に Content-Type: ****
と記述することで、Content-Typeヘッダを編集することを意味するのです。
ヘッダ名を誤ると動作してくれませんので、注意して下さい。
今回、扱うヘッダは「URLヘッダ」になります。
(URLは一般的にはヘッダとして定義されていませんが、ProxomitronではURLを操作するフィルタを作成する都合上、ヘッダとして扱われます。)
では、Keyに URL:
から始まる名前を付けてみましょう。
URL:
以降は好きな名前を付けて良いので、「skip ime.nu」と命名してみました。
(Out)
はリクエストヘッダを扱うフィルタである事を示しています。
URLヘッダは便宜上のヘッダですが、リクエストヘッダとして設定されているため、このように命名しています。
(Out)
は URL:
と違って、必ず付けなければいけないわけではありませんが、Keyに (Out)
もしくは、(In)
を付けることは慣習となっているようです。
次に、Match欄の表現を考えます。
http://ime.nu/
URLヘッダのMatch欄においては、スキームからURLテストを行います。
http://ime.nu/(http://|)(*)\0
先程は説明を省きましたが、実は http://ime.nu/http://www.google.co.jp/
でもリダイレクトされます。
これに対応するために、(http://|)
の表現を入れておきます。
次に、リダイレクトするために必要な文字列を変数に格納する必要がありますが、そのままローカル変数を置くと、(http://|)
を変数に格納してしまいます。
これを回避するために、(*)\0
と記述します。
最後に、Replace欄の表現を考えます。
$JUMP(http://\0)
Proxomitronに用意されているリダイレクト用のマッチングコマンドは$JUMPと$RDIRです。
$JUMPはブラウザにURLが変更されたことを知らせますが、$RDIRは知らせないという違いがあります。
今回は、URLが変わったことを知らせて欲しいので、$JUMPを使うことになります。
最後に、ヘッダフィルタ編集画面を閉じ、[Out] をチェックオンにします。
[HTTP headers] In = FALSE Out = TRUE Key = "URL: skip ime.nu (Out)" Match = "http://ime.nu/(http://|)(*)\0" Replace = "$JUMP(http://\0)"
それでは、最終チェックです。
http://ime.nu/www.google.co.jp/, 及び, http://ime.nu/http://www.google.co.jp/ のリンクを踏んでみて下さい。
転送ページはスキップされましたか?
(リダイレクトに成功している場合は、[ログウインドウ] に JumpTo: http://www.google.co.jp/
という記述が残っているはずです。)
インターネット検索の経験のある方なら、Googleは馴染みのある検索エンジンだろうと思います。
実は、Google検索結果のURLには特別な意味があります。
例えば、http://www.google.co.jp/search?ie=utf-8&oe=utf-8&lr=lang_ja&num=20&q=Proxomitron
このURLから、ある程度、検索結果を予想することができるのです。
ie=utf-8
oe=utf-8
lr=lang_ja
num=20
q=Proxomitron
今回、注目するのは num=20
です。
この数値を "30" に変更してみると…?
http://www.google.co.jp/search?ie=utf-8&oe=utf-8&lr=lang_ja&num=30&q=Proxomitron
30件ずつWebページが表示するようになりましたね。
Googleは num=
の指定がない時には10件ずつ表示し、num=
の指定があるときには渡された数値分ずつ表示するようになっています。
ということは、「num=
の指定がない時」に num=30
を付与したURLへリダイレクトさせれば、常に30件以上ずつ表示できる事になります。
そのように動作するフィルタを作ってみましょう。
まず、Key を考えます。
URLヘッダ(便宜上のヘッダ)を扱うので、URL:
を記述します。
フィルタ名を記述し、URLヘッダはリクエストヘッダに設定されているので、(Out)
を追記します。
次に、Match欄の表現を考えます。
http://www.google.co(.jp|m)/search
Googleは http://www.google.co.jp/ と http://www.google.com/ の2つのURLを持っているので、両方に対応させます。
http://www.google.co(.jp|m)/search(^*[&?]num\=)
NOT関数によって、後ろに num=
がある場合にはマッチしないようにします。
(http://www.google.co(.jp|m)/search(^*[&?]num\=)*)\0
アスタリスク でURL末尾まで消費します。
置換テキストに元URLを渡すために、URL全体を \0
に格納します。(参考: ローカル変数)
最後に、Replace欄の表現を考えます。
$JUMP(\0&num=30)
今回もリダイレクトする事を知らせたいので、$JUMPを用います。
[HTTP headers] In = FALSE Out = TRUE Key = "URL: Google redirector [num=30] (Out) type1" Match = "(http://www.google.co(.jp|m)/search(^*[&?]num\=)*)\0" Replace = "$JUMP(\0&num=30)"
それでは、最終チェックです。
http://www.google.co.jp/search?lr=lang_ja&q=Proxomitron のURLへ行って、結果を確かめてみて下さい。
「num=
の指定がない時」だけではなく、「num=
の値が30より少ない時」にも、num=30
にするフィルタを考えてみましょう。
前回と違う部分はMatch欄だけなので、Match欄に絞って考えます。
http://www.google.co(.jp|m)/search([&?](^num\=)[^&]+)+
「num=
の指定がない時」に、元URLに num=30
を付加すると num=
が2つ存在するURLになってしまいます。
これは num=
を省いた文字列を取得しておけば回避できるので、そのようにします。
([&?](^num\=)[^&]+)+
で、「num=
を含まないクエリ文字列」を繰り返します。(参考: title要素がないページにtitleを付け加える2)
この表現によって、num=
の指定がない時にはURLの末尾まで、num=
の指定がある時には、num=
の手前まで消費できます。
http://www.google.co(.jp|m)/search([&?](^num\=)[^&]+)+(^[&?]num\=[#30:*])([&?]num\=[^&]+|)
次に来る文字列は「&num=
」か「URLの終端」であるはず。
(^[&?]num\=[#30:*])
によって、num=
の値が30以上である時にマッチしないようにします。(参考: NOT関数, 文字クラス)
次に、something or nothing を用いて、num=
が存在する時には、消費しておきます。
(http://www.google.co(.jp|m)/search([&?](^num\=)[^&]+)+)\#(^[&?]num\=[#30:*])([&?]num\=[^&]+|)(*)\#
num=
の文字列の両脇を置換スタックに格納します。
末尾に \#
をそのまま置くと、([&?]num\=[^&]+|)
をスタックに格納してしまうので、(*)\#
で対応しておきます。
[HTTP headers]
In = FALSE
Out = TRUE
Key = "URL: Google redirector [num=30] (Out) type2"
Match = "(http://www.google.co(.jp|m)/search([&?](^num\=)[^&]+)+)\#(^[&?]num\=[#30:*])([&?]num\=[^&]+|)(*)\#"
Replace = "$JUMP(\@&num=30)"
最後に確認を。
以下のURLを踏んで、それぞれの結果を確かめてみて下さい。