⭐ 推荐:社区规则条款 V1.0

蜘蛛爬虫分析中状态码统计怎么做?

chinaz
chinaz 初级会员超兽战士
发布于 2026-10-11 15:14 ·2 浏览 ·0 回复

学完这篇,你能从 Nginx/Apache 访问日志里按 Googlebot、Baiduspider、bingbot 等蜘蛛分别统计 200、301、404、500 等状态码,并快速定位抓取异常。

第一步:确认日志格式,找到状态码列

这一步要确认日志里状态码在第几列,做完你才能避免把请求时间或字节数当成状态码。先看一条 Nginx 默认 combined 格式日志:

head -1 /var/log/nginx/access.log

典型输出:

127.0.0.1 - - [10/Oct/2023:13:55:36 +0800] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

按空格切分后,第 9 列是状态码。验证一下:

awk '{print $9}' /var/log/nginx/access.log | head

如果输出是 200、301、404、500,说明列位置正确。若你改过 Nginx log_format,以实际输出为准。

注意:日志可能被切割成 access.log.1、access.log.2.gz。分析历史日志用 zcat /var/log/nginx/access.log*.gz,不要只盯当前 access.log。

第二步:用 awk 按蜘蛛统计状态码

这一步要把蜘蛛请求过滤出来,再统计状态码数量,做完你能得到每个爬虫的 200、404、500 分布。Nginx 日志是纯文本,awk + sort + uniq 最快:

awk '$0 ~ /Googlebot|Baiduspider|bingbot|YandexBot|Sogou web spider|360Spider/ {print $9}' /var/log/nginx/access.log \
| sort | uniq -c | sort -nr

输出类似:

 1200 200
   35 301
   18 404
    3 500

如果要把 Googlebot 和 Baiduspider 分开看,用循环:

for bot in Googlebot Baiduspider bingbot YandexBot; do
  echo "== $bot =="
  awk -v b="$bot" 'index($0,b)>0 {print $9}' /var/log/nginx/access.log \
  | sort | uniq -c | sort -nr
done

注意:只看总状态码没有意义。Googlebot 全是 200,不代表 Baiduspider 没有 404。必须按蜘蛛分开统计。

第三步:用 GoAccess 看可视化状态码报表

这一步要把日志生成 HTML 报表,做完你能在浏览器里点菜单看状态码和爬虫面板。以 GoAccess 1.9.3 为例,Ubuntu/Debian 安装:

sudo apt update
sudo apt install goaccess

生成报表:

goaccess /var/log/nginx/access.log --log-format=COMBINED -o report.html

用浏览器打开 report.html。在顶部导航栏点击 “Crawlers” 可看爬虫请求量;点击 “HTTP Status Codes” 可看整体状态码分布。若要“某个蜘蛛 + 某个状态码”的精确交叉表,仍建议用第二步或第四步。

注意:GoAccess 默认按日志行解析,Nginx 自定义格式要加 --log-format,例如 --log-format='%h %^[%d:%t %^] "%r" %s %b "%R" "%u"',否则状态码会错位。

第四步:用 Python 按蜘蛛+状态码做交叉表

这一步适合多天日志和复杂筛选,做完你能导出 CSV 给运营或 SEO 看。安装 pandas:

pip install pandas

脚本:

import re
import pandas as pd

pattern = re.compile(
    r'(?P<ip>\S+) \S+ \S+ \[(?P<time>[^\]]+)\] '
    r'"(?P<req>[^"]*)" (?P<status>\d{3}) \S+ '
    r'"[^"]*" "(?P<ua>[^"]*)"'
)

rows = []
with open('/var/log/nginx/access.log', encoding='utf-8', errors='ignore') as f:
    for line in f:
        m = pattern.search(line)
        if m:
            rows.append(m.groupdict())

df = pd.DataFrame(rows)
bots = {
    'Googlebot': 'Googlebot',
    'Baiduspider': 'Baiduspider',
    'bingbot': 'bingbot',
    'YandexBot': 'YandexBot'
}

def pick_bot(ua):
    for key, name in bots.items():
        if key.lower() in ua.lower():
            return name
    return '其他'

df['bot'] = df['ua'].apply(pick_bot)
spider = df[df['bot'] != '其他']
result = spider.groupby(['bot', 'status']).size().unstack(fill_value=0)
print(result)
result.to_csv('spider_status.csv', encoding='utf-8-sig')

打开 spider_status.csv,你会看到行是蜘蛛,列是状态码,单元格是请求数。

注意:User-Agent 可以伪造。重要判断不要只信 UA,Googlebot 可结合反向 DNS 或 Google Search Console 的抓取统计验证。

第五步:按天看趋势,设异常阈值

这一步要把状态码统计拆到每天,做完你能发现某天 404 突然升高或 5xx 集中爆发。命令:

{ zcat /var/log/nginx/access.log*.gz 2>/dev/null; cat /var/log/nginx/access.log; } \
| awk '$0 ~ /Googlebot|Baiduspider|bingbot/ {print $4}' \
| cut -d: -f1 | sort | uniq -c

得到每天蜘蛛请求量。再把日期和状态码组合:

{ zcat /var/log/nginx/access.log*.gz 2>/dev/null; cat /var/log/nginx/access.log; } \
| awk '$0 ~ /Googlebot/ {print $4, $9}' \
| cut -d: -f1 | sort | uniq -c

重点看:404 是否指向已删除页面,403 是否被防火墙拦截,429 是否限速过严,5xx 是否服务器不稳定。

小结

  • 先确认日志格式,Nginx combined 格式中状态码通常在第 9 列。
  • 必须按蜘蛛分开统计,不要只看总状态码。
  • 快速统计用 awk + sort + uniq,可视化用 GoAccess,复杂分析用 Python pandas。
  • 历史日志要处理 .gz 压缩文件,命令用 zcat 或 zgrep。
  • UA 可能伪造,关键蜘蛛要结合反向 DNS 或 Search Console 验证。
  • 重点监控 404、403、429、5xx,并按天看趋势。
版权声明:本文来自 GJ站长论坛《蜘蛛爬虫分析中状态码统计怎么做?》
原文链接:https://www.gj0.com/thread-1636.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。

全部回复 0

还没有回复,来抢沙发~