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

如何通过日志分析蜘蛛的抓取路径和内链结构?

周末
周末 新人站长
发布于 2026-10-12 21:47 ·4 浏览 ·0 回复
内容摘要

通过服务器日志筛选并验证搜索引擎蜘蛛请求、将访问记录解析为表格,结合站内爬取数据可还原蜘蛛抓取顺序,并找出内链中的孤儿页面与抓取死角。

学完这篇,你能用服务器日志还原搜索引擎蜘蛛的抓取顺序,并配合站内爬取数据找出内链结构中的孤儿页面和抓取死角。

第一步:找到日志文件并确认格式

这一步要拿到原始访问日志,知道每一列是什么,后面才能准确切分。Nginx 默认日志在 /var/log/nginx/access.log,Apache 在 /var/log/httpd/access_log 或 /var/log/apache2/access.log。先看一眼格式:

head -n 3 /var/log/nginx/access.log

如果看到类似 127.0.0.1 - - [10/Oct/2024:13:55:36 +0800] "GET /a.html HTTP/1.1" 200 512 "-" "Mozilla/5.0",这就是 Nginx 默认的 combined 格式。重点字段是:请求时间、请求 URL、状态码、User-Agent。后面的命令都按这个格式写。

注意:日志可能被轮转成 access.log.1、access.log.2.gz。只分析当前文件会漏掉历史抓取记录。压缩包用 zgrep,例如 zgrep -iE 'Baiduspider' /var/log/nginx/access.log.*.gz。

第二步:筛出蜘蛛请求并验证真伪

这一步把普通用户和蜘蛛分开,得到一份只含蜘蛛的日志。用 grep 过滤常见 UA:

grep -iE 'Baiduspider|Googlebot|bingbot|Sogou web spider|360Spider|YandexBot' /var/log/nginx/access.log > /tmp/spider.log

统计各蜘蛛出现次数:

awk -F'"' '{print $6}' /tmp/spider.log | sort | uniq -c | sort -rn

$6 是 combined 格式里的 User-Agent。如果输出里出现大量陌生 IP,先别高兴,UA 可以伪造。真蜘蛛要验证 IP:百度蜘蛛看官方 IP 段,Googlebot 用 host 66.249.66.1 反查域名,或者看 Google 官方 JSON 验证接口。

注意:不要用 Referer 字段判断内链来源。蜘蛛请求通常不带 Referer,这一列基本都是 -。内链结构要靠后面的站内爬取数据来补。

第三步:把日志拆成可分析的表格

这一步把文本日志变成 CSV,方便排序和统计。新建 parse_spider.py:

import re, csv
pat = re.compile(r'(?P<ip>\S+) - - \[(?P<time>[^\]]+)\] "(?P<method>\S+) (?P<url>\S+) [^"]*" (?P<status>\d+) \S+ "[^"]*" "(?P<ua>[^"]*)"')
bots = re.compile(r'Baiduspider|Googlebot|bingbot|Sogou|360Spider|YandexBot', re.I)
with open('/var/log/nginx/access.log', errors='ignore') as f, open('spider.csv', 'w', newline='') as out:
    w = csv.writer(out)
    w.writerow(['time', 'ip', 'url', 'status', 'ua'])
    for line in f:
        m = pat.match(line)
        if m and bots.search(m.group('ua')):
            w.writerow([m.group('time'), m.group('ip'), m.group('url'), m.group('status'), m.group('ua')])

运行 python3 parse_spider.py,得到 spider.csv。再统计抓取最多的 URL:

awk -F',' 'NR>1 {print $3}' spider.csv | sed 's/?.*//' | sort | uniq -c | sort -rn | head -50

sed 's/?.*//' 是去掉 URL 参数,避免同一个页面被拆成几十条记录。

第四步:还原蜘蛛的抓取路径

这一步看蜘蛛按什么顺序爬、爬了多深。用 Python 按时间排序后,打印某个 IP 的访问序列:

import pandas as pd
df = pd.read_csv('spider.csv')
df = df[df['ua'].str.contains('Baiduspider', case=False)]
df = df.sort_values('time')
print(df[['time', 'url', 'status']].head(100).to_string())

重点看三件事:第一,蜘蛛是不是从首页进入后,沿着导航和内链逐层抓;第二,有没有大量 404、301、302,这些会消耗抓取配额;第三,同一个 URL 是否在短时间内被重复抓取。如果发现蜘蛛直接跳到深层页面,说明该页面有外链或 sitemap 入口;如果只抓首页不抓列表页,通常内链入口太弱。

注意:状态码只统计 200 不够。301、302 也算一次抓取,但最终内容不在这个 URL 上。用 awk -F',' 'NR>1 {print $4}' spider.csv | sort | uniq -c 看状态码分布。

第五步:用站内爬取工具补齐内链结构

这一步拿到每个页面的入链数。打开 Screaming Frog SEO Spider 20.x,在顶部输入域名,点 Start。爬完后点左侧 Internal > All Inlinks,再点右上角 Export,导出 inlinks.csv。这个文件里每一行是一条内链,包含来源页 Source 和目标页 Destination。用 Excel 或 pandas 按 Destination 分组计数,就得到每个页面的内链数量。

也可以用命令行快速统计:

awk -F',' 'NR>1 {print $2}' inlinks.csv | sort | uniq -c | sort -rn > inlink_count.txt

第六步:把日志和内链数据对撞,找出问题页面

这一步是全文目的:找出“有抓取但无入链”和“入链多但抓取少”的页面。把 spider.csv 按 URL 统计抓取次数,和 inlink_count.txt 合并。重点看三类:

  1. 入链数 = 0,但日志里有蜘蛛抓取。这类页面通常来自 sitemap 或外链,站内没有入口,用户也很难点到。
  2. 入链数很高,但蜘蛛抓取次数很少。说明内链位置可能太深,或者链接被 nofollow、JS 渲染挡住。
  3. 抓取深度大于 4 层的页面。用 Screaming Frog 的 Crawl Depth 列排序,超过 4 的页面优先加内链。

注意:URL 要统一。/a、/a/、/a?from=1 在日志里可能算三个页面,分析前先做归一化:统一小写、去参数、补结尾斜杠。

小结

  • 先确认 Nginx/Apache 日志格式,用 grep 筛蜘蛛,再用 Python 转成 CSV。
  • 蜘蛛请求不带 Referer,内链来源必须用 Screaming Frog 的 All Inlinks 补齐。
  • 抓取路径按时间排序看顺序、状态码和深度,重点找 404、301、302 和重复抓取。
  • 把日志抓取次数和入链数对撞,优先处理孤儿页面和深度超过 4 层的页面。
  • UA 可以伪造,关键蜘蛛要验证 IP;日志轮转文件不要漏掉。
版权声明:本文来自 GJ站长论坛《如何通过日志分析蜘蛛的抓取路径和内链结构?》
原文链接:https://www.gj0.com/thread-1800.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。

全部回复 0

还没有回复,来抢沙发~