[Python学习日记-59] 开发基础练习2——网站访问日志分析
简介
题目
答案
简介
该练习结合了函数和一些常用的模块开发了一个对网站访问日志分析的程序,可以巩固实践之前学习的内容。
题目
基本需求:
- 统计本日志文件的总 pv、uv 数
- 列出全天每小时的 pv、uv 数
- 列出排名前十 uv 的 IP 地址,以及每个 IP 地址的 pv 点击数
- 列出排名前十访问量最多的页面及每个页面的访问量
- 列出访问来源的设备列表及每个设备的访问量
- 日志格式说明
网络日志文件:https://download.csdn.net/download/zjw529507929/89938292
名词解释:
- pv(page visit):页面访问量,一次请求就是一次 pv
- uv(user visit):独立用户,一个 IP 地址就算一个独立用户
注意:没有 IP 地址的可以认为是异常日志,不用统计!
编码规范需求:
- 代码规范遵守pep8 (https://python.org/dev/peps/pep-0008/)
- 函数有相应的注释
- 程序有文档说明文件(README.md参考:https://github.com/csrftoken/surveySystem/blob/master/README.md)
- 程序设计的流程图
答案
程序运行流程图:
在开发程序前最好还是先画一个程序的运行流程图,这样程序的开发逻辑会非常清晰,我们画这个图的时候可以上网注册一个 processon(ProcessOn思维导图流程图-在线画思维导图流程图_在线作图实时协作)或者下载一个 Visio 来画流程图。
目录结构:
website_log/
| -- __init__.py # 代表 Employer_info 是一个包,无代码
| -- code.py
| -- README.md
| -- 网站访问日志.txt
code.py:
# -*- coding: utf-8 -*-
import re
LOG_FILE = '网站访问日志.txt'
COLUMNS = ['ip', 'time', 'url', 'device']
LOGS = {}
def make_msg(msg):
return '\033[31m%s\033[0m' % msg
def init_var():
for i in COLUMNS:
LOGS[i] = []
def add_file(line):
# ip: 122.71.241.175
obj = re.search(r'\d{1,3}(\.\d{1,3}){3}', line)
if not obj:
return False
ip = obj.group()
# time: 15/Apr/2019:00
obj = re.search(r'\d{1,2}\/[a-zA-Z]+\/\d{4}:\d{2}', line)
if not obj:
return False
time = obj.group()
# url: /api/v1/affiches/
obj = re.search(r'[GET|POST]\s\/(\w+\/)*', line)
if not obj:
return False
url = re.search(r'\/(\w+\/)*', obj.group()).group()
# device
obj = re.search(r'"Mozilla(\/\d\.\d)*(\s\()*([\s|\w|\;|\.|\-])*', line)
if not obj:
return False
device = obj.group().strip('"')
LOGS['ip'].append(ip)
LOGS['time'].append(time)
LOGS['url'].append(url)
LOGS['device'].append(device)
return True
def load_file(log_file):
"""
加载文件
:param log_file:
:return:
"""
init_var()
f = open(log_file, 'r')
for line in f:
add_file(line)
f.close()
def pv_count(ex_msg, index, num=0):
if not (index in COLUMNS):
print(ex_msg + ':', make_msg(len(LOGS['ip'])))
return len(LOGS['ip'])
columns = list(set(LOGS[index]))
columns.sort()
d_cnt = {}
for column in columns:
d_cnt[column] = 0
for index, column in enumerate(LOGS[index]):
d_cnt[column] += 1
nums = []
if num > 0:
for i in d_cnt:
nums.append(d_cnt[i])
nums = list(set(nums))
nums.reverse()
nums = nums[0:num]
s = 0
print(ex_msg)
for column in columns:
if len(nums) != 0:
if d_cnt[column] in nums:
print('(' + column + '):', make_msg(d_cnt[column]))
s += d_cnt[column]
else:
print('(' + column + '):', make_msg(d_cnt[column]))
s += d_cnt[column]
return s
def uv_count(ex_msg, index):
if not (index in COLUMNS):
columns = list(set(LOGS['ip']))
print(ex_msg + ':', make_msg(len(columns)))
return len(columns)
columns = list(set(LOGS[index]))
columns.sort()
d_cnt = {}
for column in columns:
d_cnt[column] = []
for index, column in enumerate(LOGS[index]):
d_cnt[column].append(LOGS['ip'][index])
s = 0
print(ex_msg)
for column in columns:
cnt = len(list(set(d_cnt[column])))
print('(' + column + '):', make_msg(cnt))
s += cnt
return s
def main():
load_file(LOG_FILE)
# pv: page visit, 页面访问量,一次请求就是一次pv
# uv: user visit, 独立用户,一个ip就算一个独立用户
# 1. 统计本日志文件的总pv、uv数
pv_count('统计本日志文件的总pv', '')
uv_count('统计本日志文件的总uv', '')
# 2. 列出全天每小时的pv、uv数
print('累计pv数:', make_msg(pv_count('列出全天每小时的pv数', 'time')))
print('累计uv数:', make_msg(uv_count('列出全天每小时的uv数', 'time')))
# 3. 列出top 10 uv的IP地址,以及每个ip的pv点击数
print('累计pv数:', make_msg(pv_count('列出top 10 uv的IP地址,以及每个ip的pv点击数', 'ip', 10)))
# 4. 列出top 10 访问量最多的页面及每个页面的访问量
print('累计pv数:', make_msg(pv_count('列出top 10 访问量最多的页面及每个页面的访问量', 'url', 10)))
# 5. 列出访问来源的设备列表及每个设备的访问量
print('累计pv数:', make_msg(pv_count('列出访问来源的设备列表及每个设备的访问量', 'device')))
main()
README.md:
开发环境
Python (3.12.4)实现功能
该程序实现了对网络日志信息的分析,分别有:
1、统计本日志文件的总 pv、uv 数
2、列出全天每小时的 pv、uv 数
3、列出排名前十 uv 的 IP 地址,以及每个 IP 地址的 pv 点击数
4、列出排名前十访问量最多的页面及每个页面的访问量
5、列出访问来源的设备列表及每个设备的访问量
函数说明:
make_msg(msg):构造显示信息
init_var():初始化日志信息
load_file(load_file):加载日志文件
pv_count(ex_msg, index, num=0):pv数据处理函数
uv_count(ex_msg, index):uv数据处理函数
main():主函数