东尧爱分享
这是东尧每天一篇文章的第28天
东尧写文章的目标:分享东尧的经验和思考,帮你获取物质和精神两方面幸福。
日志分析在SEO中有着非常重要的作用,通过日志分析我们可以看到蜘蛛的各种抓取状态,分析热门页面,提取错误页面等等。
今天要教大家的就是使用python来打造一个简单的日志分析工具,对我们的网站日志进行归类分析。
1
工具效果
对日志内容进行分类并统计分析。
2
需求分析
统计每个搜索引擎蜘蛛的来访次数
统计每个搜索引擎都访问了哪些页面
统计访问最多的页面和目录
统计抓取成功和失败的页面及次数
统计蜘蛛IP及其访问次数
3
程序设计
存储设计
将结果保存到CSV文件中,每个搜索引擎分成独立的文件(以下案例使用Baiduspider进行示范)
程序计算临时存储设计
(使用字典来存放,因为字典有键值对方便对应和查找)
统计每个搜索引擎蜘蛛的来访次数(visits)
统计每个搜索蜘蛛IP及其来访次数(visit_spiders)
统计每个搜索引擎都访问了哪些页面及次数(visit_pages)
统计访问了哪些目录及次数(visit_path)
统计抓取失败的页面和次数(visit_error)
baidu = {} # 创建针对百度蜘蛛的字典
baidu['visits'] = 0 # 统计总访问次数
baidu['visit_spiders'] = {} # 统计蜘蛛IP及次数,键是字符串,值是字典,可放置蜘蛛IP和来访次数
baidu['visit_pages'] = {} # 统计访问页面
baidu['visit_dirs'] = {} # 统计访问目录及次数
baidu['visit_error'] = {} # 统计状态码及次数
日志读取分析
如果要实现以上数据维度的分析,那么日志文件里面必须包含访问者的ip、状态码、访问了哪些页面、以及访问者的UA(user-agent用户代理),否则就无法分析出来。
识别搜索引擎和正常用户主要就是通过UA来判断的。
网站日志基本都是每行一条记录的,每个字段信息之间是用空格分开的,因此只需要遍历日志文件的每一行,然后用空格来拆分每个字段,提取需要的字段信息即可。下面是一条日志的样子:
220.181.125.138 - - [17/Feb/2017:00:00:13 +0800] "[www.brooks.com] GET /xiaoxuejiaoyu/ernianji/ernianjixiaceshuxueko/48265.html HTTP/1.1" 200 6667 "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)" "-""request_time 0.122""upstream_response_time 0.122"
此条日志信息详细的记录了访问者的ip、访问时间、时区、访问的域名、请求 方式、访问页面、http版本、请求状态码、服务器返回字节数、用户代理、请求时间、响应时间等字段信息。
代码实现
使用for循环来遍历文件
使用成员操作符(in)来判断搜索引擎蜘蛛是否存在日志记录中,如果存在则将对应蜘蛛的访问次数加1
with open('2017-02-17.log') as logfile: # 用with方法打开文件可以不用手动关闭文件
print('开始分析日志')
for line in logfile:
if 'Baiduspider' in line:
baidu['visits'] += 1 # 百度蜘蛛访问次数+1
然后使用字符串的split方法来切割字符串,将字符串转成列表。通过列表的下标获取需要的字段
item = line.split() # split方法默认用空格来做切分
提取蜘蛛IP,然后作为字段的键名,通过字典的get方法来判断字典中是否已经存在相同的ip,如果不存在则新建一个键名,然后值设置为1,如果存在则将对应的值加1
# 获取蜘蛛IP及其访问次数
spider = item[0] # 将蜘蛛IP提取出来
if baidu['visit_spiders'].get(spider):
baidu['visit_spiders'][spider] += 1 # 如果此IP在字典内,则对此蜘蛛访问次数值加1
else:
baidu['visit_spiders'][spider] = 1 # 如果IP不存在,则将此新IP创建到字典里
提取URL:跟蜘蛛ip一样的操作
提取404状态码(错误页面)信息,通过判断 item[9]是否为‘404’就可以进行操作。
提取访问目录:目录的提取是将URL使用字符串的split方法以斜杠进行拆分,先判断URL是否包含两个及以上的斜杠,如果是就拆分,如果是首页就不拆分。然后只提取第一个目录再使用join方法重新拼接成字符串,然后跟URL一样的操作。
# 获取蜘蛛访问目录及其次数
if url == '/': # 判断url是否为根目录
dirname = '/'
elif url.count('/') >=2: # 判断url是否有二级目录
# 只获取一级目录
dirname = '/%s/' % url.split('/')[1]
else:
dirname = '' # 空字符串为False
if dirname and baidu['visit_dirs'].get(dirname): # 同时满足目录存在和字典中有此目录
baidu['visit_dirs'][dirname] += 1
elif dirname:
baidu['visit_dirs'][dirname] = 1
对上面的蜘蛛ip、访问页面、访问目录、错误页面的结果进行从大到小的倒序排序(都是字典):
# 对统计结果的字典进行排序
# sorted方法返回的是排序后的列表
# 每个列表的元素是由双元素元组组成的(主要是因为iteritems方法得到的就是双元素元组)
# 元组的第一个元素是字典的key(键),第二个元素是字典的value(值)
sort_spider = sorted(baidu['visit_spiders'].items(),key = lambda x: x[1],reverse=True)
sort_pages = sorted(baidu['visit_pages'].items(), key = lambda x: x[1], reverse=True)
sort_dirs = sorted(baidu['visit_dirs'].items(), key = lambda x: x[1], reverse=True)
sort_error = sorted(baidu['visit_error'].items(), key = lambda x: x[1], reverse=True)
判断哪个字段得到的数量是最多的(因为写入文件的时候要以最多的为准,只有知道哪个是最多的,才知道要写入多少行数据,用于for循环写入),但是蜘蛛ip的数量肯定不会有页面数量多,目录的数量也不会有页面的数量多,错误页面的数量也不会有页面的数量多(页面包括了错误页面),所有只需要得到页面的数量就好了。
要将结果写入csv文件,需要在开头引入csv模块。csv模块的使用方法在下面注释, 要解决Excel打开utf-8编码的csv文件中文乱码问题,需要在open文件时写入encoding='utf-8'就好了:
# -*- coding: utf-8 -*-
import csv
save_file = open('baiduspider.csv','w',encoding='utf-8') # w模式会将\n写入进去,结果文件中会自动多一行
fields = ('总访问量','蜘蛛IP','IP访问次数','受访目录','目录受访次数','受访页面','页面访问次数','404页面','出错次数')
csvwriter = csv.writer(save_file) # 将save_file写入到csvwriter中
csvwriter.writerow(fields) # 将fields的每个元素作为每一列
因为遍历的页面数量的列表,因此别的列表的信息可以使用pop方法来获取,当列表为空的时候就证明获取完了,然后就将值设置为空字符串,这样的话只有列表有数据的时候才会把数据写入到文件,没有数据的时候写入的就是空字符串(其实就是啥都没有)。
同时由于蜘蛛的访问总数只在第一行,也就是下标为0的时候,其余时候写入空字符串,上面两种情况都需要做判断。又因为页面的数量是最多的,所以直接遍历页面的排序结果列表就OK了。
# 将结果写入文件
row_list = ['' for _ in range(9)] # 单独的下划线表示一个占位变量,不需要用到它
for page_item in sort_pages:
row_list[0] = baidu['visits'] if sort_pages.index(page_item) == 0 else '' # 如果下标为0则返回baidu['visits'],否则返回空
除了百度蜘蛛以外,还有360蜘蛛、搜狗蜘蛛、谷歌蜘蛛等等,那这么多蜘蛛我们不可能把上述程序又重新全部敲一遍,这样代码会非常冗长。
因为针对每个搜索引擎蜘蛛,除了存储结果的名称不一样,整个处理的流程都是一样的,因此我们可以将这些流程封装成两个函数一个专门处理日志,一个用于统计结果和保存文件,这样针对不同的蜘蛛,只需要传入需要处理的日志的行信息、存放的字典名以及保存结果的文件名即可。
具体的封装函数下一节的教程中我会再为大家详细介绍,欢迎继续关注。
领取专属 10元无门槛券
私享最新 技术干货