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

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

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

 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()


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

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

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

分享给朋友:

相关文章

节假日api 负载均衡升级 增加阿里云服务器

以下是服务器的情况可根据自己的需求进行选择1.tool.bitefu.net 整合服务器到 新的阿里云服务器(配置更高),旧服务器已不再续费2.vip.bitefu.net增加一个阿里云虚拟主机 现在已经有三条dns负载均衡的解析...

VirtualXposed 不支持32位应用 32位无法安装问题解决办法

VirtualXposed 不支持32位应用 32位无法安装问题解决办法

VirtualXposed 是基于VirtualApp 和 epic 在非ROOT环境下运行Xposed模块的实现(支持5.0~10.0)。与 Xposed 相比,目前 VirtualXposed 有...

PIP 更换国内安装源linux/windows

pip国内的一些镜像  阿里云 http://mirrors.aliyun.com/pypi/simple/   中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/   豆瓣(...

遭遇国外ip抓取或攻击怎么办一招解决禁止海外IP访问

遭遇国外ip抓取或攻击怎么办一招解决禁止海外IP访问

究发现很多网站被攻击都是来自海外的肉鸡,所以禁掉海外IP访问网站也是不错的防护手段,而且国内网站几乎很少有国外用户访问,称之为大局域网也不为过。今天主机吧来教大家如何利用域名解析禁止掉海外IP访问网站。绝大多数域名解析服务商都是提供电信联通...

用CMD命令查询域名的DNS解析记录:A,NS,MX,CNAME,TXT

1、查询域名的A记录nslookup -qt=A bitefu.net当然查询A记录你直接用ping命令来ping域名也可以获得A记录。2、查询域名的NS记录nslookup -qt=NS bitefu.net3、查询域名的MX记录nslo...

python调用WinRAR暴力获取压缩密码 用网址做解压密码

原理很简单:python通过调用WinRAR.exe暴力获取压缩密码,要求必须安装WinRAR或者有WinRAR.exe这个文件(单个文件就行)。个人实测zip和rar格式都能用。缺点:费时间,费cpu一、不生成密码本:4位全数字密码:im...

发表评论

访客

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