东尧爱分享
这是东尧每天一篇文章的第29天
东尧写文章的目标:分享东尧的经验和思考,帮你获取物质和精神两方面幸福。
在上一节教程
《【python与SEO】用python打造自己的网站日志分析工具(一)》
最后我们说到了可以对代码进行函数封装,方便对所有蜘蛛进行日志分析,那么对上一节的代码如何封装呢?下面我们一起来看看。
(关注公众号陈东尧回复关键词“日志分析工具”可下载工具源码直接使用)
因为针对每个搜索引擎蜘蛛,除了存储结果的名称不一样,整个处理的流程都是一样的,因此我们可以将这些流程封装成两个函数一个专门处理日志,一个用于统计结果和保存文件。
这样针对不同的蜘蛛,只需要传入需要处理的日志的行信息、存放的字典名以及保存结果的文件名即可。
整个函数封装分为3个部分:蜘蛛字典创建、日志处理和结果统计保存。最后达到的效果是直接输入蜘蛛名即可创建分析对应的日志部分:
1
蜘蛛字典创建函数封装:
def make_spider(spider_name):
save_file = open('%s.csv' % spider_name, 'w', encoding='utf-8') # w模式会将\n写入进去,结果文件中会自动多一行
csvwriter = csv.writer(save_file) # 将save_file写入到csvwriter中
spider_name = {}
spider_name['visits'] = 0
spider_name['visit_spiders'] = {}
spider_name['visit_pages'] = {}
spider_name['visit_dirs'] = {}
spider_name['visit_error'] = {}
return spider_name,csvwriter,save_file
2
日志处理函数封装
日志处理部分的代码太长仅截取部分代码,完整代码可在公众号“陈东尧”回复关键字“日志分析工具”获得):
# 日志处理函数。蜘蛛字典spider_dict,方便传入蜘蛛参数
def log_process(spider_dict):
spider_dict['visits'] += 1 # 百度蜘蛛访问次数+1
item = line.split() # split方法默认用空格来做切分
# 获取蜘蛛IP及其访问次数
spider = item[0] # 将蜘蛛IP提取出来
if spider_dict['visit_spiders'].get(spider):
spider_dict['visit_spiders'][spider] += 1 # 如果此IP在字典内,则对此蜘蛛访问次数值加1
else:
spider_dict['visit_spiders'][spider] = 1 # 如果IP不存在,则将此新IP创建到字典里
3
结果处理和保存函数封装:
以下仅截取完整代码的一部分
# 排序和保存文件函数
def count_and_save(spider_dict,writer):
# 对统计结果的字典进行排序
sort_spider = sorted(spider_dict['visit_spiders'].items(), key=lambda x: x[1], reverse=True)
sort_pages = sorted(spider_dict['visit_pages'].items(), key=lambda x: x[1], reverse=True)
sort_dirs = sorted(spider_dict['visit_dirs'].items(), key=lambda x: x[1], reverse=True)
sort_error = sorted(spider_dict['visit_error'].items(), key=lambda x: x[1], reverse=True)
# 将结果写入文件
fields = ('总访问量', '蜘蛛IP', 'IP访问次数', '受访目录','目录受访次数',
'受访页面', '页面访问次数', '404页面', '出错次数')
writer.writerow(fields) # 将fields的每个元素作为每一列
row_list = ['' for _ in range(9)] # 单独的下划线表示一个占位变量,不需要用到它
for page_item in sort_pages:
row_list[0] = spider_dict['visits'] if sort_pages.index(page_item) == 0 else '' # 如果下标为0则返回baidu['visits'],否则返回空
4
函数调用部分(正文):
可以对任意蜘蛛进行日志分析,传入蜘蛛参数即可。
# 百度蜘蛛
baidu,baiducsv,baidufile = make_spider('baidu')
# 搜狗蜘蛛
sogou,sogoucsv,sogoufile = make_spider('sogou')
with open('2017-02-17.log') as logfile: # 用with方法打开文件可以不用手动关闭文件
print('开始分析日志')
for line in logfile:
if 'Baiduspider' in line:
log_process(baidu)
elif 'Sogou web spider' in line:
log_process(sogou)
count_and_save(baidu,baiducsv)
count_and_save(sogou,sogoucsv)
当然,上面的封装还不是最好的,因为我们把排序以及保存结果都放在一个函数里面,这样的话程序的耦合度还是比较高。
假如哪天需求更改了,需要的是升序,而不是降序或者是不需要排序,或者是保存的结果放在json文件里面而不是csv文件又或者是写入到数据库里面,那么就需要修改整个函数。
所以可以把排序和保存结果分别单独的封装成两个独立的函数,这样后面的需求更改只需要更改对应的函数就可以了,而不需要把整个函数都修改。
领取专属 10元无门槛券
私享最新 技术干货