検索エンジン経由のリクエストのrefererから,検索語を取り出すプログラムを書いた.(Ruby)
2009-08-01 対象の検索エンジンにBingを追加しました
2009-03-05 初版
Rubyでrefererから検索キーワードを抽出する
諸事情により,検索エンジン経由のリクエストのリファラーから,検索語を取り出すことにした.
どういうキーワードで検索して,このページに飛んできたのかを知るためだ.
以前,
キーワード抽出による関連ページ導出(2)で少し考えていたことの続きです.
Rubyで作成してみた.しかしencoding関係のメソッドを使っているので,1.9でないと動かないはず.
def
parse_referer(s_referer)
# name : 検索エンジン名 【必須】
# match : リファラの先頭(ホスト名) 【必須】
# p_word: 検索語のパラメータ名 【必須】
# p_enc : 検索語エンコーディングのパラメータ名
# d_enc : エンコーディング無指定時に適用するデフォルトエンコーディング
engine_list = [
Hash
[* %w(
name Google
match (www)?\.?google.*
p_word q
p_enc ie
d_enc utf8,sjis
) ],
Hash
[* %w(
name Yahoo
match search\.yahoo.*
p_word p
p_enc ei
d_enc utf8,euc
) ],
Hash
[* %w(
name LiveSearch
match search\.live\.com.*
p_word q
p_enc cp
d_enc utf8
) ],
Hash
[* %w(
name MSN
match search\.msn.*
p_word q
p_enc cp
d_enc utf8
) ],
Hash
[* %w(
name goo
match search\.goo.*
p_word MT
p_enc ie
d_enc euc
) ],
Hash
[* %w(
name Infoseek
match .*search\.www\.infoseek\.co\.jp
p_word qt
d_enc utf8,euc
) ],
Hash
[* %w(
name nifty
match .*search\.nifty\.com\/cgi\-bin\/
p_word Text
p_enc ie
d_enc sjis,euc
) ],
Hash
[* %w(
name nifty
match .*search\.nifty\.com\/websearch\/
p_word q
d_enc utf8
) ],
Hash
[* %w(
name biglobe
match .*search\.biglobe\.ne\.jp
p_word q
d_enc sjis,euc
) ],
Hash
[* %w(
name Mooter
match www\.mooter\.co\.jp
p_word keywords
d_enc utf8
) ],
Hash
[* %w(
name Bing
match www\.bing\.com
p_word q
d_enc utf8
) ],
]
engname, query, enc = nil
, nil
, nil
matched = engine_list.index {|v| s_referer =~ /^http:\/\/#{v['match'
]}/i }
if
matched
eng = engine_list[matched]
engname = eng['name'
]
s_referer.gsub!(/\\x/,'%'
)
if
s_referer =~ /[&|\?]#{eng['p_word'
]}=([^&|#]+)[&|#]?/i
query = $1
enc_alias = Hash
[* %w(
sjis Shift_JIS
shift_jis Shift_JIS
932 Shift_JIS
euc-jp EUC-JP
euc EUC-JP
utf8 UTF-8
utf-8 UTF-8
)]
# URL decode
query = query.tr('+'
, ' '
).gsub(/%([A-Fa-f0-9][A-Fa-f0-9])/) { [$1
.hex].pack('C'
) }
if
eng['p_enc'
] and
s_referer =~ /[&|\?]#{eng['p_enc'
]}=([^&|#]+)[&|#]?/i
enc = enc_alias[$1
.downcase]
end
if
enc
query.force_encoding(enc)
enc = nil
unless
query.valid_encoding?
else
eng['d_enc'
].split(','
).each
do
|e|
enc = enc_alias[e]
query.force_encoding(enc)
break
if
query.valid_encoding?
enc = nil
end
end
end
end
[engname, enc, query]
end
使用例
【プログラム】
ref = "http://www.google.co.jp/search?hl=ja&lr=lang_ja&q=ruby+%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB"
engname, enc, query = parse_referer(ref)
p engname
p query.encode('Shift_JIS'
)
【実行結果】
"Google"
"ruby インストール"
Rubyの達人なら,検索エンジン定義の箇所は言語内DSLっぽく記述できるようにするんだろうけど,
Ruby初心者なもので...