[{"data":1,"prerenderedAt":313},["ShallowReactive",2],{"blog-soft-404-detection":3,"blog-prev-soft-404-detection":112,"blog-next-soft-404-detection":199},{"id":4,"title":5,"author":6,"body":7,"canonical":96,"category":97,"cover":96,"date":98,"description":99,"draft":100,"extension":101,"keywords":96,"meta":102,"navigation":103,"noindex":100,"ogImage":96,"path":104,"seo":105,"seoDescription":96,"seoTitle":96,"stem":106,"tags":107,"updated":96,"__hash__":111},"blog\u002Fblog\u002Fsoft-404-detection.md","软 404 比死链更伤：我们用日志抓出 3000 条并清完","元析智能",{"type":8,"value":9,"toc":86},"minimark",[10,14,19,22,25,28,31,34,37,40,43,47,50,53,56,59,62,65,68,71,74,77,80,83],[11,12,13],"p",{},"软 404 是页面已经没了、服务器还返回 200，搜索引擎会一直抓、一直收、一直不给排名。我们用日志加状态码分布抓出 3000 条，清理后抓取频次涨了 55%。",[15,16,18],"h2",{"id":17},"什么是软-404","什么是软 404",[11,20,21],{},"用户和搜索引擎都以为页面还在，因为状态码是 200；但页面实际内容是\"暂无内容\"\"内容已删除\"\"加载失败\"。",[11,23,24],{},"常见的成因有三个：前端路由没配 404 兜底、CMS 删除文章后留了空模板、参数错误时返回了空列表页。",[11,26,27],{},"软 404 的坏处不是浪费一个页面，是让搜索引擎的索引里堆满空页面，连累整站质量判断。",[15,29,30],{"id":30},"我们怎么查",[11,32,33],{},"第一步，看日志里的状态码分布。如果 200 的请求占比超过 95%，而站点实际有大量已删除内容，就要怀疑。",[11,35,36],{},"第二步，抽样。从日志里随机抽 200 个返回 200 的 URL，用脚本抓页面正文，看正文长度和关键词。正文少于 100 字、或者标题里带\"未找到\"的，标记出来。",[11,38,39],{},"第三步，用 GSC 的\"已抓取但未编入索引\"报告交叉验证。这个报告里的页面，很多就是软 404。",[11,41,42],{},"2026 年 3 月我们给一个客户查的时候，抽样 200 个页面里有 37 个是软 404，按这个比例推算全站大约 1800 条。后来用脚本全量跑了一遍，实际 3100 条。",[15,44,46],{"id":45},"三类最常见的软-404","三类最常见的软 404",[11,48,49],{},"第一类，商品或功能下线的页面。产品下线了，页面还在，内容换成了\"该功能已调整\"。",[11,51,52],{},"第二类，参数错误的列表页。用户拼错参数，页面返回空列表，状态码 200。",[11,54,55],{},"第三类，前端路由的兜底页。SPA 里所有未匹配路由都渲染同一个空壳页，服务器返回 200。",[15,57,58],{"id":58},"修复顺序",[11,60,61],{},"先修影响大的：有外链指向的、还有搜索点击的、被收录的。这三类优先 301 到最相关的页面。",[11,63,64],{},"没有替代页面的，直接返回 410 或 404。别怕\"用户看到 404 不舒服\"，返回 200 的空页面更糟。",[11,66,67],{},"前端路由的兜底页要从根上改：未匹配路由返回 404，同时给用户一个可用的导航页。",[15,69,70],{"id":70},"修复后的数据",[11,72,73],{},"那个客户 3100 条软 404，我们清了 4 周。第 6 周看数据：抓取频次涨 55%，\"已抓取未编入索引\"从 1.1 万降到 4200，核心产品页的平均抓取间隔从 9 天缩到 3 天。",[11,75,76],{},"排名的变化慢一些，第 10 周才看到核心词平均提升 2.3 名。",[15,78,79],{"id":79},"判断",[11,81,82],{},"软 404 是技术 SEO 里最容易被忽略的一类，因为它不报错、不提醒、不影响用户。但它对抓取效率的损耗是实打实的。",[11,84,85],{},"每季度跑一次全量检查，比出事后再查便宜得多。这件事没有工具能一键完成，只能建自己的脚本，我们一般一天能跑完。",{"title":87,"searchDepth":88,"depth":88,"links":89},"",2,[90,91,92,93,94,95],{"id":17,"depth":88,"text":18},{"id":30,"depth":88,"text":30},{"id":45,"depth":88,"text":46},{"id":58,"depth":88,"text":58},{"id":70,"depth":88,"text":70},{"id":79,"depth":88,"text":79},null,"技术SEO","2026-05-22","软 404 是页面已经没了、服务器还返回 200，搜索引擎会一直抓、一直收、一直不给排名。我们用日志加状态码分布抓出 3000 条，清理后抓取频次涨了 55%。查法、分类和修复顺序都在这篇，清理前后的数据对比在文末，值得每季度跑一次。",false,"md",{},true,"\u002Fblog\u002Fsoft-404-detection",{"title":5,"description":99},"blog\u002Fsoft-404-detection",[108,109,110],"软404","状态码","抓取","iGB0GXREiPW54w66EGO21t52OSD7aP1-21djciYKyWc",{"id":113,"title":114,"author":6,"body":115,"canonical":96,"category":187,"cover":96,"date":188,"description":189,"draft":100,"extension":101,"keywords":96,"meta":190,"navigation":103,"noindex":100,"ogImage":96,"path":191,"seo":192,"seoDescription":96,"seoTitle":96,"stem":193,"tags":194,"updated":96,"__hash__":198},"blog\u002Fblog\u002Fnew-site-vs-old-site-diagnosis.md","新站和老站的诊断顺序不一样，别用同一张清单",{"type":8,"value":116,"toc":180},[117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177],[11,118,119],{},"2026 年 5 月我们同时接了两个站，一个是上线三个月的新站，一个是跑了七年的老站，诊断清单完全不同。新站的核心问题是搜索引擎还没认它，老站的核心问题是历史包袱太多。用同一套清单，等于两边的重点都抓不住。",[15,121,122],{"id":122},"新站先证明能收录",[11,124,125],{},"新站最怕的是做了三个月内容，一查收录为零。所以第一个月只做一件事：确认页面能被抓、能被收。",[11,127,128],{},"具体查三处。robots 有没有误屏蔽整站，尤其是测试环境配置带到了生产。站点地图有没有提交，能不能正常访问。首页到核心页的内链通不通，别让重要页面离首页四跳以上。",[11,130,131],{},"还有一个容易忽略的点：新站的域名如果有过历史，先查一下 Wayback 和 GSC，看有没有被惩罚过或者留着大量垃圾外链。我们见过一个站上线第一周就发现域名以前做过采集站。",[15,133,134],{"id":134},"老站先清历史包袱",[11,136,137],{},"老站要先做的是减法。七年的站点，常见情况是几千个废弃页面、两三套并存的 URL 结构、旧版站点还挂在线。",[11,139,140],{},"查的顺序：先看收录页面的状态码分布，找出大量 404 和 301；再看 canonical 是不是指向了奇怪的地方；最后看站点地图里有多少页面其实已经不存在。",[11,142,143],{},"2025 年我们处理过一个站，1.2 万个收录页面里，有 4000 多个是已经不存在的产品页和旧博客。这些页面吃掉抓取预算，还让整站质量显得很低。",[15,145,146],{"id":146},"新站的时间预算",[11,148,149],{},"新站不要排太多内容。前两个月最多 8 到 12 篇，重点是把核心页面做扎实：首页、产品页、文档入口、定价页、关于页。",[11,151,152],{},"这几个月的主要工作是建立主题相关性。围绕一个核心方向连续写，让搜索引擎知道你是干什么的。东一篇西一篇最浪费。",[11,154,155],{},"判断标准也很直接：三个月后核心页面有没有被收录、目标词有没有出现曝光。有曝光就有希望，连曝光都没有，先查技术。",[15,157,158],{"id":158},"老站的时间预算",[11,160,161],{},"老站前两个月基本都在做清理和修复，内容可以先放一放。",[11,163,164],{},"清理的顺序按影响排：5xx 和 404 先处理，重复内容合并，旧 URL 做 301，废弃页面 410。做完这些再谈内容。",[11,166,167],{},"老站还有个机会：历史内容里有大量可以更新的页面。把排在第 11 到 20 名的老文章挑出来，补数据、补案例、改标题，比写新文章见效快。",[15,169,170],{"id":170},"两者的共同点",[11,172,173],{},"不管新老，第一件事都是把数据存下来，然后跑一次爬虫、读一次日志。这两件事不做，后面的判断全靠猜。",[11,175,176],{},"诊断报告给客户的结论也不一样：新站给的是“多久能看到第一批曝光”，老站给的是“清理需要多久、清理完能释放多少抓取”。",[11,178,179],{},"把这两类站混在一起做，最常见的后果是新站被安排了大量技术修复，老站被安排了大量新内容。都不是当下最该做的事。",{"title":87,"searchDepth":88,"depth":88,"links":181},[182,183,184,185,186],{"id":122,"depth":88,"text":122},{"id":134,"depth":88,"text":134},{"id":146,"depth":88,"text":146},{"id":158,"depth":88,"text":158},{"id":170,"depth":88,"text":170},"SEO","2026-05-21","新站先证明能被收录，老站先清历史包袱。这篇写两种站各自的前两个月怎么排：先查什么、跳过什么、什么时候能判断有没有救，附两条判断标准。",{},"\u002Fblog\u002Fnew-site-vs-old-site-diagnosis",{"title":114,"description":189},"blog\u002Fnew-site-vs-old-site-diagnosis",[195,196,197],"站点诊断","新站","老站","04qxC1D7K33K2C6BtS1NmznnQbXQx9WNLOfhyyGmIS0",{"id":200,"title":201,"author":6,"body":202,"canonical":96,"category":97,"cover":96,"date":302,"description":303,"draft":100,"extension":101,"keywords":96,"meta":304,"navigation":103,"noindex":100,"ogImage":96,"path":305,"seo":306,"seoDescription":96,"seoTitle":96,"stem":307,"tags":308,"updated":96,"__hash__":312},"blog\u002Fblog\u002Ftrailing-slash-case-duplicate.md","尾斜杠和大小写：同一页面两个 URL 的隐形重复",{"type":8,"value":203,"toc":293},[204,207,210,213,217,229,232,235,254,257,260,263,274,277,280,284,287,290],[11,205,206],{},"一个页面只应该有一个可访问的 URL 形式。尾斜杠、大小写、index.html、http 与 https、www 与非 www，这五类变体统一在服务器层 301，别让两个都保持 200。听起来是小事，但它造成的重复内容比参数还隐蔽。",[15,208,209],{"id":209},"为什么危险",[11,211,212],{},"搜索引擎需要判断哪个是主版本。外链和分享又散落在不同变体上，权重被切成几份。日志里抓取量被稀释，你以为是收录问题，其实是同一个页被当成三个页在抓。canonical 能救一部分，但它是建议不是强制，服务器层没统一就一直在漏。",[15,214,216],{"id":215},"_2026-年-1-月那次","2026 年 1 月那次",[11,218,219,220,224,225,228],{},"一个开发者工具站，文档页同时存在 ",[221,222,223],"code",{},"\u002FDocs\u002FAPI\u002F"," 和 ",[221,226,227],{},"\u002Fdocs\u002Fapi"," 两种形式，站内链接混用，外部链接也混着来。GSC 里 60% 的文档页报了\"重复网页，用户未选定规范网页\"。",[11,230,231],{},"统一成全小写、无尾斜杠之后，一个月重复网页从 60% 降到 8%，文档页的收录率从 55% 涨到 79%。改动就是 nginx 里三条规则。",[15,233,234],{"id":234},"五类变体的处理顺序",[236,237,238,242,245,248,251],"ol",{},[239,240,241],"li",{},"http 全部 301 到 https，一次跳到位。",[239,243,244],{},"裸域 301 到 www（或者反过来，选一个，别两个都行）。",[239,246,247],{},"大写 301 到小写。",[239,249,250],{},"尾斜杠统一：目录类路径统一无斜杠，或者统一带斜杠，二选一。",[239,252,253],{},"index.html 折叠到目录，301 过去。",[11,255,256],{},"顺序有讲究：先做协议和主机名，再做路径层。不然会出一条链跳三四次。",[11,258,259],{},"我们给客户定这条规则时，会顺手把 CDN 的缓存键也一起看：如果缓存键包含大小写或尾斜杠，同一个页面会在边缘节点缓存成多份，命中率下降，回源请求变多，本质上和重复 URL 是同一个问题。",[15,261,262],{"id":262},"服务器层怎么写",[11,264,265,266,269,270,273],{},"nginx 用 ",[221,267,268],{},"return 301"," 或 ",[221,271,272],{},"try_files"," 组合，Apache 用 mod_rewrite，CDN 层也要检查一遍，很多人只改了源站，边缘节点还返回旧结果。静态站生成器要统一 URL 输出规则，别让不同页面类型生成不同形式。",[15,275,276],{"id":276},"验证方法",[11,278,279],{},"curl 每个变体看返回码和 Location；Screaming Frog 爬一遍看有没有 301 和重复标题；GSC 网址检查确认 canonical 和最终 URL 一致。这三步花不到一小时。",[15,281,283],{"id":282},"和-canonical-的关系","和 canonical 的关系",[11,285,286],{},"服务器统一和 canonical 是两道防线，不是二选一。服务器层解决了大部分变体，canonical 兜住那些没法重定向的情况，比如参数变体、跨域镜像。只靠 canonical 不做重定向，蜘蛛每次还是会请求多个变体，抓取预算照样被切碎。",[15,288,289],{"id":289},"立场",[11,291,292],{},"这不是小事。一个站点三种 URL 形式，等于把权重分三份，再努力也是三分之一。统一规则的收益比多写十篇文章快。",{"title":87,"searchDepth":88,"depth":88,"links":294},[295,296,297,298,299,300,301],{"id":209,"depth":88,"text":209},{"id":215,"depth":88,"text":216},{"id":234,"depth":88,"text":234},{"id":262,"depth":88,"text":262},{"id":276,"depth":88,"text":276},{"id":282,"depth":88,"text":283},{"id":289,"depth":88,"text":289},"2026-05-23","\u002Fdocs\u002Fapi 和 \u002Fdocs\u002Fapi\u002F 是不是同一页，\u002FAbout 和 \u002Fabout 呢？这两类重复比参数更隐蔽。这篇给服务器层的统一规则、五类变体的处理顺序，以及一个 2026 年 1 月的修复记录。",{},"\u002Fblog\u002Ftrailing-slash-case-duplicate",{"title":201,"description":303},"blog\u002Ftrailing-slash-case-duplicate",[309,310,311],"URL设计","重复内容",301,"jRlViDM6rOiCWw4iVh3ooY6pmG4fGkmXp82FxlJoabo",1794088105429]