Python 入门实操:写一个日志统计小工具,练熟文件读写与计数排序
学 Python 最怕只背语法不动手。这篇文章用一个真实的小需求练手:统计一份 Web 访问日志中每个 IP 的访问次数,并找出访问量最高的前 5 个 IP。麻雀虽小,五脏俱全——文件读写、字符串处理、字典计数、排序输出,这四样最常用的基础能力可以一次练完,而且全程只用标准库,不用安装任何第三方包。
一、先看清日志长什么样
常见的 Nginx 访问日志,每一行都以客户端 IP 开头,后面跟着请求时间、请求方法和状态码,大致如下:
192.168.1.10 - - [24/Oct/2026:08:01:12 +0800] "GET /index.html HTTP/1.1" 200 1024
192.168.1.11 - - [24/Oct/2026:08:01:15 +0800] "GET /api/users HTTP/1.1" 200 512
192.168.1.10 - - [24/Oct/2026:08:01:20 +0800] "POST /login HTTP/1.1" 302 128
目标很明确:IP 就在每行的第一个字段,只要按空格切分取第一段即可,不需要一上来就学正则表达式。
二、逐行读取,不要一次性全读进来
新手常犯的错误是用 read() 或 readlines() 把整个文件读进内存。日志动辄几百 MB,这样很容易把内存吃满。更稳妥的做法是把文件对象当作迭代器逐行处理,读一行、处理一行:
with open("access.log", "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line:
continue
ip = line.split()[0]
print(ip)
这里有三个细节值得注意:第一,用 with 打开文件,代码块结束会自动关闭,不怕中途异常时忘记关;第二,先 strip() 去掉行尾换行并跳过空行,否则空行切分后取下标 0 会直接报 IndexError;第三,明确写出 encoding=“utf-8”,避免在不同系统上因默认编码不同而乱码。
三、计数交给 Counter,少写样板代码
统计次数最朴素的写法是自己维护一个字典,每次用 get 取旧值再加一。这段代码当然没问题,但标准库 collections 里的 Counter 就是为计数场景准备的:给它一个元素,它自动累加;最后调用 most_common(n) 就能直接拿到出现次数最多的前 n 个结果。把前两步拼起来,就是完整工具。
四、完整代码与运行效果
from collections import Counter
def top_ips(log_path, n=5):
counter = Counter()
with open(log_path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line:
continue
ip = line.split()[0]
counter[ip] += 1
return counter.most_common(n)
if __name__ == "__main__":
for ip, cnt in top_ips("access.log"):
print(f"{ip}: {cnt}")
用上面的三行样本日志运行,输出如下:
192.168.1.10: 2
192.168.1.11: 1
结果和人工数的一致。如果想把结果留档,再顺手练一次文件写入:以 “w” 模式打开 result.txt 把每行写进去即可,注意手动补上换行符。
五、跑通之后,可以这样扩展
建议按顺序给自己加需求:统计每个状态码出现的次数(状态码在每行倒数第二个字段);先按双引号切出请求部分,再统计访问最多的 URL 路径;把 Top N 的 N 改成命令行参数,通过 sys.argv 读取。每一个小改动,都会让你对字符串和容器的理解再扎实一层。
小结
入门阶段最有效的学习方式,是拿一个能跑通的完整例子反复改。本文从样本出发,依次练了逐行读文件、split 切分字段、Counter 计数和 most_common 排序输出。四步都掌握了,后面无论是做日志分析、数据清洗还是写自动化脚本,都会顺手很多。
- 点赞
- 收藏
- 关注作者
评论(0)