【路飞学城】第二模块作业一:

基本需求 90%
1 统计本日志文件的总pv、uv
2 列出全天每小时的pv、uv数
3 列出top 10 uv的IP地址,以及每个ip的pv点击数
4 列出top 10 访问量最多的页面及每个页面的访问量
5 列出访问来源的设备列表及每个设备的访问量
名词解释:
pv:page visit , 页面访问量,一次请求就是一次pv
uv: user visit, 独立用户,一个ip就算一个独立用户 分行是谈你你
注意:没有ip的可以认为是异常日志,不用统计!

运用的部分知识点讲解:

1:split()函数

语法:str.split(str="",num=string.count(str))[n]

参数说明:
str: 表示为分隔符,默认为空格,但是不能为空(’’)。若字符串中没有分隔符,则把整个字符串作为列表的一个元素
num:表示分割次数。如果存在参数num,则仅分隔成 num+1 个子字符串,并且每一个子字符串可以赋给新的变量
[n]: 表示选取第n个分片

注意:当使用空格作为分隔符时,对于中间为空的项会自动忽略

网站访问日志分析

开发环境

Python3.8.3

导入包

import re#正则
import arrow#时间处理
import datetime#时间处理
from prettytable import PrettyTable#生成表格美化输出

导入数据并读取

# 添加文件
log_file = '网站访问日志.txt'
def get_file():    
    with open(log_file, 'r', encoding='UTF-8') as f:                while True:        
           data = f.readline()            
           if data:                
               yield data            
           else:               
               break
# TODO:1:统计网站访问日志文件的总pv,uv
def log_total():
    print("网站访问日志分析的总pv(页面访问量),uv(独立用户)".center(50, "-"))
    tmp_dict = {
     'pv': [], 'uv': set()}# 集合自动去重,优化了代码
    print('waiting....')
    for i in get_file():
        res = re.findall('(\d+.\d+.\d+.\d+)\s-\s-\s',i)
        if not res: continue
        res = res[0]
        tmp_dict['pv'].append(res)
        tmp_dict['uv'].add(res)
    table = PrettyTable(['总PV数','总uv数'])
    table.add_row([len(tmp_dict['pv']),len(tmp_dict['uv'])])
    print(table)

1:首先读取数据

2:通过正则匹配数据

3:网页访问量的统计事项:将ip存储进列表里

4:用户总数统计事项:将ip存储在集合中,利用集合自动去重的功能实现存储

5:通过PrettyTable模块实现格式化输出

# TODO:2:列出全天每小时的pv,uv数
def log_hour():
    tmp_dict = {
     }
    print('waiting...')
    for i in get_file():
        res1 = re.search('(\[.*?\])', i)
        if not res1:continue
        res1 = res1.group().strip('[').strip(']')  # 15/Apr/2019:00:00:01 +0800
        tmp_str = datetime.datetime.strptime(res1.split(' ')[0], '%d/%b/%Y:%H:%M:%S')  # 2019-04-15 00:00:01
        tmp_day = arrow.get(tmp_str).strftime('%Y-%m-%d')  # 2019-04-15
        tmp_hour = arrow.get(tmp_str).strftime('%Y-%m-%d %H')  # 2019-04-15 00
        res2 = re.search('(\d+.\d+.\d+.\d+)\s-\s-\s', i)
        if not res2:continue
        if not tmp_dict.get(tmp_day):
            tmp_dict[tmp_day] = {
     }
        if tmp_hour not in tmp_dict.get(tmp_day):
            tmp_dict[tmp_day][tmp_hour] = {
     "pv": [], "uv": set()}
        tmp_dict[tmp_day][tmp_hour]['uv'].add(res2.group())
        tmp_dict[tmp_day][tmp_hour]['pv'].append(res2.group())
    for k in tmp_dict:
        print('[{}]日的每小时的pv和uv数统计如下: '.format(k))
        table = PrettyTable(["时间", '每个小时的pv数', '每个小时的uv数'])
        for j, v in tmp_dict[k].items():
            table.add_row([j, len(v['pv']), len(v['uv'])])
        print(table)

1:首先读取数据

2:通过正则匹配数据

3:将数据格式化存储到字典里#

“2019-4-14”:{# “2019-4-14 00”: {“pv”: [], “uv”: set()},

4:最后将数据统计出来

# TODO:3:列出top 10 uv(独立用户)的IP地址,以及每个ip的pv点击数
def top_ten_uv():
    tmp_dict = {
     
    }
    print("waiting.....")
    for i in get_file():  # 循环每一行
        res = re.search('(\d+.\d+.\d+.\d+)', i)
        if not res: continue
        res = res.group()
        if res in tmp_dict:
            tmp_dict[res]+=1
        else:
            tmp_dict[res] = 1
    table = PrettyTable(['top10 uv的IP','top10 uv的ip的pv'])
    tmp_list = sorted(tmp_dict.items(),key=lambda x: x[1],reverse=True)[0:10]
    for n1,n2 in tmp_list:
        table.add_row([n1,n2])
    print(table)

1:首先读取数据

2:通过正则匹配数据

3:通过group返回匹配到的结果

4:将ip地池存储到字典里并且判断字典里是否已经存在,如果已经存在了键值加一,不存在则添加

5:输出数据

# 4:TODO :列出top 10访问量最多的页面及每个页面的访问量
def top_ten_visit():
    tmp_dict = {
     }
    for i in get_file():
        res = re.search(
            '(?P((([01]{
      0,1}\d{
      0,1}\d|2[0-4]\d|25[0-5])\.){
      3}([01]{
      0,1}\d{
      0,1}\d|2[0-4]\d|25[0-5]))).*(?P /.*?HTTP/1.1)',
            i)
        if not res:continue
        ip, page = res.group("ip"), res.group("page").strip('HTTP/1.1')
        if page in tmp_dict:
            tmp_dict[page].append(ip)
        else:
            tmp_dict[page] = [ip]
    table = PrettyTable(['top10的页面', 'top10的页面访问量'])
    tmp_list = sorted(tmp_dict.items(), key=lambda x: len(x[1]), reverse=True)[0:10]
    for n1, n2 in tmp_list:
        table.add_row([ n1,len(n2)])
    print(table)

1:首先读取数据

2:通过正则匹配数据

3:匹配网页的同时需要匹配好ip如果没有ip则不计入数据

4:将ip与page分组,并将page后面的HTTP/1.1strip掉

5:判断page是否在字典里不在的话添加,并肩ip添加进去,在的话直接添加值ip,字典没有值去重功能

6:循环自动匹配键与值输出:取出字典里的键,并输出值的长度

# 5:TODO:列出访问来源的设备列表及每个设备的访问量
def device_list():
    print("waiting.....")
    tmp_dict = {
     }
    for i in get_file():
        res = re.search(
            '(?P((([01]{
      0,1}\d{
      0,1}\d|2[0-4]\d|25[0-5])\.){
      3}([01]{
      0,1}\d{
      0,1}\d|2[0-4]\d|25[0-5]))).*?(?P\(.*?\))',
            i)
        if not res:continue
        ip, device = res.group("ip"), res.group("equipment")
        if device in tmp_dict:
            tmp_dict[device].append(ip)
        else:
            tmp_dict[device] = [ip]
    table = PrettyTable(['设备来源','访问量'])
    tmp_list = sorted(tmp_dict.items(), key=lambda x: len(x[1]), reverse=True)
    for n1, n2 in tmp_list:
        table.add_row([ n1,len(n2)])
    print(table)

1:首先读取数据

2:通过正则匹配数据

3:匹配设备的同时需要匹配好ip如果没有ip则不计入数据

4:将设备与ip分组,分别加到字典里,设备是键,ip是值

5:输出:键:设备名,值:ip的长度

# TODO :退出系统
def q():
    """
    退出
    :return:
    """
    exit("欢迎再次使用!!!")

退出系统

#TODO:功能循环
def handler():
    tmp_dict = {
     
        "1": ["统计本日志文件的总pv、uv", log_total],
        "2": ["列出全天每小时的pv、uv数", log_hour],
        "3": ["列出top 10 uv的IP地址,以及每个ip的pv点击数", top_ten_uv],
        "4": ["列出top 10 访问量最多的页面及每个页面的访问量", top_ten_visit],
        "5": ["列出访问来源的设备列表及每个设备的访问量", device_list],
        "6": ["退出", q]
    }
    while True:
        print("欢迎使用网站访问数据分析系统".center(50,'-'))
        for k,v in tmp_dict.items():
            print(k,v[0])
        cmd = input('输入序号:').strip()
        if cmd.upper() == 'q'or cmd.upper()=='Q':
            break
        if cmd in tmp_dict:
            tmp_dict[cmd][-1]()
        else:
            print('输入不合法,请重新输入!!!!')

1:输入数字,对应功能能循环调用

2:判断输入数字是否在字典里,在字典内就直接调用函数,不在的话就重新输入

#TODO:函数调用
if __name__ == "__main__":
    handler()

你可能感兴趣的:(路飞学城,python)