结论:追踪单个 URL 的抓取历史,唯一可靠的做法是把服务端访问日志按「归一化后的 URL」精确过滤,落成带时间戳的记录表,再看爬虫 UA、状态码、响应字节数的变化曲线。搜索引擎后台和本地爬虫工具都只给你「最近一次」或聚合数据,拿不到完整历史。
为什么不能只看搜索引擎后台的抓取统计
结论:Google Search Console 的「抓取统计信息」是按天聚合的整站数据,不按 URL 拆分;URL Inspection API 只返回该 URL 的 lastCrawlTime(最近一次抓取时间),没有历史序列,且配额为每个资源每天 2000 次查询。
同样,Screaming Frog、Sitebulb 这类工具记录的是「你自己爬了什么」,不是搜索引擎爬虫的行为轨迹。所以要看单个 URL 的真实抓取历史,数据源只能是访问日志。
单个 URL 的抓取历史从哪里拿?三种数据源对比
结论:追求完整历史就用 Nginx/Apache 访问日志(可自控字段、自控保留期),要交叉验证再用搜索引擎官方接口。
- 访问日志:字段最全,能拿到 IP、UA、状态码、响应时间、referer,保留多久取决于你的 logrotate 策略。
- GSC URL Inspection API:只能查最近一次,适合做「日志里这个 URL 最后被抓是什么时候」的对照。
- 爬虫工具日志:只反映本地爬取,不能代表 Baiduspider / Googlebot 的访问。
用命令把某个 URL 的抓取记录捞出来
结论:Nginx 默认 combined 格式下,用 grep + awk 两行就能拉出某个 URL 的时间线,按天聚合再加一层 cut。
grep -h 'GET /article/123 ' /var/log/nginx/access.log* \
| awk '{print $4, $1, $8}'
# 2. 看是哪些爬虫在抓(UA 在最后一个引号里)
grep -h 'GET /article/123 ' /var/log/nginx/access.log* \
| awk -F'"' '{print $6}' \
| grep -oE 'Baiduspider|Googlebot|bingbot|YandexBot|360Spider|Sogou web spider' \
| sort | uniq -c
# 3. 按天统计抓取频次
grep -h 'GET /article/123 ' /var/log/nginx/access.log* \
| awk '{print $4}' | tr -d '[' | cut -d: -f1 | sort | uniq -c
历史日志被压缩过要用 zgrep -h 替换 grep -h,access.log* 通配符配合 -h 可以不输出文件名。抓取量大的站建议把结果直接写入 SQLite 或 ClickHouse,用 (url_normalized, crawl_time) 建联合索引,再按天做增量聚合。
URL 归一化:怎么保证统计的是同一个 URL
结论:不做归一化,/article/123、/article/123/、/article/123?utm_source=x 会被算成三个 URL,历史被切成碎片。
归一化规则建议按这个顺序执行:
- 去掉
utm_*、fbclid、spm 等纯跟踪参数;
- 统一
http/https 协议、统一 host 大小写;
- 去掉末尾多余的
/(根目录除外);
- 去掉默认端口
:80、:443;
- 排序保留的业务参数(如
?page=2&sort=price → 按字母序排列)。
站点同时输出 <link rel="canonical"> 的话,把 canonical 值作为归一化 key 最省事。
抓取历史要记录哪些字段
结论:至少要存 7 个字段,否则你无法回答「这次抓取和上次有什么不同」。
url_normalized、crawl_time(精确到秒)、crawler_name(从 UA 提取)、ip、status_code、response_bytes、response_time。
注意 $request_time 和 $upstream_response_time 默认不在 combined 格式里,需要在 nginx.conf 的 log_format 中显式加上,否则响应时间字段拿不到。
三个容易踩的坑
结论:304 也是抓取、CDN 会吞日志、日志轮转会截断时间线,这三点最容易让人误判「爬虫不来了」。
- 304 陷阱:返回
304 Not Modified 同样是一次有效抓取,但 response_bytes 为 0,别把它当成「没抓」。
- CDN 吞日志:站前挂了 CDN,源站日志里可能只剩回源请求,要看 Cloudflare Logpush、阿里云 CDN 实时日志这类边缘日志。
- 日志轮转:
logrotate 按天切割后老文件会变 .gz,查询时一定要带 * 通配并处理压缩文件。
盯单个 URL 的抓取历史,本质上就是「日志过滤 + URL 归一化 + 时间序列落库」这三步。先把归一化规则定死,再把时间、UA、状态码、响应时间四列存下来,之后无论是排查收录掉线还是对比抓取频次变化,都能直接查出完整轨迹。