作者:admin,发布日期:2020-10-04
阅读:2583;评论:0
应该是今年的第N次更新,由于前段时间比较忙,没有怎么管理博客,最近国庆才有空更新。
写在开头
这篇文章中,我们将使用python的requests包以及内置的reduce等函数,对爱快路由中的网址浏览记录进行批量抓取并做简单分析,主要是为了练手和复习python内置的map和reduce函数。
爱快里面的操作
要获取到网址浏览记录,我们首先需要在爱快中打开此设置,然后爱快才会记录网址浏览记录。
数据的获取
博主首先尝试了爱快自带的导出功能,但是发现自带的导出功能有很大的缺陷,点击批量下载不是直接导出一个文件,而是一个文件一个文件单独下载下来,而且这个记录是按照小时生成的,一个小时会生成一次,这就导致最终导出的文件数量非常多。
经过分析,爱快导出网址浏览记录时,会访问下载链接进行下载,这个下载链接需要鉴权,类似于下面的网址:
http://0.0.0.0/audit_url/20200915T010000
最后的20200915T010000实际为导出文件页面显示的文件名称,而这个文件名称是可以生成的,他的规则看一眼就可得知:
年份+月份+日期+T+时间+0000
而且除了年份为4位外,其他均为2位,不足2位前面补0,所以我们就可以得到文件名的格式
name_format = "2020%02d%02dT%02d0000" # %02d表示2位整数,不足2位左边补0
而在前面提到,这个网址需要鉴权,由于我们不需要整个过程自动化,所以我们直接从谷歌浏览器中登录获取爱快后台的session key,这里只需要用到sess_key这个cookies,剩下据我猜测应该是用于后台js显示:
知道这些后,我们就可以使用requests模块批量进行下载数据了,在这里使用了requests.session(),让requests去管理此次会话
import requests def main(): session = requests.session() session.cookies["sess_key"] = "" # 前面得到的sess_key name_format = "2020%02d%02dT%02d0000" for i in range(1, 31): # 生成月份1-30 for j in range(24): # 生成小时0-23 name = name_format % (10, i, j) data = session.get("http://0.0.0.0/audit_url/%s" % name) # 下载记录 if data.status_code == 200: # 如果文件存在就写入到本地 with open("./log/%s" % name, "wb") as f: f.write(data.content) print("[+] Download %s" % name) # 输出记录 if __name__ == '__main__': main()
运行代码,我们就可以得到所有的日志了:
批量读取日志文件
首先使用os.getcwd()获取当前目录,然后使用os.listdir()来列出目录下所有文件和目录。
这里没有做目录的筛选,因为我们的log目录下面只有日志文件,不存在目录,所以不需要做处理。
接着我们将文件按行读取,然后对其进行分割。
file_list = os.listdir(os.getcwd() + "/log") print(file_list) log_list = [] for file in file_list: with open("./log/%s" % file, "r") as f: for log in f.readlines(): log_list.append(log.split())
分割后的数据类似于此结构:
[['192.168.1.24', '00:00:00:00:00:00', '1601796769', '2020-10-04', '15:32:49', '5040005', '/', 'vexrmb.i8mc.cn'], ['192.168.1.22', '00:00:00:00:00:00', '1601796771', '2020-10-04', '15:32:51', '2990002', '/cgi-bin/httpconn', '0.0.0.0']]
数据分析
首先我们要知道reduce的函数的用法,这里可以参考廖雪峰的网站上的python教程:
https://www.liaoxuefeng.com/wiki/1016959663602400/1017329367486080
然后就是对数据做分析了,我们使用reduce进行了一次最简单的分析,统计每个网站被访问的次数,然后对其进行排序,访问次数最多的在最前面,并且数据结果:
import os from functools import reduce def main(): file_list = os.listdir(os.getcwd() + "/log") # print(file_list) log_list = [] for file in file_list: with open("./log/%s" % file, "r") as f: for log in f.readlines(): log_list.append(log.split()) # print(log_list) result = reduce(views_count, log_list, {}) # 按照value对结果字典进行排序 result = sorted(result.items(), key=lambda x: x[1], reverse=True) # 输出结果 for k, v in result: print(k, v) # reduce处理过程,b[7]为访问的网址,从上方结构可得 def views_count(a, b): """ :type b: str :type a: dict """ if b[7] in a.keys(): a[b[7]] += 1 else: a[b[7]] = 1 return a if __name__ == '__main__': main()
输出结果类似于下方结果:
vexrmb.i8mc.cn 143867 api.curseforge.com 72558 servermods.forgesvc.net 63151 files.forgecdn.net 58431 media.forgecdn.net 45738 www.mczhifu.com 43427 mcstats.org 28355 101.91.5.187 16397 bStats.org 12798 api.yumc.pw 10627 .....
写在结尾
python的内置reduce,map,filter等函数可以对数据进行简单的处理,当然,对于大量数据,我们可以将其导入hadoop进行流式计算,以获得实时的数据。博主在此篇文章中仅进行的基础分析,对于此类型的数据,还可以对其访问时间段的等数据进行聚合等操作。