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