Apacheのログから検索ワードランキングを生成(C#)


Apacheのログから検索ワードを抽出してみました。



検索ワードの出現頻度順にソートしたCSVファイルを出力させています。
グラフはエクセルで描いていますが、nplot等のグラフ描画ライブラリを使うと、
ツールのみでグラフ画像生成までできそうですね。

定期的に画像(or htmlのtable)を更新すればリアルタイムランキングが生成できそうです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Collections;
using System.Diagnostics;
namespace ApacheLogAnalyzer
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string path_input  = @"C:Program Fileshogeaccess_bak_for_anylyze.log";//Apacheのログ
                string path_output = @"C:Program FileshogeApacheLogAnalyzer.csv";//出力CSV
                string url_google = "http://www.google.co.jp/search";
                string url_yahoo = "http://search.yahoo.co.jp/search";

                StreamReader sr = new StreamReader(path_input);

                Dictionary<string, int> dic = new Dictionary<string, int>();
                string line = "";
                //ログ解析
                while ((line = sr.ReadLine()) != null)//1行ずつ
                {
                    string query = "";
                    //検索エンジンのURLが含まれているか
                    if (line.Contains(url_google))//google
                    {
                        Match m = Regex.Match(line, url_google + @".*?q=(.*?)[&$]", RegexOptions.IgnoreCase);
                        if (m.Success)
                        {
                            query = m.Groups[1].Value;
                        }
                    }
                    else if(line.Contains(url_yahoo))//yahoo
                    {
                        Match m = Regex.Match(line, url_yahoo + @".*?p=(.*?)[&$]", RegexOptions.IgnoreCase);
                        if (m.Success)
                        {
                            query = m.Groups[1].Value;
                        }
                    }
                    if (query != "")
                    {
                        //URLデコード
                        query = HttpUtility.UrlDecode(query, Encoding.UTF8);//GetEncoding("SJIS"));

                        //空白文字で区切り、配列とする
                        query = query.Replace(" ", " ");//全角スペースを半角スペースに置換
                        string[] words = query.Split(' ');//空白で分割

                        //ワードごとの検索数を数える
                        foreach (string word in words)
                        {
                            if (word != "")
                            {
                                if (!dic.ContainsKey(word))
                                {
                                    dic.Add(word, 1);//追加
                                }
                                else
                                {
                                    dic[word]++;//カウントアップ
                                }
                            }
                        }
                    }
                }
                //検索数が多い順にソートしてCSV出力
                List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>(dic);
                list.Sort(sorter);

                StreamWriter sw = new StreamWriter(path_output, false, Encoding.GetEncoding("SJIS"));
                foreach (KeyValuePair<string, int> kvp in list)
                {
                    sw.WriteLine(""" + kvp.Key + ""," + """ + kvp.Value +""");
                }
                sw.Close();

                //ビューワで開く
                Process.Start(path_output);
            }
            catch (Exception exp)
            {
                Console.WriteLine(exp.Message);
            }
        }
        static int sorter(KeyValuePair<string, int> k1, KeyValuePair<string, int> k2)
        {
            return k2.Value - k1.Value;
        }
    }
}

、、、それにしても、ニコ生系のワードが多いですね。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です