検索エンジン経由のリクエストの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初心者なもので...


© 2024 KMIソフトウェア