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

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

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

 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

分享给朋友:

相关文章

php Aes 加密模式ECB填充pkcs5padding base64

最近做支付项目用到了aes加密不过试了好多办法总是和官方给出的结果不一样,找了很久终于找到了测试结果同 http://tool.chacuo.net/cryptaes/ <?php /**  * [Aes&nb...

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

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

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

七牛html js上传带进度条源码

七牛html js上传带进度条源码注册链接https://s.qiniu.com/uM7RJv完整代码下载:https://n802.com/f/349707-489018989-c141f6(访问密码:5036)http://www.yi...

在CentOS 5.x 6.x里使用yum源 换阿里云国内源换vault.centos.org源

阿里云CentOS 5 的系统,无法用yum来安装应用软件。  原因:CentOS 5 在2017-03-31日已经结束支持,不再提供维护更新,所以包括阿里云镜像站的文件可能都是过时或已经有部分文件缺失。 &n...

安卓模拟器连接端口 及常用命令

下面是我总结和测试通过的:有的是搜集来的模拟器名称                     &nbs...

apicloud影视APP源码 无需后台

apicloud影视APP源码 无需后台

介绍集合vip影视接口到一个android app中 方便观看各平台影视资源及直播开源地址:https://gitee.com/web/vip_yingshi软件架构使用apicloud搭建影视APP源码,无后台,调用接口同步api解析网址...

发表评论

访客

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