楼主: casey_c
972 1

[程序分享] 使用 Pandas 分析网站访问日志 [推广有奖]

  • 0关注
  • 10粉丝

博士生

92%

还不是VIP/贵宾

-

威望
0
论坛币
96 个
通用积分
2.0091
学术水平
2 点
热心指数
15 点
信用等级
2 点
经验
11502 点
帖子
278
精华
0
在线时间
94 小时
注册时间
2016-11-22
最后登录
2022-5-2

相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
通过一个例子向大家演示如何运用 Pandas 来进行 Apache 访问日志分析。本文内容其实也是原作者对 Pandas 库的一次尝试。
1、载入并解析数据

在解析网站日志时需要用到 apachelog 模块 ,因此我们首先需要了解一下 Apache 配置中的日志相关格式,这里并不打算在这方面详细展开,如果你对此感兴趣的话,可以详细查阅一下 官方提供的格式描述。在此,我们对 Apache 配置格式进行一个简单的说明,其中的所有元素可以被归纳为下述语句:

format = r'%V %h  %l %u %t \"%r\" %>s %b \"%i\" \"%{User-Agent}i\" %T'

其中,各个符号组合具体含义如下(详情可见这里):

V          - 由 UseCanonicalName 设置的服务器名称 %h          - 远程主机(即客户端IP)%l          - 由 identd 决定的用户身份(这并不常用因为不可靠)%u          - 通过 HTTP 认证决定的用户名%t          - 服务器完成处理请求的次数%r          - 客户端请求行("GET / HTTP/1.0")%>s         - 从服务器发送到客户端的状态代码 (200, 404 等)%b          - 对客户端的响应的大小(以字节为单位)\"%i\"      - 引用对应的URLUser-agent  - 浏览器的标识字符串 %T          - Apache 请求时间

  1. %matplotlib inline
  2. import sys
  3. import apachelog
复制代码


设置格式:



  1. fformat = r'%V %h %l %u %t\"%r\"%>s %b \"%i\" \
  2. "%{User-Agent}i\" %T'
复制代码


创建解析器:


  1. p = apachelog.parser(fformat)
复制代码


示例字符串:


koldunov.net 85.26.235.202 - - [16/Mar/2013:00:19:43 +0400] "GET /?p=364 HTTP/1.0" 200 65237 "http://koldunov.net/?p=364" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11" 0


  1. sample_string = 'koldunov.net 85.26.235.202\
  2. - -[16/Mar/2013:00:19:43 +0400] \
  3. "GET /?p=364 HTTP/1.0" \
  4. 200 65237 "http://koldunov.net/?p=364" \
  5. "Mozilla/5.0 (Windows NT 5.1) \
  6. AppleWebKit/537.11 (KHTML, like Gecko) \
  7. Chrome/23.0.1271.64 Safari/537.11" 0'
复制代码
  1. data = p.parse(sample_string)
复制代码
  1. data
复制代码

1.jpg


看来我们的解析器工作正常,那么接下来就让我们载入更多的真实数据吧(示例文件下载地址:地址1 地址2):


  1. log = open('access_log_for_pandas').readlines()
复制代码

对目标文件的每一行进行解析,并将它保存为一个由很多字典构成的列表:


  1. log_list = []
  2. for line in log:
  3.        try:
  4.           data = p.parse(line)
  5.        except:
  6.           sys.stderr.write("Unable to parse %s" % line)
  7.        data['%t'] = data['%t'][1:12]+' '+data['%t'][13:21]+' '+data['%t'][22:27]
  8.       
  9.        log_list.append(data)
复制代码

需要注意的是,在这个案例中我们需要对时间的格式进行稍微地调整,否则 Pandas 无法对其进行正确解析。


2、数据框构建与调整
经过上述步骤,我们得到了一个由字典构成的列表,接下来我们将它转化为数据框:


  1. import pandas as pd
  2. import numpy as np
  3. from pandas import Series, DataFrame, Panel
复制代码
  1. df = DataFrame(log_list)
复制代码


如下便是我们得到的数据框,看一下这个数据框的前两行:



  1. df[0:2]
复制代码
2.jpg


并不需要在分析中用到数据中的所有字段,所以接下来删除其中用不到的列:


  1. del df['%T']; del df['%V']; del df['%i']; del df['%l']; del df['%u']; del df['%{User-Agent}i']
复制代码

并且修改剩下列的列名,使其更加容易被人理解:


  1. df = df.rename(columns={'%>s': 'Status', '%b':'b',
  2.                         '%h':'IP', '%r':'Request', '%t': 'Time'})
复制代码

现在我们再来看一下这个数据框的前五行,已然清晰干净许多:


  1. df.head()
复制代码

3.jpg


接下来我们需要先将时间列 Time 转换为 datetime 格式并且为其加上序号(下面我们要调用的 pop 函数将删掉原始的 Time 列):


  1. df.index = pd.to_datetime(df.pop('Time'))
复制代码

变量 Status 应该为一个字符串型的数据,我们来对其进行转换:


  1. df['Status'] = df['Status'].astype('int')
复制代码

变量 b 这一列中有时候会出现字符串 '-' ,所以在处理这一列的时候我们不能用 astype


  1. df['b'][93]
复制代码
'-'

我们可以自己构建一个函数,来将所有的横杠都转换为 NaN,只留下浮点数,并将其单位由字节转换为兆字节:


  1. def dash2nan(x):
  2.     if x == '-':
  3.         x = np.nan
  4.     else:
  5.         x = float(x)/1048576.
  6.    
  7.     return x
复制代码
  1. df['b'] = df['b'].apply(dash2nan)
复制代码
肯定有人能够用一些更酷炫的方式来实现上文中的格式调整 :)
以上是数据载入和预处理的过程,原文较长,先搬运到这里,后续还有 流量分析、服务器状态分析等可视化过程,有时间继续分享,感兴趣的同学也可以直接去 数析学院 查看原文,在 pandas 基础进阶课程包










二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:网站

沙发
casey_c 发表于 2017-2-22 10:47:22 |只看作者 |坛友微信交流群

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-27 12:30