天天看點

php提取nginx日志增量,從nginx日志中提取爬蟲資訊

Update:2016.03.26 發現有僞裝成googlebot的client,嚴格篩選進入爬蟲資訊統計的日志,增加請求類型為GET的條件&& $2~/GET/ 。

一般來說,搜尋引擎爬蟲不會執行頁面上的JavaScript代碼,而網站分析工具 大多又是基于JavaScript代碼的,這也就是說,預設情況下,網站分析工具不能記錄到搜尋引擎爬蟲這部分的流量。但搜尋引擎爬蟲資料對于SEO又是非常的重要,那麼如何才能拿到搜尋引擎爬蟲對網站的爬取資料呢?方法可能有很多,比如直接從網站伺服器日志中來統計爬蟲資訊。本文以nginx日志為例,來說明如何從中提取出爬蟲資訊。

一、讀取日志

設定讀取檔案的換行符為\n,告知程式需要讀取的檔案的路徑和檔案名,檔案名中的日期使用當天的前一天,這樣之後将這個處理腳本弄成每天定時任務的話,每天處理的都是前一天的日志。

讀取日志的時候有一個需要特别注意的地方是,應該使用日志中的User Agent資訊是否包含爬蟲辨別來過濾,而不能簡單地使用grep來過濾,這樣日志中其他部分包含這些辨別的也會被過濾出來當做爬蟲處理,比如有一條日志請求URI可能為/robots.txt,如果使用grep簡單過濾,所有通路過/robots.txt的都會被當做為爬蟲,顯然是不對的。

還有一個值得注意的是,Yahoo! 搜尋引擎爬蟲的User Agent資訊中既不包含bot,也不包含spider,需要用其特有的yahoo! slurp來比對。

主要Bash代碼:

IFS=$'\n'

dt=$(date -d'yesterday' '+%Y%m%d') #每天讀取前一天的日志

logfile="/var/log/nginx/access.log-${dt}.gz" #nginx access.log日志

#讀取日志并将User Agent資訊中包含爬蟲辨別的過濾出來進行解析操作

zcat ${logfile} | awk -F'"' 'tolower($6)~/bot|spider|yahoo! slurp/ && $2~/GET/  {print $0}' | \

while read line

do

二、解析日志

解析日志主要使用awk,其中爬蟲名稱的識别使用bash中的case語句,注意case語句末尾是兩個分号(;;)。

要提取爬蟲通路時的時間中的hour,需要用到grep -oE,即正則比對且截取子串,提取到的子串可能是0開頭的,如上午8點日志中是08,可以使用sed去除前面的0,然後再做時區轉換。注意,這裡的正則比對式要寫得足夠嚴謹,不然跑出來的資料可能亂七八糟的。

爬取的這些資訊之後都要存入資料庫,而資料庫中字段的長度是有限制的,比如這裡限制了page_url為255個字元,是以對于超過255個字元的需要截取,可以用cut,截取前255個字元。

主要Bash代碼:

user_agent=$(echo ${line} | awk -F'"' '{print tolower($6)}')

spider_name='unknown'

case ${user_agent} in

*google*mobile*|*mobile*google*)

spider_name='googlebot-mobile';;

*googlebot-image*)

spider_name='googlebot-image';;

*googlebot*)

spider_name='googlebot-pc';;

*mobile*baiduspider*)

spider_name='baiduspider-mobile';;

*baiduspider*)

spider_name='baiduspider-pc';;

*360spider*|*haosouspider*)

spider_name='360spider';;

*mobile*bingbot*)

spider_name='bingbot-mobile';;

*bingbot*)

spider_name='bingbot';;

*yahoo*)

spider_name='yahoobot';;

*yandexbot*)

spider_name='yandexbot';;

*sogou\ web\ spider*)

spider_name='sogoubot';;

esac

access_date=$(date -d ${dt} +'%Y-%m-%d') #爬取日期即為處理的access.log檔案名中的日期

origin_hour=$(echo ${line} | grep -oE '([01][1-9]|10|3[01])\/[a-zA-Z]{3}\/20[1-9]{2}:([01][0-9]|2[0-3])' | awk -F':' '{print $2}')

format_hour=$(echo ${origin_hour} | sed -r 's/^0([0-9])/\1/')

access_hour=$(((format_hour + 8) % 24)) #轉換成中原標準時間的小時

page_url=$(echo ${line} | awk -F'"' '{print $2}' | awk -F' ' '{print $2}')

#爬取的頁面url隻保留前255個字元

if [ ${#page_url} -gt 255 ]

then

page_url=$(echo ${page_url} | cut -c1-255)

fi

http_status=$(echo ${line} | awk -F'"' '{print $3}' | awk -F' ' '{print $1}')

三、存儲資料到資料庫

echo INSERT INTO就将這些資料插入了MySQL了,因為這裡是root身份的,是以不需要在mysql後帶上user和password也可直接登入

Bash代碼:

#存入資料庫

echo "INSERT INTO blog_spider_test (spider_name,date,hour,page_url,http_status) VALUES('$spider_name','$access_date','$access_hour','$page_url','$http_status');" | mysql test

四、前端展示

目前還做得比較粗糙,到w3school拷貝了一份php代碼,改了下SQL查詢,現在在浏覽器裡就可以看網站爬蟲的資料了。至于要支援排序、分組等功能,隻能之後有空再折騰下了。

本文完整的Bash腳本可參見:這個gist