SQLの窓

2013年03月01日


VBS : レンタルサーバーに画像を置いてブログに貼ると、アクセスログで記事毎のアクセス状態を知る事ができます

自分が使っているサーバーのアクセスログは以下のようになっているので、IPアドレスとタイムスタンプを正規表現で取り出して該当記事がいつどこからの IP からアクセスされたかを知る事ができます。
xxx.xxx.xxx.xxx - - [27/Feb/2013:10:21:24 +0900] "GET /image/logical_error.png HTTP/1.1" 200 28573 "http://logicalerror.seesaa.net/article/331996491.html" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
Windows で実はなにより手軽な VBScriptで

適当なフォルダにログを置いて、同じ場所に以下の checklog.vbs を置いて、先頭にログのファイル名と出力ファイルと対象となる記事の URL を指定してエクスプローラから実行します。

IPアドレスの正規表現は厳密ではありませんが、調べてみると IP アドレスの正規表現は複雑なわりに信頼性低そうなので、きちんとチェックしたい場合はプログラムでチェックして読み飛ばすなりしたほうが良いと思いました。

checklog.vbs
FilePath = "access_log_20130227"
OutFile = "check_27.log"
TargetUrl = "http://logicalerror.seesaa.net/article/331996491.html"

' **********************************************************
' オブジェクト作成
' **********************************************************
Set Fs = CreateObject( "Scripting.FileSystemObject" )

' **********************************************************
' ファイルオープン
' **********************************************************
on error resume next
Set InFile = Fs.OpenTextFile( FilePath, 1 )
if Err.Number <> 0 then
	Wscript.Echo Err.Description
	Wscript.Quit
end if
on error goto 0
Set OutFile = Fs.OpenTextFile( OutFile, 2, True )

' **********************************************************
' 正規表現
' **********************************************************
Set regEx = New RegExp
' 検索パターン : IPアドレスらしきものとタイムスタンプ
regEx.Pattern = "(\d+\.\d+\.\d+\.\d+)[^\n]+(\[[^\n]+\])"
' 大文字小文字を区別しない
regEx.IgnoreCase = True
' 文字列全体を検索
' False だと一件しか検索しない
regEx.Global = True

' **********************************************************
' 処理
' **********************************************************
strBreak = ""
Do While not InFile.AtEndOfStream
	' 行を読み取る
	Buffer = InFile.ReadLine
	' 対象となる URL を含んでいる
	if instr( Buffer, TargetUrl ) <> 0 then

		' 行を調べる
		Set Matches = regEx.Execute(Buffer)

		strTarget1 = ""
		For Each Match in Matches
			' 検索結果の中の 最初に見つけた IPアドレスらしきもの
			strTarget1 = Match.SubMatches(0)
			' IPアドレスらしきもの後にある、[] で囲まれたタイムスタンプ
			strTarget2 = Match.SubMatches(1)

			' 一つのセットのみで良い
			Exit For
		Next

		' IPアドレスらしきものがあった場合
		if strTarget1 <> "" then
			' 初回と、連続するIPアドレスらしきものの先頭のみ出力
			if strBreak <> strTarget1 then
				OutFile.WriteLine strTarget1 & vbTab & strTarget2
			end if

			' 今回の内容を保存
			strBreak = strTarget1
		end if

	end if
Loop

' **********************************************************
' ファイルクローズ
' **********************************************************
OutFile.Close
InFile.Close

Wscript.Echo "処理が終了しました"

記事 URL をサイト URL に短縮すると

サイトに対するアクセスログを IP アドレスで分析する事になります。出力フォーマットは以下のような感じになっているので、コマンドプロンプトを使ってソートすれば、マッチング処理で同一 IP からのアクセスを分析できると思います。
xxx.xxx.xxx.xxx	[27/Feb/2013:10:21:24 +0900]
xxx.xxx.xxx.xxx	[27/Feb/2013:12:02:59 +0900]
xxx.xxx.xxx.xxx	[27/Feb/2013:15:43:20 +0900]
ソートは、type check_27.log | sort > check_27s.log のようにすると作成できます。 マッチングは、ソートされた二つのファイルを使って同一 IP アドレスを出力するようにするものですが、以下のようなものを作ってテストしてみました。
FilePath = "check_26s.log"
FilePath2 = "check_27s.log"
OutFileName = "match.log"

' **********************************************************
' オブジェクト作成
' **********************************************************
Set Fs = CreateObject( "Scripting.FileSystemObject" )

' **********************************************************
' ファイルオープン
' **********************************************************
on error resume next
Set InFile = Fs.OpenTextFile( FilePath, 1 )
if Err.Number <> 0 then
	Lbox.MsgOk( Err.Description )
	Wscript.Quit
end if

Set InFile2 = Fs.OpenTextFile( FilePath2, 1 )
if Err.Number <> 0 then
	Lbox.MsgOk( Err.Description )
	Wscript.Quit
end if
on error goto 0
Set OutFile = Fs.OpenTextFile( OutFileName, 2, True )

' **********************************************************
' マッチング処理
' **********************************************************
Buffer = InFile.ReadLine
wk = Split(Buffer,vbTab)
Buffer = wk(0)

Buffer2 = InFile2.ReadLine
wk = Split(Buffer2,vbTab)
Buffer2 = wk(0)

Do While not InFile.AtEndOfStream

	if Buffer = Buffer2 then
		OutFile.WriteLine Buffer
	else
		Do While Buffer >= Buffer2 and not InFile2.AtEndOfStream
			Buffer2 = InFile2.ReadLine
			wk = Split(Buffer2,vbTab)
			Buffer2 = wk(0)
			if Buffer = Buffer2 then
				OutFile.WriteLine Buffer
			end if
		Loop
	end if

	Buffer = InFile.ReadLine
	wk = Split(Buffer,vbTab)
	Buffer = wk(0)
Loop

' **********************************************************
' ファイルクローズ
' **********************************************************
OutFile.Close
InFile.Close

Wscript.Echo "処理が終了しました"

マッチング処理は昔からある二つのファイルの比較方法で、二つのファイルの比較するキーが同一ならば、どちらか一つを読み進めて( この場合は、InFile )、それ以外では小さいほうのファイルを読み進めます。そうすると必ず同じデータがヒットするというアルゴリズムです。

この方法は、データベースが無くてもテキストデータをソートするコマンド( SORT )さえあれば可能なので、バッチ処理として使う上において今でもとても有効だと思います。




タグ:VBScript
posted by lightbox at 2013-03-01 10:00 | VBS + インターネット | このブログの読者になる | 更新情報をチェックする
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり