アクセスログから、Googleでどんな検索をして、このサイトに来たかを知る方法

Google Analytics を使えばいいんだけど、まぁシェル芸でもできるんやで。
Added by kanata about 8 years ago

やりたいこと

まず、こういうタイプのApacheのログがある。

999.999.999.999 - - [01/Jun/2016:00:00:00 +0900] "GET /projects/a-painter-and-a-black-cat/news HTTP/1.1" 200 54953 "https://www.google.co.jp/search?q=%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf&btnG=%E6%A4%9C%E7%B4%A2&hl=ja" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"

このログからは、googleで検索して、このページに来たことがわかる。Refererに記録されている。

ただ、マルチバイト文字は、すべからくURLエンコードされていて、そのままでは読めない。ログから、それを抽出して、デコードして表示してみましょう。

Google Analyticsを使えばいいという話もあるけれど、シェル芸の練習でやってみます。

ログの抽出

ここがシェルスクリプトの真骨頂である。1行でいける。

まず、該当のログを出力してみる。

# cat /var/log/httpd/access_log-???????? /var/log/httpd/access_log

全部のログが表示されちゃう。絞り込んでみよう。

  • "google"が含まれるログに絞り込む。
| grep google
  • そこから、"Googlebot"を含まないログに絞り込む。
|grep -v Googlebot
  • そこから、q=&"を含まないログに絞り込む。
|grep -v "q=&"
  • そこから、"q=cache"を含まないログに絞り込む。
|grep -v "q=cache"
  • そこから、"q="を含むログに絞り込む。
|grep q=

全部くっつけて、、、こうじゃ!

# cat /var/log/httpd/access_log-???????? /var/log/httpd/access_log |grep google|grep -v Googlebot|grep -v "q=&"|grep -v "q=cache"|grep q=

環境の違いで、微妙に上手くいかない人もいるかと思うが、適宜調整してください。

URLデコード

URLデコードは、実はワンライナーで実現できる。

perl -e '$ARGV[0]=~s/\+/ /g;$ARGV[0]=~s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;print"$ARGV[0]\n"' "ここにURLエンコードデータ"

上の方に書いたログで試してみよう。

対象は、以下の部分である。

%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf

ほい。

$ perl -e '$ARGV[0]=~s/\+/ /g;$ARGV[0]=~s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;print"$ARGV[0]\n"' "%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf"
画像 データ 隠蔽 ctf

さて、ログから該当部分を抽出するにはどうするか。

こうした。

  • "q="を区切り文字として、それ以降を出力
echo 'ログのデータ1行' | awk -F'q=' '{print $2}'
  • "&"を区切り文字として、その手前を出力
|awk -F'&' '{print $1}'
  • "(ダブルコーテーション)を区切り文字として、その手前を出力
|awk -F'\"' '{print $1}'

全部くっつけて、、、こうじゃ!

echo 'ログのデータ1行' | awk -F'q=' '{print $2}'|awk -F'&' '{print $1}'|awk -F'\"' '{print $1}'

実際に試してみよう。

$ echo '999.999.999.999 - - [01/Jun/2016:00:00:00 +0900] "GET /projects/a-painter-and-a-black-cat/news HTTP/1.1" 200 54953 "https://www.google.co.jp/search?q=%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf&btnG=%E6%A4%9C%E7%B4%A2&hl=ja" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"' | awk -F'q=' '{print $2}'|awk -F'&' '{print $1}'|awk -F'\"' '{print $1}'
%E7%94%BB%E5%83%8F+%E3%83%87%E3%83%BC%E3%82%BF+%E9%9A%A0%E8%94%BD+ctf

ちゃんと抽出できてますね。

Googleでどんな検索をして、このサイトに来たかを知るツール(シェルスクリプト)

それで、こんなシェルスクリプトを作ってみた。
時系列でどんな検索ワードで飛んできたかわかる。

PrintGoogleSearchWords.sh

#!/bin/bash

IFS='
'

CONTENT=`cat /var/log/httpd/access_log-???????? /var/log/httpd/access_log |grep google|grep -v Googlebot|grep -v "q=&"|grep -v "q=cache"|grep q=`

for WORD in ${CONTENT}
do
  HOST_NAME=`echo ${WORD} | awk '{print $1}'`
  ACCESS_DATE=`echo ${WORD} | awk '{print $4}'|tr -d '['`
  URL_ENCODE_DATA=`echo ${WORD} | awk -F'q=' '{print $2}'|awk -F'&' '{print $1}'|awk -F'\"' '{print $1}'`
  URL_DECODE_DATA=`perl -e '$ARGV[0]=~s/\+/ /g;$ARGV[0]=~s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;print"$ARGV[0]\n"' ${URL_ENCODE_DATA}`
  printf "%s %15s %s\n" ${ACCESS_DATE} ${HOST_NAME} ${URL_DECODE_DATA}
done

exit 0

Comments

Add picture from clipboard (Maximum size: 100 MB)