蜘蛛的抓取次数是一种有限资源。很多站点遇到的并不是“蜘蛛不来”,而是它把访问额度花在了一批长期没有变化的页面上——每次到访都返回同样的内容,等于白跑一趟。减少这类空趟,条件请求和更新信号是两个可以立刻动手的地方。
为什么蜘蛛会反复抓取没有变化的页面
搜索引擎并不知道某个页面什么时候改了内容,它只能靠两条线索:一是页面自己给出的更新信号(Last-Modified、ETag),二是历史抓取记录里观察到的变化频率。如果页面既不给更新信号,又曾经在某个时间段频繁变动过,蜘蛛往往会保持一段时间的较高访问频率,直到多次确认“没什么变化”才慢慢降低。
所以问题通常不在爬虫,而在响应头里缺少判断依据。
条件请求在日志里长什么样
当抓取端带上 If-Modified-Since 或 If-None-Match 请求头,而服务器判断资源未变化时,会返回 304。这类记录在日志里很有辨识度:
- 304:资源未变化,服务器不回传正文,抓取成本最低。
- 200 且带 Last-Modified 或 ETag:正常回传内容,同时给出了下次判断的依据。
- 200 且没有任何缓存相关响应头:每次都要完整回传正文,重复抓取的成本最高。
核对时不必追求 304 比例多高,只要确认重要页面的响应头里确实存在可用的更新信号即可。完全没有信号的站点,才需要优先处理。
Last-Modified 与 ETag 的写法细节
Last-Modified
时间要真实反映内容改动的时间。常见的问题有两类:一是由程序在每次请求时动态生成当前时间,导致这个字段永远在变,等于告诉蜘蛛“页面刚刚改过”;二是内容明明更新了,字段却不动,让蜘蛛误判页面静止。前者会造成高频回访,后者会让新内容迟迟不被重抓。
ETag
ETag 是内容指纹。多节点部署时尤其要注意:如果同一份内容在不同节点上算出不同的 ETag,抓取端每次拿到都不一样,就会一直走 200 全量回传,条件请求形同虚设。核对方法是分别向不同节点请求同一地址,比对响应头里的 ETag 是否一致。
Sitemap 的 lastmod 要与实际改动对齐
把整站的 lastmod 批量刷成当天,短期看似“提醒了蜘蛛”,实际会让这个字段失去参考价值——当所有地址都显示同一时间,抓取端无法区分谁真的更新了。更稳妥的做法是按栏目维护:更新频繁的列表页、详情页如实填写,长期不变的规则页、关于页保留原始时间即可。
更新节奏与抓取频次的错位
日志里经常能看到一种错位:栏目页一周更新多次却很少被抓,而某个几年没动过的说明页每周都被访问若干次。
- 高频更新页面:值得让蜘蛛多来,需要清晰的更新信号与稳定的内链入口。
- 长期不变页面:可以让它安静待着,不必人为制造变动迹象。
如果发现低价值页面占用明显偏多的抓取次数,可以先检查它是否带上了动态的 Last-Modified,或者被大量内链反复指向。
核对清单
- 抽取一周日志,统计同一地址的重复抓取次数与响应码分布。
- 检查重点页面的响应头里是否有稳定的 Last-Modified 或 ETag。
- 多节点环境下比对同一地址的 ETag 是否一致。
- 核对 Sitemap 中 lastmod 与内容实际改动日期是否吻合。
- 观察长期不变页面是否仍被高频抓取,找出原因再决定是否调整。
这些调整不会立刻带来可见的变化,但它们影响的是抓取资源被用在了哪里。把重复抓取降下来,空出来的次数才有机会落到真正需要被发现的地址上。