#freeze [[FrontPage]] 2009/07/30 からのアクセス回数 &counter; #contents ** アクセスログ解析 [#m77c65e1] 自分のブログページに対し、どのようなことを知りたいと思ってアクセスしてきて いるのかを調べるために、 apacheのアクセスログの内、Googleの検索経由でアクセスされたものを抽出しました。 *** アクセスログのフィールド切り [#ma171ef7] アクセスログから、 - アクセス時刻 - アクセスページのURL - Googleの検索文字列 を取り出すことにします。 この解析は面倒だと思っていたら、以下のURLで正規表現を使って簡単に切り出せることが分かりました。 http://www.groovy-number.com/java/sample/AccessLog.html 切り出した、フォールドからブログのタイトルと検索文字列を取り出します。 - URLDecodeを使って%xxのように変換されている日本語を変換する - ブログはPukiWikiを使っているので、必ずindex.phpがGETコマンドに入っている - Googleの検索文字列は、q=の後に続く ことを考慮して、以下のように処理しました。 #pre{{ PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out)); BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(INPUT_FILE))); Pattern pattern = Pattern.compile(".+ .+ .+ \\[(.+) \\+0900\\] \"([^\"]+)\" .+ .+ \"([^\"]+)\" \"[^\"]+\""); String line = null; while ((line = reader.readLine()) != null) { Matcher matcher = pattern.matcher(line); if (matcher.matches()) { String time = matcher.group(1); String url = URLDecoder.decode(matcher.group(2), "UTF-8"); String google = matcher.group(3); String query=null; StringTokenizer token = new StringTokenizer(google, "?&"); while (token.hasMoreTokens()) { String str = token.nextToken(); if (str.indexOf("q=") == 0) { query = URLDecoder.decode(str, "UTF-8"); query = query.replaceFirst("q=", ""); } } url = url.replaceFirst("GET .*\\/index.php\\?", ""); url = url.replaceFirst(" HTTP\\/1..", ""); writer.printf("%s,", time); writer.printf("\"%s\",", url); if (query != null) writer.printf("\"%s\"", query); writer.println(); } else { System.out.println("解析できない行がありました:" + line); } } reader.close(); writer.close(); }} *** アクセスログからGoogle検索を抽出 [#g25a4a32] 最後にアクセスログからGoogle検索のログを切り出します。 以下のようなコマンドを使用します。 #pre{{ $ grep http://www.google.co.jp/search /var/log/apache2/access.log | grep index.php >1 }} ここでは、1に書き込んでいます。((変更する場合には、javaのプログラムも合わせて変更してください)) ** 出力例 [#l57c4c07] grepで切り出したGoogle検索ログからjavaのプログラムでブログのタイトルと検索文字列を抽出すると、 #pre{{ 27/Jul/2009:13:38:58,"antlr/ANTLRWorksを使ってみる","antlr " 27/Jul/2009:13:43:26,"Spring-MVC/ステップ・バイ・ステップ/Convention over configuration","Convention over Configration " 27/Jul/2009:14:07:19,"avr/最初の一歩","AVR ATmega32 配線" 27/Jul/2009:14:08:45,"手書きのプリント基板","ペン プリント基盤" 27/Jul/2009:14:24:41,"Spring-MVC/ステップ・バイ・ステップ/ソース解説","<property name="prefix" value="/WEB-INF/jsp/" />" 27/Jul/2009:14:42:22,"Spring-MVC/ステップ・バイ・ステップ/Daoの実装","daoインターフェース作成" 27/Jul/2009:14:46:29,"Cart問題","action #springUrl" }} のような結果がでました。 今後、この結果を蓄積し、記事間の類似度や検索文字列の類似などを調べてみたいと考えています。 ** コメント [#ndc7f3ba] この記事は、 #vote(おもしろかった[9],そうでもない[0],わかりずらい[0]) #vote(おもしろかった[9],そうでもない[1],わかりずらい[0]) 皆様のご意見、ご希望をお待ちしております。 #comment_kcaptcha