[{"data":1,"prerenderedAt":274},["ShallowReactive",2],{"blog-crawler-discovery-to-index":3,"blog-prev-crawler-discovery-to-index":98,"blog-next-crawler-discovery-to-index":160},{"id":4,"title":5,"author":6,"body":7,"canonical":82,"category":83,"cover":82,"date":84,"description":85,"draft":86,"extension":87,"keywords":82,"meta":88,"navigation":89,"noindex":86,"ogImage":82,"path":90,"seo":91,"seoDescription":82,"seoTitle":82,"stem":92,"tags":93,"updated":82,"__hash__":97},"blog\u002Fblog\u002Fcrawler-discovery-to-index.md","爬虫从发现到入库走四步，卡在哪一步决定怎么修","元析智能",{"type":8,"value":9,"toc":75},"minimark",[10,14,18,25,31,37,43,46,49,57,60,63,66,69,72],[11,12,13],"p",{},"结论放在前面：一个页面没被收录，原因只可能落在四步里——发现 URL、抓取成功、渲染出内容、通过索引判定。我们排查从来不从\"内容质量\"开始，而是倒着走：先看索引报告给了什么理由，再看抓取和渲染，最后才怀疑内容。",[15,16,17],"h2",{"id":17},"四步各自会断在哪",[11,19,20,24],{},[21,22,23],"strong",{},"第一步，发现。"," 蜘蛛得先知道 URL 存在，靠内链、sitemap、外链三条路。孤岛页、只出现在筛选结果里的产品页、藏在第 5 页之后的分页，常常连\"被发现\"都没做到。",[11,26,27,30],{},[21,28,29],{},"第二步，抓取。"," 知道地址不等于能抓到。robots.txt 规则、服务器 5xx、CDN 拦截、抓取频次过低，都会让请求进不来。判断方法很朴素：看日志里这个路径有没有被请求过。",[11,32,33,36],{},[21,34,35],{},"第三步，渲染。"," 请求成功了，返回的 HTML 里却没有正文——React、Vue 做的产品页和文档站最常见。初始 HTML 只有一个空挂载点，正文全靠 JS 填。",[11,38,39,42],{},[21,40,41],{},"第四步，索引。"," 抓到了、渲染了，还可能因为 canonical 指向别处、页面被标 noindex、内容和别的页重复、整体质量不足而不入库。",[15,44,45],{"id":45},"我们的一次排查",[11,47,48],{},"2025 年 6 月，一个做 API 网关的公司找过来，文档站 1200 个页面，GSC 显示只收录了 298 个。他们自己提交过三次 sitemap，也请人改过两轮内容，四个月没起色。",[11,50,51,52,56],{},"我们先看索引报告，大量文档页的状态是\"已发现，尚未编入索引\"，说明发现没问题、抓取跟不上。再拉日志：Googlebot 每天只请求 60 次左右，其中 40 多次花在一个带参数的搜索页上。查 robots.txt，发现一行 ",[53,54,55],"code",{},"Disallow: \u002Fdocs\u002Fv2\u002F"," 是 2024 年做旧版迁移时留下的，一直没删，而 v2 恰好是现在的主力文档。",[11,58,59],{},"顺手又发现 sitemap 里有 3200 条是带 utm 参数的 302 跳转链接，等于往搜索引擎嘴里塞了一堆无效地址。",[11,61,62],{},"只改了两处：删掉那行 Disallow，sitemap 只保留返回 200 的规范 URL。第 11 天收录数从 298 涨到 913，一个月后 1200 页里收录了 1100 出头。",[15,64,65],{"id":65},"排查顺序为什么不能反",[11,67,68],{},"内容质量是四步里成本和周期都最高的一环，重写一轮至少两个月才能看出效果；robots.txt 和 sitemap 的问题，半小时就能验证。先把便宜的可能性排掉，是我们给自己定的规矩。有个团队反过来做，先重写了 40 篇文档，最后发现是 CDN 把 Googlebot 的 IP 段拦了，白干三个月。",[11,70,71],{},"顺序照抄就行：GSC 索引报告看理由，日志看有没有请求，curl 看返回的 HTML，最后才看页面本身写得怎么样。",[11,73,74],{},"另外一句实话：日志里连一次请求都没有的页面，先别想收录，先想它凭什么被找到。",{"title":76,"searchDepth":77,"depth":77,"links":78},"",2,[79,80,81],{"id":17,"depth":77,"text":17},{"id":45,"depth":77,"text":45},{"id":65,"depth":77,"text":65},null,"技术SEO","2025-09-13","页面不收录，九成能在发现、抓取、渲染、索引这四步里定位到原因。我们按倒序排查，附每一环的查法，以及 2025 年 6 月一个 1200 页文档站只收录 300 页的复盘。",false,"md",{},true,"\u002Fblog\u002Fcrawler-discovery-to-index",{"title":5,"description":85},"blog\u002Fcrawler-discovery-to-index",[94,95,96],"抓取","索引","爬虫","ivhAhgnZHzoOzREp6Y8dTvg1LSFD5W2dXWwJsx_KeBA",{"id":99,"title":100,"author":6,"body":101,"canonical":82,"category":148,"cover":82,"date":149,"description":150,"draft":86,"extension":87,"keywords":82,"meta":151,"navigation":89,"noindex":86,"ogImage":82,"path":152,"seo":153,"seoDescription":82,"seoTitle":82,"stem":154,"tags":155,"updated":82,"__hash__":159},"blog\u002Fblog\u002Fgsc-average-position-misread.md","GSC 平均排名不能直接看，它会掩盖三个问题",{"type":8,"value":102,"toc":143},[103,106,110,113,116,119,122,125,128,131,134,137,140],[11,104,105],{},"GSC 的平均排名是所有查询按曝光加权出来的一个数，它不指向任何一个真实关键词的位置。2025 年 8 月我们把月报里这个指标删掉，换成排名分桶，客户第一次看懂流量为什么没涨。如果你还拿它当 KPI，先看下面三个坑。",[15,107,109],{"id":108},"它是加权平均不是中位数","它是加权平均，不是中位数",[11,111,112],{},"举个极端例子：10 个词里 9 个排第 2，1 个排第 80，平均排名算下来 9.8，看起来进了前十。真实的点击几乎全来自那 9 个词，第 80 名那个有没有，对流量没有影响。反过来，某个词从第 40 名掉到 100 名开外，它不再被计入报告，平均排名反而变好看。",[15,114,115],{"id":115},"三个被它掩盖的问题",[11,117,118],{},"第一，掉出前 100 的词会被剔除。GSC 只统计有曝光的查询，页面滑出 100 名之后曝光归零，直接从分母里消失。所以平均排名上升，经常意味着你丢了长尾。",[11,120,121],{},"第二，品牌词摊平了差距。我们服务的一个开发者工具站，品牌词曝光占全部曝光的四成，排第 1。把品牌词算进去，非品牌词排 30 名也显得体面。我的处理是在查询报告里用正则排除品牌词，导出后再算一次。",[11,123,124],{},"第三，新页面收录期的波动会被误读。新文章刚收录时排 60 名开外，把平均值拉低；过两周它爬到 20 名，平均值跟着翘起来，团队以为整站都在改善，实际只是几个新页面在爬坡。",[15,126,127],{"id":127},"我们改成看什么",[11,129,130],{},"排名分桶。1-3、4-10、11-20、21-50、50 以外五档，每周一固定看各档的词数变化。真正值得高兴的是 4-10 档词数在涨，那是最容易吃到点击的位置。11-20 档在涨但 4-10 档不动，说明内容够了、权重不够，要补内链和外链。",[11,132,133],{},"曝光与点击的比值。查询级导出，筛曝光涨、点击没涨的词，这些词通常卡在 8 到 15 名，标题和描述还有得改。",[11,135,136],{},"导出时注意，GSC 界面一次最多给 1000 行，想看全量得按日期切段，或者直接走 Search Console API，每天 2.5 万行的配额，一个小站够用。",[11,138,139],{},"有一类操作我明确反对：为了让这个数字好看，把明显排不动的长尾页面 noindex 掉，让平均值更接近前排。这是自欺欺人。你要的是点击，不是数字好看。真要设目标，设 4-10 档的词数、设非品牌词的自然点击，都比平均排名靠谱。",[11,141,142],{},"我的判断很简单：谁在月度汇报里拿平均排名从 22 升到 18 当主要成绩，基本是没看分层数据。这个指标适合判断趋势方向，不适合当效果证据。",{"title":76,"searchDepth":77,"depth":77,"links":144},[145,146,147],{"id":108,"depth":77,"text":109},{"id":115,"depth":77,"text":115},{"id":127,"depth":77,"text":127},"工具评测","2025-09-12","平均排名是按曝光加权摊平的一个数，涨了不代表流量涨。我们踩过这个坑之后，月报里改成排名分桶加查询级曝光，这篇文章写清楚怎么读才不会被它误导。",{},"\u002Fblog\u002Fgsc-average-position-misread",{"title":100,"description":150},"blog\u002Fgsc-average-position-misread",[156,157,158],"GSC","数据指标","排名监控","7Gmje2EhVaEgpzYuammbt_JsXkyFMFoZBk56nNRc7OI",{"id":161,"title":162,"author":6,"body":163,"canonical":82,"category":83,"cover":82,"date":263,"description":264,"draft":86,"extension":87,"keywords":82,"meta":265,"navigation":89,"noindex":86,"ogImage":82,"path":266,"seo":267,"seoDescription":82,"seoTitle":82,"stem":268,"tags":269,"updated":82,"__hash__":273},"blog\u002Fblog\u002Flcp-optimization-retrospective.md","官网首屏提速复盘：从四点六秒到一点九秒我们改了什么",{"type":8,"value":164,"toc":253},[165,168,171,175,178,181,185,188,192,203,207,210,214,221,225,232,235,238,241,244,247,250],[11,166,167],{},"今年 8 月我们接手一个 SaaS 官网的性能整改，移动端 LCP 4.6 秒，六周后稳定在 1.9 秒。中间没有换服务器，也没有重写前端。六件事按性价比排下来，顺序比技术选择更重要。",[11,169,170],{},"这个站的情况挺典型：Next.js 做的营销站，首屏传输 2.8MB，42 个请求，第三方脚本 9 个。老板的原话是\"我们的页面怎么这么慢\"，但没人知道慢在哪。我们先跑了一轮真实的移动端测试，不是本地开 DevTools 看，而是用 4G 模拟加 CPU 4 倍降速。",[15,172,174],{"id":173},"第一件首屏传输从-28mb-压到-740kb","第一件：首屏传输从 2.8MB 压到 740KB",[11,176,177],{},"图片占 1.6MB。hero 图、六张客户 logo、一张 dashboard 截图，全是 PNG。换成 WebP，按容器尺寸出 2 倍图，logo 改 SVG。这一步单独把 LCP 从 4.6 秒带到 3.2 秒。",[11,179,180],{},"顺带一个细节：他们 logo 墙用了六张 400×400 的 PNG，实际渲染 32×32。这种浪费在软件站特别多，客户 logo 是市场部从 PPT 里导出来直接上传的。",[15,182,184],{"id":183},"第二件砍掉三个阻塞渲染的请求","第二件：砍掉三个阻塞渲染的请求",[11,186,187],{},"头部有一个字体 CSS、一个图标库 CSS、一个没用上的组件库样式，合计 210KB，全是同步加载。字体改自托管加 preload，图标库换成内联 SVG 只留用到的 14 个，组件库样式按需引入。LCP 到 2.7 秒。",[15,189,191],{"id":190},"第三件中文字体换子集","第三件：中文字体换子集",[11,193,194,195,198,199,202],{},"他们的中文主字体是 3.4MB 的思源黑体全量包，",[53,196,197],{},"font-display"," 没设。改成常用 3500 字的子集，280KB，",[53,200,201],{},"font-display: swap","。中文软件站这一步几乎必做，代价小，收益稳定。",[15,204,206],{"id":205},"第四件第三方脚本全部延后","第四件：第三方脚本全部延后",[11,208,209],{},"9 个第三方里，客服组件、两个统计、一个 AB 测试、一个热力图，首屏一个都不需要。改成用户首次交互后再加载，首屏请求从 42 降到 19。LCP 到 2.1 秒。",[15,211,213],{"id":212},"第五件给首屏图提优先级","第五件：给首屏图提优先级",[11,215,216,217,220],{},"hero 图加 ",[53,218,219],{},"fetchpriority=\"high\"","，同时在 head 里 preload。这一步单独看收益最小，但在 2.1 秒的基数上，它挤出了最后的 0.2 秒。",[15,222,224],{"id":223},"第六件html-走边缘缓存","第六件：HTML 走边缘缓存",[11,226,227,228,231],{},"营销页内容一周改一次，没必要每次回源。在 CDN 上给首页和定价页设了 10 分钟缓存加 ",[53,229,230],{},"stale-while-revalidate","，TTFB 从 620 毫秒降到 140 毫秒。",[15,233,234],{"id":234},"顺序比技术重要",[11,236,237],{},"六件事如果倒过来做，先上 CDN 再优化图片，效果要差一半。我们判断顺序的标准很土：这一步能不能减少字节或者减少阻塞，能就优先。优先级调整和缓存策略属于锦上添花，放在最后。",[11,239,240],{},"还有个反常识的点：这个站做完 PSI 分数从 31 到 88，但自然流量第三周才开始动，第六周涨了 23%。速度是必要条件，不是充分条件，别指望改完性能排名第二天就往上走。",[15,242,243],{"id":243},"过程中踩的三个坑",[11,245,246],{},"第一个坑是 preload 加重复了。前端在 head 里加了 preload，组件里又自己加载一次，同一张图下载两遍，移动端多花了 400 毫秒。排查方法是在网络面板里按文件大小排序，看到同一 URL 出现两次就明白了。",[11,248,249],{},"第二个坑是缓存把改动盖住了。图片换完，CDN 上还是旧版本，测了两天都是 4.1 秒，差点以为方向错了。现在我们的规矩是每次改静态资源都带版本号或者刷新缓存。",[11,251,252],{},"第三个坑是只测了首页。首页做到 1.9 秒，客户很满意，结果产品页、文档页还在 5 秒以上。营销站真正的入口是产品页和文档，首页只占访问量的三成。这批页面后来单独做了一轮，又多花了两周。",{"title":76,"searchDepth":77,"depth":77,"links":254},[255,256,257,258,259,260,261,262],{"id":173,"depth":77,"text":174},{"id":183,"depth":77,"text":184},{"id":190,"depth":77,"text":191},{"id":205,"depth":77,"text":206},{"id":212,"depth":77,"text":213},{"id":223,"depth":77,"text":224},{"id":234,"depth":77,"text":234},{"id":243,"depth":77,"text":243},"2025-09-14","一个 Next.js 营销站移动端 LCP 4.6 秒，六周做到 1.9 秒，没换服务器没重写前端。六件事按性价比排序：图片、阻塞请求、字体子集、第三方脚本、首图优先级、边缘缓存。",{},"\u002Fblog\u002Flcp-optimization-retrospective",{"title":162,"description":264},"blog\u002Flcp-optimization-retrospective",[270,271,272],"LCP","性能复盘","移动端速度","gYDspv4w527tyyC7CnRBp8IUP7YrQDImAmaZXjafsgY",1794088112415]