[Python学习日记-59] 开发基础练习2——网站访问日志分析

news2024/11/24 9:51:57

[Python学习日记-59] 开发基础练习2——网站访问日志分析

简介

题目

答案

简介

        该练习结合了函数和一些常用的模块开发了一个对网站访问日志分析的程序,可以巩固实践之前学习的内容。

题目

基本需求:

  1. 统计本日志文件的总 pv、uv 数
  2. 列出全天每小时的 pv、uv 数
  3. 列出排名前十 uv 的 IP 地址,以及每个 IP 地址的 pv 点击数
  4. 列出排名前十访问量最多的页面及每个页面的访问量
  5. 列出访问来源的设备列表及每个设备的访问量
  6. 日志格式说明

网络日志文件:https://download.csdn.net/download/zjw529507929/89938292

名词解释:

  • pv(page visit):页面访问量,一次请求就是一次 pv
  • uv(user visit):独立用户,一个 IP 地址就算一个独立用户

注意:没有 IP 地址的可以认为是异常日志,不用统计! 

编码规范需求:

  1. 代码规范遵守pep8 (https://python.org/dev/peps/pep-0008/)
  2. 函数有相应的注释
  3. 程序有文档说明文件(README.md参考:https://github.com/csrftoken/surveySystem/blob/master/README.md)
  4. 程序设计的流程图

答案

程序运行流程图:

          在开发程序前最好还是先画一个程序的运行流程图,这样程序的开发逻辑会非常清晰,我们画这个图的时候可以上网注册一个 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():主函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2229802.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tiktok批量添加达人怎么弄

在 TikTok 上批量添加达人可以借助一些工具或方法,以下是一些常见的途径: 点我达秘免费体验地址注册 使用达人邀约工具: 功能特点:这类工具专为 TikTok 跨境小店和本土小店提供服务,可以实现多国家、多店铺同时私信和…

深度学习-激活函数详解

激活函数在神经网络中的作用是引入非线性特征,使得网络可以拟合和表达更复杂的数据关系。它通过对输入进行非线性变换,让每一层的输出既能反映输入特征,又能传递重要信息,以进行梯度更新。以下是关于常用激活函数的详细讲解。 1.…

基于vue框架的的乐守护儿童成长记录系统b65tg(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能:用户,成长指标,疫苗接种,学业档案,课外活动,旅游经历,交流论坛 开题报告内容 基于Vue框架的乐守护儿童成长记录系统开题报告 一、研究背景与意义 随着科技的飞速发展和家庭对子女成长关注度的不断提升,如何科学、系统地记…

使用wordcloud与jieba库制作词云图

目录 一、WordCloud库 例子: 结果: 二、Jieba库 两个基本方法 jieba.cut() jieba.cut_for_serch() 关键字提取: jieba.analyse包 extract_tags() 一、WordCloud库 词云图,以视觉效果提现关键词,可以过滤文本…

安卓13 连接usb设备后不更新ui

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码更改4.彩蛋1.前言 有些界面在链接usb设备后,ui会被刷新,导致闪烁问题。 2.问题分析 像这种问题一般是usb事件,导致的ui事件更新了,处理方法是禁止该事件 3.代码更改 这块我们就需要在输入事件管理里面…

根号下-1等于多少

根号下的负数在实数范围内是没有定义的,但在复数范围内,我们可以用虚数单位 来表示。具体来说: 因此,根号下的负一等于虚数单位 。

什么是人工智能(AI)?

人工智能AI(即Artificial Intelligence)是计算机科学的一个分支,旨在让计算机模仿人类的决策能力、像人类一样思考和行动,来解决如自然语言处理、推荐、智能数据检索、预测等方面人类无法处理或难以处理的复杂工作。 为什么需要人…

国标GB28181公网直播EasyGBS国标GB28181软件的应用场景

随着科技的飞速发展,安防视频监控技术已经成为现代社会不可或缺的一部分,它在保障公共安全、企业运营安全以及个人财产安全方面发挥着举足轻重的作用。国标GB28181网页直播平台EasyGBS安防视频监控平台,作为集高效性、稳定性与智能化于一体的…

[java][基础]JSP

目标: 理解 JSP 及 JSP 原理 能在 JSP中使用 EL表达式 和 JSTL标签 理解 MVC模式 和 三层架构 能完成品牌数据的增删改查功能 1,JSP 概述 JSP(全称:Java Server Pages):Java 服务端页面。是一种动态的…

Bacnet+springboot部署到linux后,无法检测到网络中的其他设备

场景描述 springbootbacnet4j项目完成后,在window环境可以正常检测到其他设备,但是部署到linux环境之后,无法获取。 解决办法 首先bacnet的子网掩码要设置为:255.255.255.0 确保linux服务器的防火墙允许 255.255.255.255 广播。…

HarmonyOS 5.0应用开发——音频播放组件的封装

【高心星出品】 文章目录 音频播放组件的封装开发步骤封装类代码测试代码 音频播放组件的封装 鸿蒙中提供了AVPlayer来实现音频播放的功能,播放的全流程包含:创建AVPlayer,设置播放资源,设置播放参数(音量/倍速/焦点模…

深度探索C++对象模型

文章目录 前言一、关于对象C对象模型 二、构造函数实例分析 拷贝构造函数程序转化语意学(Program Transformation Semantics)成员初始化列表 三、数据语义学(The Semantics of Data)数据存取多种继承情况讨论仅单一继承加上虚函数多重继承虚拟继承 Pointer to Data Members 四、…

TLV320AIC3104IRHBR 数据手册 一款低功耗立体声音频编解码器 立体声耳机放大器芯片麦克风

TLV320AIC3104 是一款低功耗立体声音频编解码器,具有立体声耳机放大器以及在单端或全差分配置下可编程的多个输入和输出。该器件包括基于寄存器的全面电源控制,可实现立体声 48kHz DAC 回放,在 3.3V 模拟电源电压下的功耗低至 14mW&#xff0…

【Rust中的序列化:Serde(一)】

Rust中的序列化:Serde Serde是什么?什么是序列化序列化?Serde运行机制Serde Data ModelVistor ApiSerializer ApiDeserializer Api 具体示例流程分析具体步骤:那么依次这个结论是如何得出的呢?什么是de? 总结 Serde是什么&#…

普通的Java程序员,需要深究源码吗?

作为Java开发者,面试肯定被问过多线程。对于它,大多数好兄弟面试前都是看看八股文背背面试题以为就OK了;殊不知现在的面试官都是针对一个点往深了问,你要是不懂其中原理,面试就挂了。可能你知道什么是进程什么是线程&a…

【vue项目中添加告警音频提示音】

一、前提: 由于浏览器限制不能自动触发音频文件播放,所以实现此类功能时,需要添加触发事件,举例如下: 1、页面添加打开告警声音开关按钮 2、首次进入页面时添加交互弹窗提示:是否允许播放音频 以上两种方…

2024 windos运行程序的时候弹窗:找不到ddl文件【已经解决,只要三步】修复ddl文件

一、错误复现 就是这个错误,网上一顿乱找,也解决不来,不是花钱就是付费就是充会员!! 二、ddl官网地址下载新的ddl文件(自己缺哪个,搜索哪个下载) 然灵机一动,ddl肯定有官…

Java并发常见面试题总结(上)

线程 ⭐️什么是线程和进程? 何为进程? 进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程 在 Java 中,当我们启动 main 函数时其实就是启动了一…

分类算法——逻辑回归 详解

逻辑回归(Logistic Regression)是一种广泛使用的分类算法,特别适用于二分类问题。尽管名字中有“回归”二字,逻辑回归实际上是一种分类方法。下面将从底层原理、数学模型、优化方法以及源代码层面详细解析逻辑回归。 1. 基本原理 …

AutoGLM:智谱AI的创新,让手机成为你的生活全能助手

目录 引言一、AutoGLM:开启AI的Phone Use时代二、技术核心:AI从“语言理解”到“执行操作”三、实际应用案例:AutoGLM的智能力量1. 智能生活管理🍎2. 社交网络的智能互动🍑3. 办公自动化🍒4. 电子商务的购物…