当前位置:首页 > 技术分享 > 正文内容

python 高速处理分析超大网站日志文件 带进度条手动输入日志文件

admin3年前 (2021-06-17)技术分享1252

 python 高速处理分析超大网站日志文件 带进度条手动输入日志文件

    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就算一个独立用户

#!/usr/bin/python
# -*- coding:utf-8 -*-
# date_time:2021/6/16
"""
    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就算一个独立用户
"""
import re
from tqdm import tqdm
import time

class log_analysis():
    def __init__(self):
        self.ip = {} #所有ip
        self.url = {} #所有url
        
        self.day_ip = {}  # 存全天每小时的ip
        self.day_source = {}  # 存全天每小时的source(访问量)
        self.click_pv = {}  # 存ip点击的页面
        self.equipment_data = {}  # 返回设备数据
    
    # 读取数据
    def read_data(self,path):
        """
        带进度条读取日志内容
        :param path:
        :return:
        """
        print("正在读取数据,请稍候~~~~")
        num_lines = sum(1 for line in open(path,'r', encoding='utf-8'))
        with open(path, 'r', encoding='utf-8') as f:
            #lines = "";
            for line in tqdm(f, total=num_lines):
                #lines = lines+line
                self.format_data(line)
        
    #格式化数据
    def format_data(self,data):
        ip = self.access_source(data)
        url = self.access_url(data)
        time_list = self.access_time(data)
        equipment = self.access_equipment(data)

        for ip_data in set(ip):
            self.ip[ip_data]=ip_data
            self.day_ip.setdefault(ip_data,0)
            self.day_ip[ip_data] +=1 # count返回这个值出现过几次
        
        for source_data in set(time_list):
            self.day_source.setdefault(source_data,0)
            self.day_source[source_data] += 1

        for top_source in set(url):
            self.url.setdefault(top_source,0)
            self.url[top_source] += 1
            self.click_pv.setdefault(top_source,0)
            self.click_pv[top_source] += 1
        
        for equipment_source in set(equipment):
            self.equipment_data.setdefault(equipment_source,0)
            self.equipment_data[equipment_source] += 1
        
        #self.equipment_data = dict(zip(equipment, url))
    
    # 提取访问源(IP)
    def access_source(self,data):
        """
        返回IP列表
        :param data:
        :return:
        """
        # re.findall 把所有匹配到的字符放到列表中,返回一个列表
        ip_data = re.findall(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b", data)
        return ip_data


    # 提取访问时间
    def access_time(self,data):
        """
        返回时间列表
        :param data:
        :return:
        """
        # 这个匹配全时间,但是只要求到小时,用第二个匹配,不然统计访问量会运算很久
        # time_data = re.findall("(?P<time>\\d{4}:\\d{2}.\\d{2}.\\d{2}.\\W.\\d{3})", data)

        # time_data = re.findall("(?P<time>\\d{4}:\\d{2})", data)
        time_data = re.findall("\d{2}/\D{3}/\d{4}:\d{2}:\d{2}", data)
        #print(time_data)
        # for time in time_data:
        #     time_list.append(time)
        # print(len(time_list))
        return time_data


    # 提取访问的url页面
    def access_url(self,data):
        """
        回返访问设备。
        :param data:
        :return:
        """

        url_data = re.findall("\\w+ /.*HTTP/\\d.\\d", data)
        # for url in url_data:
        #     # print(type(url))
        #     if 'GET' or 'POST' not in str(url):
        #         url_list.append(url)
        #         # print(url)
        #     else:
        #         continue
        # print(url_list)
        return url_data


    # 提取访问的设备
    def access_equipment(self,data):
        """
        返回设备数据
        :param data:
        :return:
        """

        equipment_data = re.findall("Mozilla/.*", data)
        # for equipment in equipment_data:
        #     equipment_list.append(equipment)
        # print(equipment_list)
        return equipment_data
    # 数据处理函数
    def data_processing(self):
        """
        处理总pv、uv
        处理全天每小时的pv、uv数
        处理top 10 uv的IP地址,以及每个ip的pv点击数
        处理top 10 访问量最多的页面及每个页面的访问量
        处理访问来源的设备列表及每个设备的访问量
        :return:
        """
        msg = """
        1-->查看总pv、uv,
        2-->查看全天每小时的pv、uv数,
        3-->查看top 10 uv的IP地址,以及每个ip的pv点击数,
        4-->查看top 10 访问量最多的页面及每个页面的访问量,
        5-->查看访问来源、设备的访问量,
        6-->重新选择文件,
        7-->输入 "q" 退出程序"""

        ip = self.ip #所有ip
        url = self.url #所有url
        
        day_ip = self.day_ip  # 存全天每小时的ip
        day_source = self.day_source  # 存全天每小时的source(访问量)
        click_pv = self.click_pv  # 存ip点击的页面
        equipment_data = self.equipment_data  # 返回设备数据
        print("数据处理完成!!!")

        while True:
            print(msg)
            user_input = input("请输入你先查询的信息编号:")
            if not user_input:
                print("请输入内容~~")
                continue

            cmd = int(user_input) if user_input.isdigit() else user_input

            if cmd == 1:
                # 1.统计本日志文件的总pv、uv
                url_num = 0
                for ip_data in set(url):
                    url_num +=url[ip_data]
                
                print("总的页面访问量:%s 次" % url_num)
                print("总的IP数量:%s 个" % (len(set(ip))))  # set去重
            elif cmd == 2:
                # 2.列出全天每小时的pv、uv数
                # ip数量提取
                print("2.全天每小时的pv、uv数")                
                for hours_ip,hours_num in sorted(day_ip.items(), key=lambda item:item[1], reverse=True)[0:10]:
                    print("每小时的ip数量:%s ip:%s" % (hours_num, hours_ip))
                # 访问量提取
                # print(day_source)
                for hours_source,hours_num in sorted(day_source.items(), key=lambda item:item[1], reverse=True)[0:10]:
                    print("每个小时的访问量:%s次 时间: %s" % (hours_num, hours_source))

            elif cmd == 3:
                # 3.列出top 10 uv的IP地址,以及每个ip的pv点击数
                print("3.top 10 的ip地址")
                for top_ip,ip_num in sorted(day_ip.items(), key=lambda item:item[1], reverse=True)[0:10]:
                    print("top 10的pv点击数:%s次,ip地址 %s" % (ip_num, top_ip))

                print("每个ip的页面点击数")
                for click_data,click_num in sorted(click_pv.items(), key=lambda item:item[1], reverse=True)[0:10]:
                    print("top 10的页面访问量:%s次 --> %s" % (click_num, click_data))

            elif cmd == 4:
                # 4.列出top 10 访问量最多的页面及每个页面的访问量
                print("4.访问量最多的页面+访问量")
                for click_data,click_num in sorted(click_pv.items(), key=lambda item:item[1], reverse=True)[0:10]:
                    print("top 10的访问量最多的页面:%s 页面访问量:%s" % (click_num, click_data))

            elif cmd == 5:
                # 5.列出访问来源的设备列表及每个设备的访问量
                print("5.设备来源和设备访问量---")

                count = 0
                for equipment_source,equipment_num in sorted(equipment_data.items(), key=lambda item:item[1], reverse=True)[0:10]:
                    print("设备访问量:%s  设备名称:%s  " % (equipment_num, equipment_source))
                    if count == 10:break
                    count += 1
            elif cmd == 6:
                inputfile()
            elif cmd == 'q':quit()
            else:
                print("请重新输入~~")


def inputfile():
    file_input = input("请输入您要处理的日志文件:")
    while True:
        if not file_input:
            print("请输入内容~~")
            continue
        print(file_input)
        obj1 = log_analysis()
        obj1.read_data(file_input)
        obj1.data_processing()
# 主函数
def main():
    """
    程序入口
    :return:
    """
    inputfile()
    #data_processing(head_data)


main()


扫描二维码推送至手机访问。

版权声明:本文由小刚刚技术博客发布,如需转载请注明出处。

本文链接:http://blog.bitefu.net/post/177.html

分享给朋友:

相关文章

thinkphp等框架开发中容易忽略的xss攻击及应对XSS攻击方法

thinkphp等框架开发中容易忽略的xss攻击及应对XSS攻击方法

虽然说现在的web开发框架都是挺成熟的框架,在性能、安全等方面都有比较好的表现,但问题往往出现在业务逻辑上,如上周我再公司发现的一个跨站脚本攻击,(通常公司是这么过滤的,max(0,$_GET[‘a’])、strip_tags($_GET[...

WPS表格办公—取消科学计数法显示

WPS表格办公—取消科学计数法显示

我们在利用WPS表格与Excel表格进行日常办公时,经常需要制作各种各样的表格,当我们在表格当中输入长数据的时候,表格经常会自动显示为科学计数法,很多人都看不懂科学计数法的意思,那么,我们如何在输入长数字的时候避免显示为科学计数法呢,今天我...

php高效检测远程图片是否存在

php高效检测远程图片是否存在function img_exits($url){     $ch = curl_init();    &...

[教程] WTG备份新方法——FFU镜像格式

[教程] WTG备份新方法——FFU镜像格式

FFU(Full Flash Update) 格式是一种基于扇区的磁盘镜像文件格式,默认使用快速哈夫曼压缩(Xpress-Huffman)算法压缩,在捕获和部署时会生成哈希表进行校验,并可以使用DISM修改捕获的镜像。FFU格式很适合WTG...

centos 配置Let's Encrypt 泛域名https证书

centos 配置Let's Encrypt 泛域名https证书

前言2018年1月份Letsencrypt可以申请泛域名证书,这让我们部署多域名、多站点https省了很多功夫,终于可以不用维护多个域名的https证书。笔者以acme.sh为例,手把手教你配置https证书~本教程适用于centos 6....

安装Windows 10X 教你如何安装Win10X正式版 及下载地址

安装Windows 10X 教你如何安装Win10X正式版 及下载地址

安装Windows 10X 教你如何安装Win10X正式版:Windows 10X是Windows 10操作系统的新版本,主要针对双屏电脑。由于即将运行Windows 10X的双屏电脑(例如即将面世的Surface Neo)的开发遇到挫折,...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。