百度收录量忽然腰斩:用日志分析追查 Baiduspider 抓取异常的完整过程

2026-09-26 01:16:11 1 次浏览
SEO百度搜索资源平台日志分析爬虫Nginx

适用读者:维护传统网站的 SEO 技术同学、管 Nginx 的后端工程师,以及所有盯着百度索引量曲线发愁的站长。

两周时间,站点的百度索引量从 4200 掉到 1900,掉了一半还多。搜索资源平台的后台却一直显示「数据正常」,反馈中心提交问题,等来的也是模板回复。运营那边急了,把电话打到运维老周(化名)那里,老周看了一眼监控说:「服务器没报警,流量也稳,应该不是我们的问题。」这句话后来被证明完全不对——问题恰恰就出在我们自己身上,而且是两个叠加在一起的低级错误。

这是一家做本地生活服务的站点,页面量不小,本地服务类目的搜索流量占了大头。索引量腰斩意味着接下来几周自然流量会跟着往下塌,等流量曲线掉下去再动手就晚了。所以那天下午我们决定不猜了,直接去翻 Nginx 的访问日志。

后台说正常,日志里全是事故现场

百度搜索资源平台的索引量工具给的是一个事后统计值,更新有延迟,而且只告诉你掉了多少,不告诉你为什么掉。后台显示「正常」指的是平台服务本身没故障,跟蜘蛛抓没抓到你的页面是两码事。这个区别当时没人想明白,大家都在等后台自己恢复,一等就是一周。

日志面板、放大镜与爬虫机器人

访问日志不会撒谎。当晚我把前一周的 access.log 拉下来粗看了一眼,自称 Baiduspider(百度蜘蛛)的请求量并不少,但状态码很扎眼:大片的 404 和 302,中间还夹着成串的 429。情况清楚了——蜘蛛天天来,来的却大都在撞墙。

不过在分析状态码之前,还有一道必须先做的工序:分清真假蜘蛛。

真假 Baiduspider 的判定机制

网上有大量流量伪装成百度蜘蛛来爬站,有的想薅内容,有的干脆在扫漏洞。如果把假蜘蛛的请求算进抓取统计,后面所有结论都是歪的。判定真蜘蛛只有一个可靠办法:反向 DNS(Reverse DNS)验证,这也是 Google 官方推荐验证 Googlebot 的同一套思路,百度官方文档里的判定要求是一致的。

机制拆开看是这样:真蜘蛛的来源 IP 做 PTR 反查,得到的域名一定落在 baidu.com 或 baidu.jp 的子域下,形如 crawl-116-179-32-1.baidu.com。光有这一步还不够严谨,因为 PTR 记录本身可以伪造,所以要再做一次正向解析,把反查出来的域名解析回 IP,结果里必须包含原来那个 IP,两次都过才算数。UA 字段里带 Baiduspider 字样不构成任何证据,UA(User-Agent)是客户端自己填的字符串,想写什么写什么。

flowchart TD
    A[日志中发现 Baiduspider UA] --> B[提取来源 IP]
    B --> C[对 IP 做 PTR 反查]
    C --> D{域名以 .baidu.com 或 .baidu.jp 结尾?}
    D -- 否 --> E[标记为假蜘蛛]
    D -- 是 --> F[对该域名做正向解析]
    F --> G{解析结果包含原 IP?}
    G -- 否 --> E
    G -- 是 --> H[确认为真蜘蛛]

当天日志里自称 Baiduspider 的来源 IP 有 47 个,走完两步验证后只剩 9 个,其余 38 个全是伪装流量,占比超过八成。这批假流量的请求集中在站外推广落地页和搜索参数页,一看就是冲着内容库存来的。先把它们从统计里剔掉,才能看真蜘蛛到底遇到了什么。

日志分析脚本:反查验证与状态码统计

环境说明:CentOS 7,Nginx 1.20,日志为 combined 格式,主机上装有 bind-utils(提供 host 命令)。反查这步用 shell 就够,统计部分用 Python,无第三方依赖。

# 前置条件:能登录网站服务器,装有 bind-utils 或 dnsutils(提供 host 命令)
# 目标:把日志里自称 Baiduspider 的来源 IP 逐一反查验证

# 从当天日志抽出所有带 Baiduspider 的请求 IP,去重
awk -F'"' '/Baiduspider/ {print $1}' access.log | awk '{print $1}' | sort -u > spider_ips.txt

# 逐个 IP 做反向 DNS,看 PTR 记录落在哪个域
while read ip; do
  ptr=$(host "$ip" 2>/dev/null | awk '{print $NF}')
  echo "$ip -> $ptr"
done < spider_ips.txt

# 判定标准:PTR 必须是 *.baidu.com 或 *.baidu.jp 结尾
# 其他任何形如 baiduspider-xxx.xxx 的域名都按假蜘蛛处理

# 把两步验证都通过的 IP 手工整理进白名单文件
cat > spider_ips_verified.txt <<'EOF'
# 以下 IP 均已通过 PTR 反查 + 正向解析双重验证
# 116.179.32.x 段与 123.125.71.x 段为常见真蜘蛛来源
EOF

# 对通过反查的域名再正向解析一次,确认解析回同一个 IP
host crawl-116-179-32-1.baidu.com
# 输出地址列表里必须包含原来那个 IP,双重验证才算过
# 依赖:Python 3.8+,无第三方库
# 用途:统计真蜘蛛(IP 已通过反查验证)请求的状态码分布
# 日志格式:Nginx combined

import re
from collections import Counter

# 读取双重验证通过的真蜘蛛 IP 清单,每行一个
REAL_IPS = set(open("spider_ips_verified.txt").read().split())

# 匹配请求行里的状态码,例如 "GET /x HTTP/1.1" 404
STATUS = re.compile(r'HTTP/1\.[01]" (\d{3})')
# 匹配请求的目标 URL,用于单独统计 404 死链
PATH = re.compile(r'"(?:GET|POST|HEAD) ([^ ?]+)')

status_counter = Counter()
path_counter = Counter()

for line in open("access.log", encoding="utf-8", errors="ignore"):
    # 先按 UA 粗筛,减少后续正则的运算量
    if "Baiduspider" not in line:
        continue
    # 再按来源 IP 精筛,只留反查验证过的真蜘蛛
    ip = line.split()[0]
    if ip not in REAL_IPS:
        continue
    m = STATUS.search(line)
    if not m:
        continue
    code = m.group(1)
    status_counter[code] += 1
    # 404 的目标地址单独计数,方便后续回收旧链接
    if code == "404":
        p = PATH.search(line)
        if p:
            path_counter[p.group(1)] += 1

total = sum(status_counter.values())
# 输出状态码占比,看清抓取配额被谁吃掉了
for code, n in status_counter.most_common():
    print(code, n, f"{n / total:.1%}")

# 输出被抓得最多的死链 Top 20,作为回收清单的输入
for p, n in path_counter.most_common(20):
    print("404", n, p)

跑完统计,问题全部摆在桌面上。

状态码分布:抓取配额被谁吃掉了

真蜘蛛两周内一共留下约 12.6 万条请求,状态码分布如下。

状态码 占比 典型目标 问题定性
200 32% 首页、栏目页 正常返回
404 26% 旧新闻详情页 迁移后链接未回收
302 14% 旧域名跳转 应改 301 永久跳转
429 20% 全站随机 限流模块误伤真蜘蛛
5xx 及其他 8% 动态接口 上游偶发超时

抓取配额(Crawl Budget)是个容易被忽略的东西:百度给一个站点的抓取频次有上限,蜘蛛在站内每次打在 404 或 302 上,都是在消耗这份配额。配额被死链和临时跳转吃掉四成,正常页面的抓取量自然上不去,新内容进不了索引,旧内容又因为长期得不到更新抓取被逐步清退,索引量就这么一路往下掉。

顺着 404 Top 20 的地址清单往下追,两个源头很快浮出来。一个是旧链接没回收:半年前站点从旧域名迁到新域名,新闻详情页的 URL 规则改过一次,迁移时只做了首页和栏目的跳转,十几万条详情页旧地址悬空,蜘蛛手里攥着的还是旧地址,来了就是 404。302 的来源类似,旧域名当初配的是临时跳转,一直没人改成 301(永久重定向)。另一个是 robots 文件误封:对比迁移前后的 robots.txt,新文件里多了一行 Disallow: /m/。本意是封掉移动端一套废弃模板,但移动端站点实际就挂在 /m/ 目录下,这一封等于把移动端全部页面挡在抓取之外。上线两个月,/m/ 下没有任何新页面被抓过。

至于 429,是迁移时新上的限流模块干的。运维照着网上教程配了 Nginx 限流(Rate Limiting),阈值给得激进,真蜘蛛抓取频次一冲高就撞墙,撞了就收到 429。假蜘蛛倒是不受影响——它们分散在各个 IP 上,没触发单 IP 限流。这个对比很讽刺,也说明限流策略压根没考虑过搜索引擎蜘蛛的来源特征。

修复时间线:六周从 1900 回到 5100

问题清单确定后,按影响面从大到小排期动手,前两周见效最快。

timeline
    title 六周修复与恢复时间线
    第 1 周 : 删除 robots 中的 Disallow: /m/ : 限流模块为已验证蜘蛛 IP 开白名单
    第 2 周 : 详情页旧地址批量映射 : Nginx 层下发 301 规则
    第 3 周 : 旧域名 302 全部改为 301 : 抓取异常占比首次降到 10% 以内
    第 4 周 : 资源平台提交新链接与死链清单 : 索引量止跌回升到 2600
    第 5 周 : /m/ 移动端页面重新被抓取 : 索引量到 3700
    第 6 周 : 常规内容更新节奏恢复 : 索引量回到 5100

第 1 周先把 robots.txt 里的 Disallow: /m/ 删掉,这是零成本动作;同一周给限流配置加上了已验证蜘蛛 IP 段的白名单,429 从此归零。第 2 周到第 3 周处理旧链接,十几万条详情页旧地址按规则映射到新地址,直接在 Nginx 层做批量 301,同时把旧域名的 302 全部改成 301。第 4 周在搜索资源平台提交新链接和死链清单,让百度那边尽快更新对站点的认知。第 5、6 周基本是等,索引量从第三周末开始抬头,第 6 周末回到 5100,比掉之前的 4200 还多出 900——迁移后一直没被抓的移动端页面这回全进来了。

修复前后的关键数据对比:

指标 修复前(8 月中) 修复后(10 月初)
真蜘蛛日均抓取次数 约 9000 约 21000
404 占比 26% 3%
429 占比 20% 0
302 占比 14% 1%
百度索引量 1900 5100

几条经验写给同行,少走弯路。索引量下降时别只盯后台,第一时间去服务器拉日志,日志是最接近事实的数据源。任何迁移,301 重定向和 robots 检查要当成发布清单的固定项,不能靠事后补。限流策略必须给搜索引擎蜘蛛留通道,否则等于亲手把蜘蛛往外推。真假蜘蛛的判定只能靠 DNS 反查加正向验证,UA 靠不住,这条没有变通余地。

顺带说说 GEO:AI 爬虫的日志长得不一样

这套日志分析方法同样适用于盯 AI 爬虫(GEO,Generative Engine Optimization 关注的那批机器人),但识别方式有差别。搜索引擎蜘蛛普遍提供官方反向 DNS 验证,百度蜘蛛认 baidu.com 和 baidu.jp,Googlebot 认 googlebot.com 和 google.com;而不少 AI 爬虫的反查验证要么没提供,要么域名不统一,GPTBot、ClaudeBot 这类主要靠 UA 加已知 IP 段对照来识别,误判率天然高一些。关注点也不同:搜索引擎蜘蛛看重抓取频次与收录规模,AI 爬虫更在意内容能不能被引用进生成的答案,日志里的地址分布、命中页面类型差别都很大。传统 SEO 和 GEO 短期内是两套并行的事,别混在同一个仪表盘里看。

误区澄清或趋势预判

两个常见误区顺手澄清。有人认为索引量下降一定是内容质量问题,先改文章再说——如果抓取环节满是 404 和 429,内容写得再好蜘蛛也拿不走,先修抓取链路再看内容,顺序不能反。也有人觉得给蜘蛛放开抓取会让服务器压力变大,实际上配合正确的限流白名单和缓存策略,蜘蛛的请求模式相当规律,压力完全可控。

往后看,搜索引擎对站点质量的判断会越来越依赖抓取环节的信号:返回 410 和正确 301 的站点,比满站 404 加 302 的站点,在同等内容条件下拿到的抓取配额只会差距更大。日志分析这门老手艺,做站点的人值得练熟。

参考与延伸

  • 百度搜索资源平台学院(官方教程与规范入口):https://ziyuan.baidu.com/college/index
  • Google 官方对验证 Googlebot 的反查 DNS 方法说明(思路与百度蜘蛛一致):https://developers.google.com/search/docs/crawling-indexing/verify-googlebot
  • 百度搜索资源平台(索引量工具与反馈中心):https://ziyuan.baidu.com/

百度收录、Baiduspider、日志分析、抓取配额、Nginx、301 重定向

🤖
本内容由 AI 辅助生成,经人工校对审核;部分素材、资料来源于公开网络,仅作个人观点分享与交流使用,无任何商业侵权意图。若内容、图片、文字涉及您的合法著作权、版权权益,请联系本人,核实后将第一时间删除、修改相关内容。