用 Python 统计日志里每个 IP 的访问次数

排查异常流量最基础的一步:从 access.log 里数出「哪个 IP 来得最多」。本文代码为真实运行验证版(2026-10-06 实跑通过)。

核心脚本

import re, collections

pat = re.compile(r'\b(\d{1,3}(?:\.\d{1,3}){3})\b')
cnt = collections.Counter()
status = collections.Counter()

for line in open('access.log'):
    m = pat.search(line)
    if not m:          # 坏行/空行直接跳过,别让整段崩掉
        continue
    cnt[m.group(1)] += 1
    sm = re.search(r'\s(\d{3})\s*$', line)
    if sm:
        status[sm.group(1)] += 1

print("IP Top:", cnt.most_common(10))
print("状态码分布:", dict(status))

实跑结果

用一份 9 行测试日志(含 1 行无 IP 的坏行)验证:

IP Top: [('203.0.113.5', 4), ('198.51.100.7', 2)]
状态码分布: {'200': 5, '404': 1, '500': 1}

坏行被正确跳过,计数准确。

4 个容易踩的坑

  1. 别用 split 硬切:不同日志格式列数不一样,正则匹配「IP 形状」更稳;\b 防止从时间戳里截出假 IP。
  2. IP 提取和状态码提取分开:状态码在行尾,单独用 \s(\d{3})\s*$ 锚定,避免 200(响应)和时间混淆。
  3. 坏行必须跳过:真实日志总有打烂的行,if not m: continue 这一行是脚本能不能跑完的关键。
  4. 用 Counter 而不是 dict 手写:most_common(10) 一行出 Top 榜,自己写排序既慢又容易错。

不想自己折腾日志?喵窝资源铺提供代写脚本/数据清洗服务(¥19.9 起)→

← 返回全部文章