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

 

发表评论

电子邮件地址不会被公开。

Post Navigation