# 保哥笔记 — WordPress SEO > 本分片含 16 篇文章,按发布日期倒序。全部分片索引见 https://zhangwenbao.com/llms-full.md **站点**:https://zhangwenbao.com/ **分类**:WordPress SEO **生成**:2026-06-04 23:09:29 CST --- ## Rank Math怎么设置对SEO最好?一个出海独立站的逐项取舍清单 - URL:https://zhangwenbao.com/rank-math-best-seo-settings.html - 分类:WordPress SEO - 发布:2026-05-28 | 更新:2026-05-28 - 摘要:Rank Math选项繁多,新手最常见的错不是配少了而是开太多,把作者归档、站内搜索页、空标签页全收录稀释了站点质量。本文以一个WooCommerce快时尚DTC站为样本,逐项讲清向导怎么选、sitemap收录什么、各类页面的index与noindex怎么定,给出一份照抄的开关取舍清单。 - 关键词:WordPress SEO,结构化数据,SEO插件,索引优化,Rank Math > **TLDR**:摘要:Rank Math的设置项多到能劝退人,但真正影响排名的就那十几个开关;剩下绝大多数,默认就是最优解,你越折腾越糟。更扎心的是,新手最爱花一下午去刷那个“内容100分”,而那恰恰是整套插件里对排名最没用的一项。这篇不带你逐个截图点一遍,而是把每个关键设置拆成“做什么、为什么、什么时候会坑你、边界在哪”,按一个WordPress + WooCommerce出海独立站的真实需求,告诉你哪些必开、哪些必关、哪些碰都别碰,配完一次稳用三年。 > 摘要:Rank Math的设置项多到能劝退人,但真正影响排名的就那十几个开关;剩下绝大多数,默认就是最优解,你越折腾越糟。更扎心的是,新手最爱花一下午去刷那个“内容100分”,而那恰恰是整套插件里对排名最没用的一项。这篇不带你逐个截图点一遍,而是把每个关键设置拆成“做什么、为什么、什么时候会坑你、边界在哪”,按一个WordPress + WooCommerce出海独立站的真实需求,告诉你哪些必开、哪些必关、哪些碰都别碰,配完一次稳用三年。 先说为什么值得专门写这篇。给WordPress站做谷歌SEO,装一个SEO插件几乎是绕不开的第一步,而Rank Math大概是目前免费版功能最全的一个——它的基础版,功能差不多顶得上Yoast的付费高级版,多关键词优化、内容分析、Schema结构化数据、自动生成XML站点地图全都带。和SEOPress比,它在规范化、站点地图生成、插件冲突、重定向这些地方更稳,踩雷概率低。 但功能全是把双刃剑:选项一多,新手就容易乱开一通,把本该默认的开关全打开,反而制造出一堆稀释权重的垃圾页。保哥这些年帮不少出海客户接手过别人配崩的Rank Math,十次有八次问题不在“没开够”,而在“开太多”。所以下面这套配置思路,核心不是“功能越全越好”,而是“该开的开、该关的狠狠关”。我们以一个做快时尚服装的DTC独立站(WordPress建站、WooCommerce管商品)为样本,一项一项过。 ## 为什么出海独立站值得花一下午把Rank Math配明白? 很多人装完插件随便点几下“下一步”就完事了,这是大忌。SEO插件的设置,本质是在替你决定“谷歌能看到你网站的哪些部分、以什么形式看到”。配错一个noindex开关,可能让你整个产品目录从搜索结果消失;配错一个站点地图选项,可能把一堆垃圾页推给谷歌抓取,稀释全站权重。这一下午,省不得。 在动手之前,先建立一个贯穿全文的判断标准,后面所有“开还是关”的纠结,都能用它一刀切: > 一个页面,有独立、丰富、不重复的价值,就让它被收录(index);否则一律noindex。 这句话听着简单,却是整套Rank Math配置的灵魂。WordPress天生会生成大量“技术性垃圾页”——空标签页、作者归档、日期归档、站内搜索结果页、分页……它们没有独立价值,却会被默认收录,在谷歌眼里就是一堆低质页,集体拉低你的站点质量信号。Rank Math的大半价值,就是帮你把这些页面精准地挡在收录之外。想清楚这条主线,你会发现下面的设置其实没那么乱。 还有一个心态要先摆正:别指望靠插件设置“做出排名”。Rank Math是帮你把技术地基铺平、不出硬伤,排名最终还是靠内容和权威。把它当成“防止自己犯错的护栏”,而不是“涨排名的魔法”,你的预期就对了。 ## 安装向导该怎么选,哪几步是新手最容易配错的? 装好启用后会进入设置向导(setup wizard)。第一个选择就有人栽:模式。 做什么:保持默认的Advanced(高级模式)就好,别选Custom。为什么:Advanced能控制更多SEO功能,正是我们想要的;Custom模式主要用于导入已有配置(省去重配),而且它依赖付费的Pro版才能发挥。坑在哪:新手以为Custom是“简单模式”,其实它是“迁移模式”,选错了反而少了一堆该有的选项。 接下来是“你的网站”这一屏,几个字段逐个说: - 网站类型:博客选personal blog,电商选small business site或webshop。我们这个服装站走WooCommerce,选webshop。 - Business Type:默认organization即可,除非你是个人IP站。 - 网站名称 / 副标题:如实填,这会进结构化数据,直接影响谷歌对你品牌实体的识别,别敷衍。 - 个人或组织名、Logo:填品牌名、传品牌Logo。Logo会进Organization结构化数据,对品牌在搜索结果里的呈现有用,务必上传。 - 社媒分享图标:可做可不做,默认即可。 再下来是Google Analytics连接。做什么:点Connect Google Service关联GA4账户,登录授权即可。边界:这一步不是必须当场做,可以先跳过、配完其他步骤再回来设。坑在哪:如果你GA4里还没创建数据流和事件,这里会连不上——得先去GA4把网站加好、数据流建好,再回来选对应的账户和媒体资源,否则Rank Math抓不到数据。新手常卡在“为什么连上了没数据”,十有八九是GA4那头没建好。 ## 站点地图(Sitemap)到底该收录哪些、排除哪些? 站点地图是你主动递给谷歌的“网站目录”,告诉它该来抓哪些页面。原则还是那句话:有价值的放进去,没价值的别放。 该打勾的:Sitemaps总开关、Include images(让图片也进站点地图,对图片搜索有用)、以及内容类型里的posts、pages、products。如果你做了商品分类目录(product categories)且每个目录页有像样的内容,也可以勾上public taxonomies。不该勾的:那些自动生成、内容稀薄的归档类。 这里有个出海站常见的纠结:商品标签(product tags)要不要进站点地图?判断标准:如果你的标签页只是几个商品的稀疏聚合、没有独立文案,别放——它就是典型的低质聚合页;如果你认真给热门标签页写了导购文案、做成了着陆页,那它有价值,可以放。一刀切的答案是没有的,回到“有没有独立价值”这把尺子量。 关于News Sitemap和Video Sitemap:前者只有你做新闻类内容才需要(填一个publication name,勾posts);后者只在你有视频内容时才勾。服装站一般用不上News,但如果你产品页嵌了大量穿搭视频,Video Sitemap值得开。 还有个容易被忽视的边界:谷歌对单个站点地图有50MB、5万条URL的上限,超了得分割。Rank Math有分割功能,建议设成每个文件最多500条URL——对中小出海站这个值完全够用,也方便你在Search Console里排查具体哪批URL出了抓取问题。 ## SEO Tweaks里那几个开关,哪些是必开、哪些是坑? 向导最后的Optimization(也就是SEO Tweaks)这一屏,几个开关分量很重,逐个拆: - Noindex empty category and tag archives(不收录空的分类页和标签页):必开。为什么:没有内容的聚合页被收录,纯属制造低质页稀释全站权重。这是“有价值才收录”原则的直接落地。 - Nofollow External Links(给外链自动加nofollow):谨慎开。做什么:它会给所有指向外部的链接自动加nofollow。坑在哪:一刀切全站nofollow,会让你给合作伙伴、友链、引用源的正常链接也都不传递权重,有时反而不利于建立你的外链画像。我的建议是别在这里全局开,而是到常规设置里用“Nofollow Exclude Domain”单独放行你信任的域名,精细控制。 - Open external links in new tab(外链新窗口打开):可开。降低跳出、延长停留,顺带Rank Math会自动加noopener、noreferrer属性,对安全也有好处。 这一屏配完,第一阶段向导就结束了。插件自动更新可开可不开——对生产站我一般关掉自动更新,手动在测试通过后再升,免得某次更新和主题打架导致前台出问题。这是个很多人忽略的稳定性边界:SEO插件直接影响meta输出,一旦更新出bug,影响的是全站收录。 ## Titles & Meta:哪些页面必须index,哪些必须noindex? 这是整套设置里最重要的一块,直接决定谷歌收录你哪些页面。逐类过一遍“该不该index”: 页面类型 | 怎么设 | 原因 | 首页(Homepage) | 必须index | 权重流入的核心入口,noindex等于自断主动脉,绝不能关 | 文章posts / 页面pages / 商品products | 必须index | 你真正想被搜到的内容主体 | 空分类页、空标签页 | noindex | 无内容的聚合页,收录只会稀释权重(有丰富内容的标签页例外) | 站内搜索结果页 | 必须noindex | WordPress会生成无数 /?s=xxx页,放任收录等于制造无穷垃圾页,对SEO极其致命 | 作者归档页 | 单作者站noindex | 单人或小团队的作者页只是内容的重复聚合,纯属冗余 | 文章格式归档(Post Formats) | noindex | 99% 的站用不到,全是重复无价值页 | 日期归档 | noindex | 除非你是强时效新闻站,否则无价值 | 这里展开两个关键点。首先是 Post Type这一节,它最该认真对待:把有价值的类型(posts、products、pages)的Robots Meta全开index,其余自定义类型一律关。这是收录策略的总闸。 其次是分隔符(separator):全局标题分隔符推荐用短横 -、长破折号 — 或竖线 | 这类干净符号,别用花里胡哨的特殊字符,既不专业也可能在SERP里显示异常。 关于noindex到底何时真正生效、一个页面被设noindex后多久从谷歌结果里消失,这中间有个时间差和机制,我在noindex页面什么时候才会从谷歌搜索结果里消失 (https://zhangwenbao.com/when-does-noindex-page-remove-from-google-search-results.html)里讲得很细,配Rank Math前建议一并搞懂,免得设了noindex却以为没生效又乱改。 ## 索引膨胀是怎么把你网站权重稀释掉的——作者页、标签页、搜索页该怎么处理? 上一节列了清单,这一节讲清楚背后的“为什么”,因为这是出海站最普遍、也最隐蔽的病。 所谓索引膨胀(index bloat),就是谷歌收录了你大量本不该收录的低质页。WordPress + WooCommerce的组合尤其容易膨胀:每个商品标签、每个属性筛选、每个分页、每个搜索词,都可能生成一个独立URL。一个只有200个商品的服装站,放任不管,被收录的页面可能膨胀到几千个,其中绝大多数是空的或近乎重复的。 危害在哪:谷歌评估一个站点的整体质量时,看的是“被收录页面的平均成色”。当你几千个收录页里有80% 是垃圾,平均分被狠狠拉低,连带你那些真正优质的产品页、博客页也跟着受连累——这就是站点级质量信号被污染。这也是为什么很多人“优质内容没少写,排名却起不来”——不是好内容不够,是垃圾页太多把它们的成色稀释了。 对症下药,三类页面重点处理: - 站内搜索结果页:务必noindex(谷歌官方在阻止搜索收录的文档 (https://developers.google.com/search/docs/crawling-indexing/block-indexing)里也把它列为典型的该屏蔽页面)。这是垃圾页的头号来源,一个站可能凭空生成无穷个 /?s= 页。 - 作者归档:单作者站直接disable。除非你是多作者团队、且每个作者页有独立介绍和内容,否则一律关。 - 标签与分页:空标签页noindex;分页(page/2、page/3)如果出现意外noindex导致内容抓不全,去Misc Pages里检查noindex paginated pages的设置。 处理索引膨胀和处理重复内容常常要配合canonical标签一起做,二者解决的是相邻但不同的问题,具体怎么搭配,可以看Canonical URL规范化标签完整指南 (https://zhangwenbao.com/canonical-url-seo-guide.html)。把noindex和canonical这两件事理清,你的WooCommerce站就能甩掉一大半技术性低质页。 ## 重定向和404监控,怎么配才能既省心又不伤SEO? Rank Math的404监控和重定向模块,是出海站长期运营里最实用的两个功能,但也藏着坑。 404监控:建议开,模式选simple(简单记录),日志上限设100条,避免日志表无限膨胀拖慢数据库。为什么开:它帮你及时发现哪些页面挂了404——太多404会推高跳出、浪费抓取、影响用户体验。边界:对一些你明知无所谓的URL(带某些查询参数的),用exclude paths排除掉,别让日志被噪音塞满。 重定向类型是新手最容易用错的地方,一张表说清: 类型 | 什么时候用 | 关键提醒 | 301永久重定向 | 绝大多数场景:页面永久换了新地址 | 权重几乎100% 转移到新URL,改链接、合并内容首选 | 302临时重定向 | 仅临时替换页面(如短期活动页) | 长期用302是大坑——权重不转移,旧URL一直占着 | 307临时重定向 | 和302类似,实际极少用 | HTTP/1.1下的临时跳转,普通站用不上 | 410已删除 | 页面彻底作废、不再提供 | 明确告诉谷歌“这页永久没了”,比404更干脆,加速从索引移除 | 记住一句:除非你非常确定是临时的,否则永远用301。把临时跳转长期化,是我见过最常见的权重流失原因之一。另外,Rank Math有个“文章URL改动自动重定向”的开关,建议开——你改了文章slug,它会自动建一条301到新地址,省得你忘了手动设、白白丢掉旧链接的流量。 还有个埋得很深的坑要专门点名:常规设置里的 Strip Category Base(去掉链接里的 /category/ 部分)。新站可以开,让URL更干净;老站千万别开——一开,你所有已被收录的分类URL结构瞬间改变,会凭空产生大量404,严重影响既有排名。这个开关对老站是个不可逆的雷,碰之前先想清楚。 ## 面包屑、图片alt、Schema这些细节,哪些真影响排名哪些是锦上添花? 这一组是“锦上添花但别忽视”的设置,按性价比排个序。 图片alt(优先级最高):开“add missing alt attributes”,让Rank Math自动给缺失alt的图片补上。为什么重要:alt既是无障碍刚需,也是图片搜索的主要相关性信号,对服装这种强视觉品类尤其值钱——很多人是通过图片搜索找到穿搭灵感再点进来的。边界:自动补的alt是用文件名兜底,质量一般;更好的做法是上传图片时就手动写好alt,自动功能只当最后的安全网。 面包屑(Breadcrumbs):建议开,分隔符用 - 之类干净符号,首页标签设成品牌名或“Home”。边界:如果你已经用Elementor或主题自带功能做了面包屑,就别在Rank Math里重复开,否则页面上会出现两条面包屑。 Schema结构化数据:给文章默认选Article或Blog Post,给商品选Product;WooCommerce模块开了之后,会自动给商品加上Product结构化数据。关键边界:Schema不是越多越好。除了面包屑、文章、商品这些该有的,别什么类型都往上堆——堆一堆不相关的Schema不会加分,反而可能因为标记和页面实际内容不符被谷歌判为可疑。结构化数据该怎么按页面类型选、怎么避免乱标,可以参考Schema结构化数据是什么、类型与怎么做 (https://zhangwenbao.com/seo-schema-guide.html)。 ## Rank Math的那个100分,到底要不要追? 这是全文我最想替你省下时间的一节。Rank Math编辑文章时会给一个0到100的“内容SEO分”,很多人盯着它较劲,非把每一项凑到绿勾。我的直白结论是:这个分数对真实排名几乎没有直接影响,别为它耗时间。 它考核的那些项——URL带关键词、标题带关键词、标题带情绪词、图片alt带词、内外链各一条、关键词密度1% 左右、开头用主关键词、H2/H3带关键词、元描述带词、标题含数字……本质上是一套上一个时代的“关键词匹配”清单。而正如我在谷歌排名背后的数学 (https://zhangwenbao.com/google-ranking-math-foundations.html)那篇里讲过的,现代谷歌靠的是语义理解和学习排序,早不是数关键词出现了几次。你把这100分刷满,谷歌并不会因此多给你一分。 那它一无是处吗?也不是。把它当成一个“别漏掉基本动作”的提醒清单就好:它提醒你“这篇是不是忘了写元描述、是不是一张图都没配、是不是连个内链都没加”——这些是基本卫生,值得照着扫一遍。但一旦基本动作都做了,分数停在80还是冲到100,真没区别。把追那20分的时间,拿去多写200字真正解决用户问题的内容,回报高得多。 顺带提一句它的Content AI功能:对中文出海内容,实用性有限,我一般关掉,免得它给一堆不痛不痒的建议干扰判断。你要写出能打动北美服装买家的文案,靠的是对人群的理解,不是插件凑出来的关键词清单。 这背后其实是个更大的认知问题,得说透。Rank Math那套100分清单,本质是把“关键词在多少个位置出现过”量化成了分数——URL里有没有、H2里有没有、前10% 正文里有没有、alt里有没有。可现代谷歌的相关性判断早就从“词在不在”升级到了“语义对不对”。换句话说,这套评分衡量的是上一代搜索引擎在乎的东西,而你优化的对象是这一代搜索引擎。用旧地图找新大陆,越认真越走偏。我见过太多出海卖家,产品页为了凑绿勾把主关键词硬塞进每个小标题,读起来像机器人说话,分数100,转化稀烂——因为真正会掏钱的买家,被那股浓浓的“为搜索引擎而写”的味道劝退了。 那对一篇出海产品页或博客,真正值得花时间的“基本动作”是哪几条?我给个排序:第一,标题和首段让人想读下去(影响点击和停留,这是真信号);第二,内容真的回答了用户搜这个词时的疑问(影响相关性和满意度);第三,配图清晰、alt写得像句人话而非关键词串;第四,该有的内链外链自然地给到。这四条做到了,Rank Math给你打75还是95都无所谓——你优化的是用户和现代算法,不是那个停留在关键词时代的进度条。把它当仪表盘扫一眼即可,千万别当成方向盘。 ## robots.txt、.htaccess、搜索意图这些“常规设置”里,还有哪些值得动? 常规设置里还埋着几个被新手忽略、其实挺关键的开关,挨个说清。 robots.txt:保持默认通常就够,Rank Math会给一份基础规则。如果要自定义,原则是只屏蔽真正无意义的路径(后台、feed、评论feed),并把站点地图地址写进去方便谷歌发现。这里有个高频误区:很多人想用robots.txt来“阻止某个页面被收录”,但robots.txt只管“能不能抓”,不管“能不能收录”——被robots拦住的页面,谷歌反而读不到你设的noindex,有时还会以无摘要的形式收录。要彻底不收录,用noindex,而不是robots.txt屏蔽。这两件事的分工,配的时候一定要分清。 .htaccess:除非你非常清楚自己在改什么,否则一律别动,保持默认。这个文件直接控制服务器层的重写和跳转,一个语法错误就可能让全站500。需要做重定向,用Rank Math的重定向模块就够了,犯不着去碰 .htaccess。 Enable Search Intent(搜索意图):建议开。开了之后,你在文章里填入焦点关键词,它会提示这个词对应的搜索意图类型(信息型、商业型、导航型、交易型),以及你的内容跟意图匹配不匹配。对出海内容很有用——很多人写跑题,根子就在没分清用户搜这个词到底是想了解还是想买。意图错了,相关性做得再足也是白搭。 面包屑的细节:前面提过建议开,这里补两个容易忽略的点。一是首页标签(Homepage Label)别用默认的英文Home,对出海站可以用品牌名,让面包屑本身也成为一个轻量的品牌曝光位;二是有个“隐藏分类名”的选项,如果你的站是以页面聚合为主、分类层级意义不大,可以打开让面包屑更简洁。面包屑还会自动生成BreadcrumbList结构化数据,在SERP里把URL显示成清晰的路径,对点击率有正面作用。 图片设置的边界:自动补alt、title建议开,但“自动补caption(图注)”和“自动补description(描述)”通常别开——caption会显示在前台、影响版面美观,description大多用不上。最理想的做法仍然是上传图片时就手写alt,自动功能只当兜底。对服装这种重图片的站,alt写得好不好,直接关系到你能不能吃到图片搜索那波流量。 ## SEO分析器和状态工具,平时该怎么用? Rank Math还带了两个偏“运维”的模块,平时不用天天看,但关键时刻能救命。 SEO Analyzer(SEO分析器):它会扫描全站、列出技术问题清单,每个问题旁边有“how to fix”。新站上线、或者接手一个别人留下的烂摊子时,先跑一遍,能快速暴露缺失的基础项(没有站点地图、缺meta、有死链等)。但它的建议偏通用、偏保守,看到分数低别慌——它只是个体检报告,不是判决书,挑真正影响收录和体验的问题修就好,那些“标题最好含数字”之类的提示可以无视。 Status & Tools(状态与工具):这里最有用的是Database Tools那几个清理按钮。当你发现Analytics数据不对、404日志乱、或者SEO分析数据明显过时,对应地点一下Purge Analytics Cache、Clear 404 Log、Flush SEO Analyzer Data就能强制刷新。这些是“数据看着不对劲时”的急救工具,平时不用碰。 还有 Social Meta和Local SEO 两块:前者填上品牌的社交账号URL,能让分享到社媒时的预览图、标题更可控,顺带给品牌实体补一组sameAs信号,值得花十分钟填好;后者只有你真有实体门店或营业地址才需要,纯线上的DTC服装站直接跳过,填了反而是噪音。 ## 哪些功能模块该开、哪些该关——一张出海站的取舍清单 最后回到Rank Math仪表盘的模块开关,给一张可以直接照抄的取舍清单(以WooCommerce服装站为例): 建议开: - 404 Monitor + Redirections:长期运营必备,前面讲过。 - Analytics:把Search Console和GA数据接进后台,方便随手看(但记住它和GA数据不会100% 一致,甚至偶尔不同步,以官方后台为准)。 - Image SEO:自动补alt和caption,服装站强烈建议开。 - Instant Indexing:能主动把新页面URL推给谷歌加速收录,新站尤其有用。 - Link Counter:统计内外链数量、给内链建议,辅助你织内链网。 - Sitemap + Schema:核心功能,必开。 - WooCommerce:用Woo管商品的一定要开,它自动给商品加Product结构化数据。 - Local SEO:仅当你有实体门店、营业地址时才开,纯线上DTC用不上。 建议关: - Content AI:对中文内容用处不大,关掉省心。 - AMP / Podcast:除非你确实做这两类内容,否则别开,徒增复杂度。 最后一个边界,也是个反直觉的建议:如果你发现Rank Math功能多到你根本用不上、还拖慢了网站,大方换成Yoast也完全没问题。Yoast更轻、速度更快,基础功能一样不缺。工具是为目标服务的,别为了用全功能而用全功能。一个出海站的SEO成败,从来不取决于你用哪个插件,而取决于你有没有想清楚“哪些页面值得被收录、你的内容凭什么被搜到”——这两个问题,任何插件都替你回答不了。 ## 常见问题解答 配置Rank Math时几个最高频的疑问,集中答一下。 Rank Math和Yoast到底该选哪个?免费版功能比Yoast全,规范化、站点地图、重定向也更稳,适合愿意细配的人。但如果你嫌它选项太多、还拖慢网站,换更轻的Yoast完全没问题,基础功能一样不缺。工具服务目标,别为用全功能而用全功能。 那个内容SEO 100分必须刷满吗?不必。它本质是上个时代的关键词匹配清单,对真实排名几乎没有直接影响。把它当成别漏掉基本动作的提醒就好——元描述、配图、内链有没有做。基本动作做完,80分和100分没区别,省下的时间多写内容更值。 提交收录时提示noindex怎么办?先单独提交那个页面看能否收录。Rank Math默认会把cart、my account等无用页设成noindex,整站提交时就可能弹这个提示。若是这类页面,属正常,不用管;若是内容页被误标,再去查它的单页设置。 某个内容页一直显示noindex标记,怎么排查?三步:一看该页是否被单独设了noindex;二查源代码或F12看meta robots是否真有noindex;三是临时禁用Rank Math再测,确认根源是不是出在插件设置上。库存为0的商品也可能被自动标noindex。 分页page/2被noindex了影响大吗?如果它导致系列内容或商品列表抓不全,就要处理。去Titles & Meta的Misc Pages,关掉noindex subpages和noindex paginated single pages即可。但若分页本就无独立价值,保持noindex反而更干净。 Strip Category Base这个开关能随便开吗?新站可以开,URL更干净;老站千万别开。一开,所有已收录的分类URL结构瞬间改变,凭空产生大量404,严重影响既有排名。这是对老站不可逆的雷,碰之前务必想清楚。 404监控和重定向有必要一直开着吗?建议开。404监控用simple模式、日志上限设100条,帮你及时发现挂掉的页面;重定向默认用301,改了文章slug时自动跳转到新地址,避免旧链接流量白白流失。两者是长期运营的省心工具。 ## 权威参考资料 ## WordPress怎么做SEO?从主机、插件到Core Web Vitals - URL:https://zhangwenbao.com/wordpress-seo-guide.html - 分类:WordPress SEO - 发布:2026-05-20 | 更新:2026-06-01 - 摘要:从WP是否适合你、主机主题选型、Yoast/Rank Math插件对比、永久连结、缓存CDN到Schema与Core Web Vitals,一篇讲透WordPress SEO的全清单与落地路径。 - 关键词:WordPress SEO,Core Web Vitals,Yoast SEO,Rank Math,WordPress优化 > **TLDR**:摘要:WordPress占全球网站超过40%,但同样跑着WP的站,SEO自然流量差距能拉到十倍以上。差距不在写文章这一段,而在主机选型、主题瘦身、SEO插件配置、永久连结结构、缓存与CDN、图片优化、Schema、Core Web Vitals这八件底层基础设施上。保哥用这篇文章给一份完整的WP SEO动作清单、Yoast和Rank Math与AIOSEO三大插件的对照决策表,再配一份出海手工皮具配饰DTC独立站12周把自然流量从月800做到月2万8的真实SOP,看完就能照着改。 > 摘要:WordPress占全球网站超过40% (https://wordpress.org/plugins/wordpress-seo/),但同样跑着WP的站,SEO自然流量差距能拉到十倍以上。差距不在写文章这一段,而在主机选型、主题瘦身、SEO插件配置、永久连结结构、缓存与CDN、图片优化、Schema、Core Web Vitals这八件底层基础设施上。保哥用这篇文章给一份完整的WP SEO动作清单、Yoast (https://yoast.com/wordpress-seo/)和Rank Math与AIOSEO三大插件的对照决策表,再配一份出海手工皮具配饰DTC独立站12周把自然流量从月800做到月2万8的真实SOP,看完就能照着改。 有人把WordPress当成一键搭起来就能跑的傻瓜建站工具,也有团队把WP当成只要装够插件就一定打不过Shopify的笨重老古董。两种判断都是只看了表面。WP本身是一个对SEO非常友好的内容管理底座,能不能跑出好成绩,取决于在地基这一层有没有做对决策。 ## WordPress真的适合做SEO吗?谁该用谁不该用? 这个问题的答案不是简单的"适合"或"不适合",而是看你的内容形态、团队配置、预算结构和长期定位。先把适合用WP的几种典型场景列清楚。 第一类是内容型站点,比如行业媒体、技术博客、垂直社区、个人品牌站、知识库。这类站每周或每天都要发新文章,文章是流量入口的主力。WP的文章编辑器、分类标签体系、永久连结自定义能力、SEO插件深度、Schema自由度 (https://sitekit.withgoogle.com/)对这类站全面占优。第二类是中型出海独立站(SKU几百到几千),尤其是产品介绍重内容、客户决策周期长、靠SEO拉新比靠付费广告便宜的品类——比如手工皮具、户外装备、专业摄影器材、家具、保健品、宠物用品等等。这类站可以走WP+WooCommerce组合,把WP的内容优势和电商功能合二为一。第三类是B2B官网+博客组合,公司主站+案例库+技术博客这种组合,WP的可控性比任何SaaS建站都高一截。 不适合用WP的场景同样要看清。第一类是几万SKU以上的大型电商,WooCommerce的数据库性能撑不住、维护成本极高,这种规模应该走Shopify Plus或自建电商系统。第二类是高度交互的SaaS产品官网,前端是React或Vue写的复杂应用,WP的模板系统反而是束缚,更适合用Webflow或Next.js。第三类是只有几个静态营销页面、不打算长期沉淀内容的快销项目,这种WP是杀鸡用牛刀,Webflow或Framer够用了。 下面这张表把几个主流建站平台横向对比一下,方便快速判断自己这个项目应该选什么。 对比维度 | WordPress | Shopify | Webflow | Wix | SEO自由度 | 极高 | 中 | 高 | 中 | 内容沉淀能力 | 极强 | 弱 | 中 | 中 | 电商SKU上限 | WooCommerce几千 | 无上限 | 不适合电商 | 几百以内 | Schema控制力 | 插件可控全部 | 主题模板内置 | 需手写 | 有限 | 多语言支持 | WPML/Polylang/Translatepress | 原生多店或Markets | 原生支持 | 原生支持 | 维护成本 | 需要懂技术 | 低 | 低 | 极低 | 速度优化天花板 | 取决于主机和优化 | 由Shopify控 | 静态CDN快 | 由Wix控 | 典型适用 | 内容站、中型电商、B2B | 电商为主 | 营销页、品牌站 | 新手快速建站 | 这张表最容易被忽略的是"内容沉淀能力"这一栏。SEO是十年累积的生意,今天写的文章三年后还要为你引流。WP的archive机制、分类标签体系、永久连结结构、内容版本管理都是为长期沉淀设计的;Shopify的Blog功能更像营销附件,长期内容站点在Shopify上跑会越来越别扭。 ## 主机、主题、HTTPS三件事怎么选才不踩坑? WP站速度和稳定性的天花板,在主机、主题、HTTPS这三个地基决策上就被锁死了一大半。这三件事如果一开始没选对,后面装再多缓存插件、做再多优化都是堵漏式打补丁。 先说主机。WP主机大致分四个档:第一档共享主机(年费几十到几百),多个站挤一台服务器,性能完全不可控,只适合个人博客试水。第二档VPS(年费几百到几千),独立资源、有完整root权限,需要自己懂Linux和Nginx,性价比最高但有技术门槛。第三档托管型WP主机(年费一千到几千美元,比如Kinsta、WP Engine、SiteGround、RunCloud),主机商负责服务器层运维、自动备份、缓存配置,价格贵但省心,适合不想折腾后端的内容团队。第四档企业级(年费几千美元以上),多区域CDN、专属技术支持,给大流量站用。 选主机的硬指标不是CPU或内存数字,而是这几条:服务器物理位置是否在你目标用户的地理范围内(出海站绝对不能用国内主机,目标欧美就选美西或欧洲机房)、是否原生支持HTTP/2和HTTP/3、PHP版本是否在8.1以上、MySQL或MariaDB是否支持InnoDB、是否有内置对象缓存(Redis或Memcached)、是否提供免费SSL证书自动续签。 再说主题。WP主题分两类:通用框架型(Astra、GeneratePress、Kadence、Blocksy这种),轻量、可配置度高、对Page Builder兼容;功能型(Avada、Newspaper这种),自带海量预设和复杂功能,体积大、加载慢。选主题的硬指标是出厂状态下首页TTFB和LCP有多快——直接在Demo站上跑PageSpeed Insights,开箱TTFB超过800毫秒或LCP超过2.5秒的主题,无论功能多漂亮都不要用。轻量框架主题加上一个像样的Page Builder(Bricks、Breakdance或者原生Gutenberg)能覆盖绝大多数内容站和电商站需求。 HTTPS这一块在2026年已经没什么可讨论的空间——必须用、必须全站、必须确保所有内链和资源加载都是HTTPS协议、必须强制301跳转把HTTP流量转到HTTPS。Let's Encrypt的免费证书足够大多数站用,托管型主机商通常会自动配。需要手工做的是上线前用Why No Padlock工具或Browser DevTools的Security面板检查"Mixed Content"问题——HTTPS页面里如果还嵌着HTTP协议的图片、脚本或iframe,浏览器会标黄甚至直接阻断加载,对SEO和用户信任都是减分项。 地基项 | 新站推荐 | 性能下限 | 预算下限 | 常见误区 | 主机 | SiteGround、Kinsta、RunCloud VPS | TTFB低于500ms | 年600元 | 用国内主机做出海站、共享主机扛流量 | 主题 | Astra、GeneratePress、Kadence、Blocksy | 开箱LCP低于2.5秒 | 免费或一次买断$59 | 选功能型大主题装一堆用不上的Demo | HTTPS | Let's Encrypt自动续签 | A级SSL Labs评分 | 免费 | 没强制301跳转、混合内容没排查 | PHP版本 | 8.2或8.3 | 不低于8.1 | 主机包含 | 停留在7.4或更低拖性能 | 对象缓存 | Redis或Memcached | 命中率超过80% | 主机包含或自建 | 没开对象缓存导致数据库被读爆 | 这张表里的预算下限是按出海独立站规划,国内站可以减半。但有一点要反复强调——主机能省的钱在SEO损失面前都不值得省。一年600的主机和一年6000的主机看起来差10倍,但服务器响应慢200毫秒可能让自然流量少30%,差价分分钟被填掉。如果想看托管型WP主机有什么暗坑,可以参考托管WordPress悄悄拦了AI爬虫,你在AI答案里消失了 (https://zhangwenbao.com/managed-wordpress-blocks-ai-crawlers-citation-loss.html)这篇老文,里头说的是托管商默认拦截AI爬虫导致站点从AI答案里消失的真实坑。 ## SEO插件Yoast vs Rank Math vs All in One SEO该选哪个? WP生态里SEO主控插件主要就这三家:Yoast SEO、Rank Math、All in One SEO(AIOSEO)。三家都有免费版和付费版,免费版基本能覆盖中小站需求,付费版加的是高级功能。选哪个不是"哪家最好",而是"哪家最贴合你的使用习惯和预算"。 Yoast SEO是老牌选手,2008年上线,全球安装量超过千万。优点是稳定、文档完善、社区资源多,几乎所有SEO教程都用Yoast举例。缺点是免费版功能在2018年后被明显阉割(Focus Keyword限制一个、Schema自由度有限、Redirection需要Premium),付费版年费99美元起,对小站不算便宜。适用场景:已经用了多年的老站(迁移成本太高)、需要企业级支持的大型站(Yoast SEO Enterprise版有专属客服)、团队成员习惯Yoast的用户。 Rank Math是新势力,2018年发布,截至2026年安装量超过200万。优点是免费版功能比Yoast Premium还多——多关键字优化、内置Schema Generator、Redirection、404监控、Google Analytics集成、Sitemap高级控制全都免费给。付费版(Pro年费89美元)加的是高级Schema类型、自动建议关键字、视频站特殊功能。适用场景:新站(直接用Rank Math免费版)、预算紧的小团队、Schema需求复杂的内容站。 AIOSEO是第三家,定位是"门外汉也能上手",UI最简洁、配置项数量最少。功能介于Yoast免费版和Rank Math之间,付费版年费49美元起。适用场景:完全没有SEO经验、不想看复杂配置面板的小博客主、企业站老板想自己改自己写。 对比项 | Yoast SEO | Rank Math | AIOSEO | 免费版关键字数量 | 1个 | 5个 | 1个 | Schema类型(免费) | 5类 | 15类以上 | 10类 | Redirection管理(免费) | 需Premium | 免费内置 | 免费内置 | 404监控(免费) | 需Premium | 免费内置 | 需付费 | Sitemap控制力 | 基础 | 细粒度 | 基础 | Google Analytics集成 | 需Premium | 免费内置 | 需付费 | 付费版年费 | 美元99起 | 美元89起 | 美元49起 | 稳定性 | 极稳 | 稳 | 稳 | 学习曲线 | 中 | 中(功能多) | 低 | 团队推荐档 | 老站、企业级 | 新站、预算紧 | 新手、纯小白 | 实际建议:2026年新建的WP站,没有特别理由的话直接选Rank Math免费版,等到真的需要它的Pro功能(多Schema类型、高级Sitemap)时再升级。老站如果已经用Yoast多年、数据沉淀深、团队习惯了,没必要硬切——切插件的迁移工作量并不小,得迁元数据、迁Redirect表、迁Schema、迁Focus Keyword,一旦哪一步出错就是数据丢失。 插件切换之外,几个共通的SEO主控插件配置原则值得反复强调。第一,Title模板要前置关键字。商品页用"产品名称 - 品牌名"、文章页用"标题 - 站名",不要反过来。第二,Description字段宁可留空让Google自己抽取,也不要写堆砌关键字的废话——Google早就能识别并惩罚这类Description。第三,Focus Keyword不要选搜索量最大的那个,要选搜索意图最匹配你这一页内容的——意图不匹配再大量也是无效流量。第四,所有产品页和文章页都要确认canonical URL指向自己、不要漂移到别人或漂移到带追踪参数的版本。 ## 永久连结结构应该怎么设? 永久连结(Permalink)结构是WP站SEO地基里最容易被新手选错、改起来又最贵的一项。WP后台"设置-永久连结"里给的几个选项里,绝大多数情况下唯一应该选的是"文章名称"(/%postname%/)。 来对比一下几种结构的差异。默认结构是example.com/?p=123,问号加数字的形式既不含关键字也不可读,SEO上完全劣势。日期和名称结构是example.com/2026/05/20/article-name,看着规整但有两个问题:URL太长、把过时的日期写进URL导致几年后看着旧。月份和名称结构同理。数字结构是example.com/archives/123,比默认稍微好但仍不含关键字。文章名称结构是example.com/article-name,简洁、含关键字、对用户和爬虫都最友好。自定义结构允许你用模板(/category/postname/这种),但加一层分类前缀会让URL变长、当文章换分类时URL也跟着变(除非加301重定向)。 永久连结结构 | 示例 | 含关键字 | URL长度 | 更换分类影响 | SEO评分 | 默认 | ?p=123 | 否 | 极短 | 无 | 差 | 日期和名称 | 2026/05/20/article-name | 是 | 长 | 无 | 中 | 月份和名称 | 2026/05/article-name | 是 | 较长 | 无 | 中 | 数字 | archives/123 | 否 | 短 | 无 | 差 | 文章名称 | article-name | 是 | 最短 | 无 | 最佳 | 分类和名称 | category/article-name | 是 | 较长 | 需301重定向 | 较好但有维护成本 | 新站直接用文章名称结构是无脑选项。已经用了别的结构的老站想换,要评估迁移成本:先用Screaming Frog爬完整站URL、和新结构对照生成301映射表、在Nginx或.htaccess或SEO插件的Redirection模块里批量录入、上线后用GSC的"覆盖率"报告盯三个月观察索引迁移进度。如果旧URL有可观的反向链接和现有排名,301切换期间会有2到6周的排名波动,这是正常的。 除了永久连结主结构,还有几条细节要注意。Slug(文章代称)要英文、小写、用连字符分隔单词,不要用空格、不要用特殊字符、不要用中文URL。Slug长度控制在5个英文单词以内,太长的Slug既影响美观也可能被搜索引擎截断显示。文章发布后Slug尽量不再改,必须改的话务必同步做301重定向。中文站点用拼音Slug也是可接受方案,但要团队内部约定拼音规范(要不要带声调、连字符还是下划线、缩写不缩写)。 ## 缓存与CDN怎么配才能不和SEO打架? WP是PHP+MySQL驱动的动态站,每次有访问者请求页面都要执行一遍PHP、查一遍数据库、再渲染输出HTML,性能开销不小。缓存和CDN就是把这个过程的输出冻成静态HTML并就近分发,让大多数访问根本不触发PHP。配好了能让TTFB从1秒压到100毫秒以内,配错了能让搜索引擎拿到过时的HTML、链接404、Robots.txt错版本。 WP缓存按层级分四层。第一层是浏览器缓存,对静态资源(CSS、JS、图片)通过HTTP响应头Cache-Control设置长TTL,让访问者第二次访问时复用本地缓存。第二层是页面缓存,把渲染完的整页HTML缓存起来,下次访问直接吐HTML不再走PHP。第三层是对象缓存,把数据库查询结果、API响应缓存在内存里,Redis或Memcached托管。第四层是OPcache,PHP字节码层面的缓存。这四层叠起来才是完整的缓存方案。 主流缓存插件有三家。WP-Rocket(年费59美元起)功能最齐全,UI最简洁,自动处理大部分配置;LiteSpeed Cache免费但只有LiteSpeed或OpenLiteSpeed服务器才能用全功能;W3 Total Cache和WP Super Cache是经典老选项,免费、灵活、但配置项多、学习曲线陡。 CDN层面,主流选项是Cloudflare(有免费版)、BunnyCDN、KeyCDN、AWS CloudFront等。Cloudflare免费版对中小站够用,付费版加WAF、Argo Smart Routing、Image Optimization这些进阶功能。对中国大陆访问者要兼顾的话,可能要考虑加阿里云CDN或腾讯云CDN做混合分发。 缓存层 | 插件或工具 | 对SEO关键点 | 常见翻车 | 浏览器缓存 | 主机商Nginx配Cache-Control头 | HTML设置短TTL避免缓存陈旧 | HTML缓存太长导致更新延迟 | 页面缓存 | WP-Rocket、LiteSpeed Cache | 登录用户、cart、Search结果排除 | 误缓存购物车页面跨用户串档 | 对象缓存 | Redis Object Cache插件 | 命中率监控、定期清空 | 没启用导致数据库读爆 | OPcache | PHP内置 | 主机商已开 | 共享主机OPcache被关 | CDN | Cloudflare、BunnyCDN | 静态资源全走CDN,HTML按需 | 把所有HTML都缓存到边缘导致更新滞后 | 缓存和SEO最常见的冲突是HTML缓存TTL设得太长。新文章发布或老文章重写后,搜索引擎来抓的时候拿到的还是旧版本,导致noindex、canonical、Schema改了也不生效。正确做法是让HTML的Cache-Control设较短(5到10分钟),静态资源设长(一年),CMS层面发文章或改文章时主动触发CDN purge把对应URL的缓存清掉。Cloudflare、BunnyCDN都有API可以做这件事,WP-Rocket、LiteSpeed Cache也都内置CDN purge集成。 另一个翻车点是搜索引擎和真实用户拿到不同HTML(cloaking)。这种事故通常发生在缓存配置里"对bot不走缓存、对真实用户走缓存"的逻辑写反,或者A/B测试工具给爬虫显示了变体内容。Google对cloaking的判罚很重,一旦被判定可能整站从SERP消失。规避办法是确保缓存层对Googlebot和真实用户一视同仁,A/B测试用Search Console的User-Agent白名单排除爬虫。 ## 图片优化WebP、lazy load、Alt文本怎么落地? 图片是大多数WP站最大的资源消耗项,也是Core Web Vitals里LCP指标的主要决定因素。优化图片三件事:格式转WebP或AVIF、按设备分发不同尺寸、首屏外的图片延迟加载。这三件事都做到位,LCP通常能从3到4秒压到1.5秒以内。 WebP格式比传统JPG压缩率高25%到35%、比PNG高更多,画质几乎无损失,所有现代浏览器都支持。AVIF是新一代格式,压缩率比WebP再高20%,但浏览器支持率2026年才刚过90%。建议做法是WebP做主力、AVIF做渐进增强(用picture元素优先AVIF、回退WebP、再回退JPG/PNG)。WP生态里做图片转WebP的主流插件有ShortPixel、Imagify、EWWW Image Optimizer,三家都有免费额度,付费版按图片张数月费几十到几百元。 按设备分发不同尺寸是通过srcset属性实现。WP默认会为每张上传的图片生成多个尺寸(thumbnail、medium、large、原图),主题模板调用the_post_thumbnail时自动输出srcset让浏览器选最合适的。要做的事是确认主题确实用了srcset、确认尺寸覆盖了主流设备宽度、首屏图片用fetchpriority="high"提示浏览器优先加载。 Lazy load(延迟加载)是首屏之外的图片在用户滚动到附近时才开始加载。WP 5.5以后原生支持loading="lazy"属性,绝大多数主题已经自动加。要确认的是首屏图片绝对不能加lazy——LCP指标专门看首屏最大图片的加载时间,加了lazy反而拖慢LCP。 Alt文本是图片的SEO命脉,决定图片能不能在Google Images里被搜到、能不能给文章带额外的语义信息。Alt写作三条原则:第一,描述图片实际内容不堆砌关键字(不要写"WordPress SEO WordPress SEO插件"这种)。第二,自然语言通顺,长度控制在10到20个英文单词或20到30个中文字。第三,装饰性图片(背景、间隔图、图标)alt写空字符串alt=""告诉爬虫"这是装饰图无需理会"。 优化项 | 插件或工具 | 预期收益 | 翻车点 | WebP转换 | ShortPixel、Imagify、EWWW | 体积减30% | 没回退JPG导致老浏览器看不到 | AVIF渐进增强 | ShortPixel付费版、自定义代码 | 再减20% | 转换时间长占用服务器 | srcset多尺寸 | WP原生+主题正确调用 | 移动端流量节约 | 主题硬编码尺寸不用srcset | Lazy load | WP原生loading=lazy | 首屏TTFB提升 | 首屏图片误加lazy拖LCP | fetchpriority | 首屏图片手动加 | LCP提升20% | 所有图片都加导致优先级失效 | Alt文本 | 编辑器手工填、AI批量生成 | Google Images流量+无障碍 | 堆砌关键字被算法降权 | 批量补Alt文本是老站迁WP做SEO最先该做的事之一。一个5年老站经常有几千张图片alt为空,用Bulk Image Alt Text插件或自己写脚本批量补一遍,Google Images流量通常2到3个月就能涨上来。AI批量生成Alt是2025年后兴起的方案,Rank Math Pro、ShortPixel都内置了AI生成功能,质量普遍可用,但产品图建议人工再过一遍。 ## Schema结构化数据在WP站怎么实现? Schema结构化数据是用JSON-LD格式向搜索引擎清晰描述页面内容的元信息——这一页是文章还是产品、作者是谁、评分多少、价格多少、什么时候发布。Schema做对了能拿到富媒体搜索结果(Rich Results),CTR提升20%到50%是常见区间。做错了或者乱用可能触发Manual Action(人工降权)。 WP站上做Schema主流路径有三条。第一条用SEO主控插件自带的Schema模块。Rank Math免费版的Schema Generator能配置Article、Product、Recipe、Course、Job Posting、FAQ、HowTo、Review等15类以上,UI是拖拽式不写代码。Yoast免费版只有基础Article和Organization,Yoast SEO Premium加几类但仍少于Rank Math免费版。AIOSEO居中。第二条用独立Schema插件。Schema Pro、WPSSO Core是两家专业Schema插件,覆盖类型比SEO主控插件更全,可以做Job Posting的baseSalary细节、Event的eventStatus、Movie的Actor列表这种深度配置。第三条手写JSON-LD注入。对Rank Math、Yoast不支持的特殊类型(比如DataCatalog、SoftwareApplication的subjectOf、aboutPage的about),写一段JSON-LD直接通过wp_head钩子注入。技术门槛最高但灵活度最高。 对中小内容站,Rank Math免费版的Schema Generator够用且省事。下面这张表列WP站最常用的几类Schema和实施路径。 Schema类型 | 典型场景 | 推荐实施方式 | 富媒体收益 | Article | 所有博客文章 | Rank Math自动 | SERP显示作者、发布日期 | Product | 电商商品页 | WooCommerce原生+Rank Math | 价格、评分、库存显示 | FAQPage | 带FAQ段的内容页 | Rank Math FAQ块或手写 | SERP折叠FAQ展开 | HowTo | 步骤型教程 | Rank Math HowTo块 | SERP步骤分步显示 | Recipe | 食谱内容 | WP Recipe Maker或Rank Math | SERP食谱卡片 | Event | 活动信息页 | The Events Calendar+Schema插件 | SERP活动卡片 | JobPosting | 招聘页 | WP Job Manager+Schema | Google for Jobs收录 | Review | 测评文章 | Rank Math Review块 | SERP星级评分 | Organization | About页、Footer | Yoast或Rank Math全局 | Knowledge Panel基础 | BreadcrumbList | 所有内页 | Rank Math自动 | SERP面包屑替代URL | Schema最容易翻车的两件事:第一,标注了页面上不存在的信息(Review schema里写了星级评分但页面上没显示),Google会判inconsistent标注、轻则忽略schema重则人工降权。第二,标注了真实但不该公开的信息(比如Product schema里把batch内部成本价误标成price),导致SERP上展示了不该展示的数据。规避办法是任何Schema都要确保"标注的信息和页面可见信息完全一致"。Rank Math的Schema模块对FAQ、HowTo、Recipe这几类有现成的"块编辑器"——直接在Gutenberg里插入对应block、填内容,schema和HTML会同步生成,不会出现这种不一致问题。如果想看WP站完整接入Schema聚合的实战路径,可以看Schema聚合实战:WP站5步接入Agentic Web (https://zhangwenbao.com/yoast-schema-aggregation-agentic-web-seo.html)这篇老文。 ## Core Web Vitals在WordPress上怎么过? Core Web Vitals(CWV)是Google定义的三个核心用户体验指标:LCP(最大内容绘制)、INP(交互到下次绘制)、CLS(累积布局偏移)。Google官方说CWV是排名因素之一,权重不算高但跨过及格线和没跨过的站,长尾流量差距能拉到20%以上。WP站要让CWV全绿,主要靠四件事。 第一件,LCP低于2.5秒。LCP指首屏最大元素加载完成的时间,对内容页一般是首屏的标题图或文章封面图,对电商页是商品主图。优化LCP三招:图片用WebP格式、用srcset按设备分发、首屏图片加fetchpriority="high"。再叠加CDN加速,移动端LCP通常能压到1.5秒以内。 第二件,INP低于200毫秒。INP指用户每次交互(点击、滚动、输入)到浏览器下次绘制的延迟,主要受前端JS执行时间影响。优化INP三招:减少非必要JS(删插件、用主题自带功能代替插件、把第三方脚本异步加载)、把首屏不需要的JS用defer或async推迟、用Web Worker把重计算放到工作线程。WP常见拖累INP的元凶是Page Builder(Elementor、WPBakery)的前端运行时和过多动效插件。 第三件,CLS低于0.1。CLS指页面加载和交互过程中元素意外位移的累积量。优化CLS三招:所有图片、视频、iframe都显式标width和height属性、给动态注入的内容(广告、推送)预留固定占位空间、避免在首屏内用插入式动效(突然弹出的弹窗、晚到的Cookie通知顶下来)。WP常见拖累CLS的元凶是用JS动态加载的Google AdSense广告和滑动弹窗。 第四件,TTFB低于800毫秒。TTFB不是CWV的三大指标之一但是基础——TTFB太慢LCP不可能快。TTFB依赖主机性能、PHP执行时间、数据库查询效率。优化路径是主机就近选、PHP升到8.2以上、对象缓存(Redis)启用、避免高频次复杂查询(用Query Monitor插件抓出慢查询逐个优化)。 CWV指标 | 及格线 | WP常见拖累点 | 优化优先级 | 预期改善 | LCP | 低于2.5秒 | 大图未WebP、未上CDN | 1 | 1.5秒可达 | INP | 低于200ms | Page Builder运行时、过多JS | 2 | 100ms可达 | CLS | 低于0.1 | 图片未标尺寸、动态注入内容 | 3 | 0.05可达 | TTFB | 低于800ms | 主机慢、PHP老版本、没对象缓存 | 0(前提) | 200ms可达 | WP站要把CWV全绿,缓存插件+CDN+图片优化插件+轻量主题这四件套是必装。WP-Rocket的"延迟加载JavaScript"、"分离CSS"、"Critical CSS"等高级功能能自动处理一大半性能优化项;LiteSpeed Cache如果主机支持LiteSpeed服务器,免费就能做到WP-Rocket付费版的80%。CWV相关的最新趋势可以参考Core Web Vitals在AI搜索时代的真实ROI解读 (https://zhangwenbao.com/core-web-vitals-ai-search-industry-benchmark.html),里头有AI搜索时代CWV的新意义。 ## 真实案例:出海手工皮具配饰DTC独立站怎么12周WP全清单落地? 保哥去年带过一个真实案例。客户做出海手工皮具配饰,主打小批量手工制作的钱包、卡包、表带、皮带、笔袋这种小件,目标市场是欧美和日本,平均客单价60到150美元,毛利率55%以上。来之前用的是WP+一个臃肿的全功能主题(Avada),WooCommerce开店但没认真做SEO,自然流量月均仅800多,付费广告占新客户80%,ROAS压力很大。 第一周做诊断盘点。Lighthouse跑首页和热门产品页:LCP 4.8秒、INP 480毫秒、CLS 0.23、TTFB 1.7秒,四项全部不达标。Screaming Frog爬完整站发现一堆问题:Slug用了带ID的Permalink结构(/?p=xxx)、Title模板把站名放在前面、Meta Description大量重复或为空、产品图都是JPG没做WebP、Alt文本90%以上为空、没有结构化数据、Sitemap插件冲突生成了两套Sitemap、robots.txt里挡了/wp-content/uploads/导致产品图都不能被Google Images抓到。地基项几乎一项不合格。 第二周做地基整改。换托管型WP主机SiteGround GrowBig档(年费300美元),从美东机房迁到欧洲机房(贴目标用户)。主题从Avada换成Blocksy(轻量框架主题,免费),用Stackable块编辑器重做首页和分类页排版,把首页LCP从4.8秒压到1.9秒。HTTPS强制301、清理掉所有Mixed Content。永久连结从默认改成文章名称结构,用Better Search Replace插件批量改了所有内链,Redirection插件录入了800多条旧URL到新URL的301映射。Permalink切换上线后用GSC的覆盖率报告盯了三周,索引迁移基本平滑。 第三周做SEO插件层。卸掉原来七零八碎的5个SEO插件(每个负责一小块),统一换成Rank Math免费版。重写所有产品页和分类页的Title模板("产品名 - 手工皮具品牌名"前置关键字)、批量生成Description(用Rank Math Pro的Content AI功能,平均30秒一篇)、给前30个核心产品手工写精修版Description。给所有产品页配Schema:Product schema(含价格、库存、SKU)、AggregateRating(带真实客户评分,已有Trustpilot集成)、BreadcrumbList。给博客文章配Article schema和FAQPage。GSC的"丰富搜索结果"报告在第二周末就开始有Product和Article富媒体识别。 第四到六周做图片和速度。装ShortPixel付费版,批量把站内2300多张图片转WebP,原图保留备份。给所有产品图首图加fetchpriority="high"。给空Alt批量补,用ShortPixel的AI Alt生成跑一遍、然后人工过一遍前300张精品款。装WP-Rocket付费版,开启延迟加载JavaScript、分离CSS、Critical CSS、数据库优化、CDN集成。Cloudflare免费版上CDN,把所有静态资源走Cloudflare边缘。CWV在Lighthouse上重新跑:LCP 1.6秒、INP 180毫秒、CLS 0.06、TTFB 280毫秒,CWV全绿。 第七到九周做内容和结构。重新规划站内信息架构:主分类按品类(钱包、卡包、表带、笔袋、皮带)、二级按风格(复古、商务、极简)、三级按材质(牛皮、马皮、植鞣皮)。把零散散落在Blog里的"皮具保养"、"皮具材质介绍"、"如何选钱包"等通用内容拢成"皮具知识库"专栏,做内部Topic Cluster互相内链。给每个核心产品配长文版的"产品故事页"补到800字以上,把工艺、材料、设计师视角讲清楚——这是手工品牌的核心卖点,长内容能拉E-E-A-T信号。 第十到十二周观察并加固。自然流量从开始的月均800涨到第八周的1万4、第十一周的2万、第十二周的2万8。CTR从1.8%涨到3.5%(富媒体Schema和Title前置关键字的双重收益)。付费广告占比从80%降到52%。手机端自然流量占比从35%涨到61%(地基整改后移动端体验大幅改善)。加固阶段把所有SOP写成文档:发布前清单、月度SEO Review清单、季度CWV跑分清单、年度Schema覆盖率审计清单。客户内部一个市场专员+一个兼职开发就能维持SOP运转。 这个案例里没有任何高深魔法,全是WP SEO的标准动作清单做扎实。地基整改一周收效不算多,但当地基+插件+图片+速度+Schema+内容这六件事像积木一样叠起来时,组合效应在第八到十二周开始集中显现。出海手工类品牌如果还在用臃肿主题+默认Permalink+空白Schema+原图JPG的组合跑WP,自然流量大概率被锁在一个低水位上,地基不动其他全是修补。 ## 哪些WordPress SEO常见误区让你白忙? 整理一份保哥这几年见过的高频误区清单,避开它们能省下大量无效投入。 误区一:装一堆SEO插件以为越多越好。实际上SEO主控插件只该装一个(Yoast、Rank Math、AIOSEO三选一),同时装两个会产生Schema冲突、Title覆盖冲突、Sitemap重复。对应的子领域(Redirection、404监控、Schema进阶)能用主控插件就别另外装,主控插件不够用再补独立插件。 误区二:把所有页面都强制index、follow。真正应该index的只有有搜索价值的内容页和商品页。购物车、结账、感谢页、用户中心、内部测试页、站内搜索结果页等应该明确noindex。把所有页面都丢进索引会稀释域名权重。 误区三:堆Tag像不要钱。每篇文章配20个标签的WP站非常常见,导致Tag归档页爆炸成几百个低质重复页。一篇文章3到5个真正描述主题的标签足够,标签数量上限做硬约束。 误区四:用插件做"内链自动化"全自动批量塞。市面上有Link Whisper等"AI内链建议"插件,确实能识别相关内容自动给你加锚文本。但完全交给自动化的结果是锚文本机械、内链密度过高、被Google判作链接操纵。内链要做但是要人工审。 误区五:Sitemap里把所有URL都丢进去。Sitemap应该只放想被索引、有价值的页面。把noindex的页面、404的页面、临时活动页都丢进Sitemap,等于浪费爬取预算还误导Google。WP的XML Sitemap工具配置时务必排除"分类归档页面参数变体"、"标签归档低质量Tag"。更多Sitemap细节可以看Sitemap完全指南:该放什么与lastmod陷阱 (https://zhangwenbao.com/xml-sitemap-complete-guide.html)这篇老文。 误区六:装免费"SEO一键优化"插件全勾选。市面上的"一键优化WP站"插件经常会改一堆你不知道的东西(minify HTML/CSS/JS、修改header、修改permalink、强制按一定规则生成Sitemap),结果某天发现某个原本好好的功能莫名其妙失效。SEO要稳的核心就是改动可控,黑盒插件能少装就少装。 误区七:不更新WP核心和插件。WP和插件每个版本都修了安全漏洞和性能问题,长期不更新等于把站点暴露在已知漏洞下。同时不更新意味着错过PHP兼容性更新,可能某天PHP升级到新版本时站点直接挂掉。建议每周看一次更新提示,重要插件每月主更,小升级随到随更。 ## 常见问题解答 WordPress真的比Shopify或Webflow更适合做SEO吗?内容型站点WP更适合:可控性强、SEO插件成熟、Schema自由度高。电商型站点要看SKU规模,几百以内Shopify更省心,几千上万考虑WooCommerce+WP。营销页型选Webflow更灵活,重内容沉淀的还是回WP。 Yoast SEO和Rank Math到底选哪个?新站直接Rank Math:免费版功能比Yoast免费版多一倍,Schema选项更全,体积更轻。老站如果已经用Yoast多年且数据迁移成本高,可以继续用Yoast Premium。AIOSEO适合不想学习曲线的非技术用户。 永久连结结构应该选哪个?绝大多数情况下选文章名称结构(/%postname%/)。简洁、含关键字、对用户和搜索引擎都友好。已经用了带日期或ID的旧结构想换,要先评估301重定向工作量,再决定换不换。 WP站速度慢主要卡在哪?前三大原因依次是没用CDN、用了臃肿主题、装了过多插件。修复优先级是先上CDN拿走一半负担,再换轻量主题或对现有主题做模板瘦身,最后审一遍插件清单删掉不用的。 WordPress的Core Web Vitals怎么样才能过?LCP靠CDN加速首屏图片、主图按设备分发WebP格式;INP靠减少前端JS、推迟非首屏脚本;CLS靠给所有图片视频iframe标明确尺寸。WP-Rocket或LiteSpeed Cache插件能自动做大部分这三件事。 必装的WP SEO插件清单是什么?四类:SEO主控(Yoast或Rank Math)、缓存(WP-Rocket、LiteSpeed Cache、W3 Total Cache三选一)、图片优化(ShortPixel或Imagify做WebP转换)、安全(Wordfence或Sucuri基础版)。其余都是按需。 Schema结构化数据在WP站怎么加最省事?Rank Math免费版内置Schema Generator能覆盖80%场景,FAQ、HowTo、Article、Product、Review都能拖拽配置。需要更细致的SignificantLink、aboutPage这种用Rank Math Pro或者自己写JSON-LD注入。 ## 结语 WordPress SEO不是装个插件就完事,也不是写完文章就坐等流量。它是把主机、主题、HTTPS、插件、永久连结、缓存、CDN、图片、Schema、Core Web Vitals这些底层基础设施这十件事一个个做对,再让内容运营在这套地基上跑长期复利。上面案例里那个出海手工皮具品牌12周做完全清单,背后是地基整改、插件统一、图片优化、速度治理、Schema覆盖、内容架构这六件事的乘法效应,单一件做完都看不到决定性变化,叠起来才是从月800到月2万8的跨越。你这个站如果在地基项上还有未做对的,先把地基补到位再聊高级技巧,效果差异立竿见影。 ## 权威参考资料 ## AI引用归零监控却没报警?托管主机可能正悄悄拦AI爬虫 - URL:https://zhangwenbao.com/managed-wordpress-blocks-ai-crawlers-citation-loss.html - 分类:WordPress SEO - 发布:2026-05-06 | 更新:2026-06-01 - 摘要:WP Engine 等托管平台会在边缘层默认限速 ClaudeBot、GPTBot,导致内容彻底无法被 AI 引用,而站内 SEO 监控全程无感。本文拆解拦截机制、训练与检索两类爬虫为何不能一刀切、缓存击穿自查命令,以及不搬站也能恢复 AI 可见性的五步路径。 - 关键词:GEO,AI爬虫,AI引用,WP Engine,托管主机 > **TLDR**:摘要:你的网站可能已经从ChatGPT、Claude、Perplexity的回答里彻底消失了,但你的SEO工具一个警报都不会响——因为拦截发生在托管服务商那一层,AI爬虫还没碰到你的网站就被原地打回去了。WP Engine默认就这么干,还不让你关。好消息是,一条curl命令、十秒钟,你就能自己验出有没有中招;真正该做的,不是把所有AI爬虫一律挡在门外,而是把它们分成三类区别对待——挡错了,要么白白被白嫖还不被提及,要么彻底从AI的答案里蒸发。 > 摘要:你的网站可能已经从ChatGPT、Claude、Perplexity的回答里彻底消失了,但你的SEO工具一个警报都不会响——因为拦截发生在托管服务商那一层,AI爬虫还没碰到你的网站就被原地打回去了。WP Engine默认就这么干,还不让你关。好消息是,一条curl命令、十秒钟,你就能自己验出有没有中招;真正该做的,不是把所有AI爬虫一律挡在门外,而是把它们分成三类区别对待——挡错了,要么白白被白嫖还不被提及,要么彻底从AI的答案里蒸发。 先讲一件让保哥盯着屏幕看了半天的事。去年底接手一个做轻奢银饰的北美独立站,品牌故事写得很用心,产品页、博客、设计师访谈全是原创长文,正是那种天生就该被AI引用的内容。团队花了一个季度,把内容结构、问答模块、信息层次全按AI搜索的偏好重做了一遍。三个月后复盘,Google排名稳中有升,搜索后台一切正常,外链也在涨。可对方市场负责人问了一句:“为什么我同事用ChatGPT问‘小众极简银饰品牌推荐’,答案里全是竞品,一次都没我们?” 当时第一反应也是往内容上找原因——是不是权威度不够、品牌信号不强。查了两周,怎么算都说这个站该被引用。后来是顺手用命令行模拟了一次AI爬虫去抓自己的网站,才发现问题压根不在内容:托管平台在最外层,把Claude的爬虫直接挡掉了,内容根本没进过Claude的“脑子”。一个被精心打磨、本该是AI引用富矿的站,在AI的世界里等于不存在。而所有SEO工具的仪表盘,全是绿的。 ## 为什么AI引用突然归零,监控工具却一个警报都没有? 这件事最阴的地方,是它发生的位置。你装的所有SEO插件,跑在网站内部;Ahrefs、Semrush用的是它们自己的爬虫;搜索后台看的是Google自己的抓取。这一整套监控,没有任何一环会去模拟“一个AI爬虫来抓我文章会发生什么”。它们压根不往那个方向看。 而托管商的拦截,恰好就发生在所有这些工具看不到的地方。一个请求进来,顺序大概是这样:先到托管平台自己的入口,很多托管商在这里还套了一层自己的安全和限速规则;不顺眼的请求,在这一层就被一句“别来这么勤,先回去”打发掉了(技术上是返回一个叫HTTP 429的状态码),根本走不到你的网站,更不会写进你看得到的任何日志。你在网站后台、在自己的防火墙面板里翻遍设置,都找不到这条规则——因为它压根不在那几层,它在你够不着的更外面那一层。 它造成的后果是“一刀切”式的。AI引用有一条铁律:能抓到,才谈得上被引用。有团队拿自己的站做过对照,结论很直白——爬虫能正常拿到内容时,AI引用率是个有意义的数字;爬虫被拦时,引用率直接归零。大致是这样: AI平台 | 它的爬虫能不能拿到你的内容 | 实测引用率 | Google AI Mode | 能(走的是Google自家爬虫) | 约37.8% | ChatGPT | 部分能(查询用的放行,训练用的被限) | 约9.6% | Claude | 不能(爬虫被挡) | 0.0% | 注意Claude那行的0.0%。不是低,是零。同一个内容质量足够、在Google AI Mode拿到近四成引用的站,在Claude里完全不存在,差别只是爬虫能不能进门。回头把这套对照套到那个银饰站上,情况几乎一样:Perplexity偶尔露面(它的爬虫没被拦),Claude全程挂零。问题从来不是内容,是门被焊死了,而你站在门里,看不见门外发生了什么。 ## 托管平台到底拦了谁,又放了谁? 这里要先破一个误会:平台不是把所有跟AI沾边的流量一律挡掉。它的拦截是挑着来的,而这个“挑”的逻辑,恰恰是看懂整件事的钥匙。把一个真实环境里观察到的行为整理出来,大概长这样: 爬虫 | 它来干嘛 | 被限/被拦的比例 | 结果 | ClaudeBot (https://support.anthropic.com/en/articles/8896518-does-anthropic-crawl-data-from-the-web-and-how-can-site-owners-block-the-crawler) | 抓内容去训练模型 | 约29% 被限速 | 抓得断断续续 | GPTBot (https://platform.openai.com/docs/bots) | 抓内容去训练模型 | 约29% 被限速 | 抓得断断续续 | Amazonbot | 抓内容去训练模型 | 约51% 被拦 | 基本进不来 | Bytespider | 抓得最凶的训练爬虫 | 约61% 被拦 | 基本进不来 | ChatGPT-User | 用户当场让它去读某一页 | 0% | 畅通 | PerplexityBot | 用户搜索时现去抓来引用 | 0% | 畅通 | 看出规律了吗?平台挡的,是那些“一次性把整站大批量拉走、拿去喂模型”的爬虫;放行的,是“某个真人当场提了个问题、模型现去抓你那一篇”的请求。站在托管商的算盘上,这么分极其合理:前一种一来就是几万次请求,把缓存击穿、把带宽吃光,而你一分钱回报都拿不到;后一种是人肉节奏、就抓一页,背后有个真实的人在等答案,放过去对服务器压力小,对你还可能有价值。 问题是,托管商拿“服务器成本”这把尺子做的切分,跟你按“能不能被AI看见”这把尺子需要的切分,根本不是一回事。对它来说,挡掉Bytespider是省钱;对你来说,如果你想被Claude的模型记住、想在以后的Claude回答里有名字,那ClaudeBot被限的那29%,就是在慢慢放血。它用自己的省钱逻辑,替你做了一个关乎品牌死活的决定,还没问过你。 ## 训练、检索、助手,三类AI爬虫到底差在哪? 要自己做对决定,先得把“AI爬虫”这个笼统的词拆开。2026年的现实是,它早就不是一种东西,而是三类目的完全不同的访客,混为一谈是眼下最贵的一个误判。 第一类,抓去训练模型的。像GPTBot、ClaudeBot、Google-Extended、Bytespider。它们把你的内容吸进模型里,喂给下一代AI。特点是抓得极多、几乎不给你带任何回头流量。它的价值是长线的、靠概率的——你的观点、品牌名进了模型的“常识库”,将来有人问相关问题、模型不联网也能张口说出你。 第二类,用户搜索时现抓现用的。像Perplexity的爬虫、各家AI搜索的检索爬虫。有人问了个问题,模型当场联网去抓相关页面,抓回来总结,给出带链接的引用。这一类对独立站当下最实在:被它抓到且抓得好,你就出现在那个带蓝色链接的引用框里,是有真人点进来的。 第三类,替某个真人临时跑一趟的。比如你把一个链接贴进ChatGPT让它读一下。它本质上代表一个具体的人,背后是一次真实的人的动作。 为什么非得分开?因为这三类“抓你多少次、给你带回多少人”差得离谱。Cloudflare (https://blog.cloudflare.com/control-content-use-for-ai-training/) 2026年第一季度有一份统计,算的就是“每给你带回一个真实访问,这个爬虫向你索取了多少次抓取”: 爬虫 | 抓取次数 ∶ 带回访问 | 说人话 | ClaudeBot(训练) | 约20583 ∶ 1 | 抓你两万多次,换一个访问 | GPTBot(训练) | 约1255 ∶ 1 | 抓上千次,换一个访问 | PerplexityBot(检索) | 约111 ∶ 1 | 开始有像样的回头流量了 | Googlebot(传统) | 约5 ∶ 1 | 抓取和回流基本对等,这是传统SEO的老基准 | 这张表能解释托管商为什么先拿ClaudeBot开刀——两万比一,在任何一个管钱的人眼里都是纯亏损。但它也精确地点出了你为什么不能跟着托管商一刀切:要是把Perplexity这种(111比1,而且这个比还在飞快变好)也一起挡掉,等于亲手掐死了眼下唯一能带真实点击的那一类AI流量。把所有AI爬虫一律Disallow掉,是2026年一个SEO顾问能给出的最糟糕的建议之一,它把“拒绝被白嫖”和“拒绝被看见”这两件完全不同的事,混成了一件。正确的姿势是分层:训练类的,看你品牌战略决定喂不喂;检索类和助手类,必须全程畅通。这三类更细的逐家操作,AI爬虫AEO优化那篇 (https://zhangwenbao.com/ai-crawler-aeo-optimization-guide.html)里按平台一个个拆过,这里不重复。 ## 你看到的GPTBot,会不会是别人冒充的? 讲完三类,必须补一个绝大多数人会跳过、然后吃大亏的点:爬虫报上来的“身份”,是可以随便填的。 一个请求自称是ClaudeBot还是GPTBot,靠的是请求头里那一栏叫User-Agent的文本——它就是一行字符串,任何人写个脚本都能把它填成 GPTBot/1.0。这就带来两个反方向的坑。一头是坏爬虫冒充正经AI爬虫,骗过你“对AI爬虫友好”的放行规则,混进来薅内容、薅带宽。另一头更隐蔽:你自己做决策时,把一大堆冒充流量当成“真AI爬虫来了”,数据看着热闹,据此做的判断全是错的——你以为GPTBot天天来抓,其实来的是一堆挂着GPTBot名头的垃圾脚本。 正经的几家——OpenAI、Anthropic、Perplexity——都公开了各自爬虫的真实出口IP段,或者明确要求用反向解析来验明正身。验证一个自称GPTBot的请求是不是真货,标准做法是两步:先拿它的来源IP做一次反向解析,看解出来的域名是不是落在官方公布的那个域里;再把这个域名正向解析回去,看是不是还能解回原来那个IP。两步都对得上,才是真的;对不上,不管它User-Agent写得多像,都按可疑处理。 落到操作上就一句话:精细放行只给“验证过的真爬虫”,对“自称是但验不过”的一律当可疑流量处理。这一步看着麻烦,但跳过它的代价是双向的——要么被垃圾爬虫薅到带宽爆表还以为是AI在抓你,要么把一堆假数据当成AI关注度去做内容决策。两种都是拿错误的地图找路。验真这件事,和前面判断“托管商拦没拦”是同一个底层要求:别看表面那栏字写了什么,要看穿到它背后到底是谁。 ## 怎么用一条curl命令,十秒钟自查中没中招? 讲了这么多原理,落到行动上其实很简单。思路就一句:用同一个网址,分别装成普通浏览器和AI爬虫各请求一次,比一下返回的结果。浏览器能正常打开、AI爬虫被打回,你就中招了。 最小一组对照命令,以Claude的爬虫为例: curl -s -o /dev/null -w "%{http_code}\n" -A "Mozilla/5.0" https://你的域名/某篇核心文章/ curl -s -o /dev/null -w "%{http_code}\n" -A "ClaudeBot/1.0 (+https://www.anthropic.com/claude-bot)" https://你的域名/某篇核心文章/ 第一条装成浏览器,第二条装成ClaudeBot,都打同一个真实页面。如果第一条返回200(正常),第二条返回429或403(被拦),问题确诊。把第二条里的身份换成GPTBot、PerplexityBot各跑一遍,就能画出你这台站“放谁、拦谁”的完整地图。 这里有个极容易踩空的坑,保哥单独拎出来讲,因为十个自查的有八个会栽在这:WP Engine这类平台的拦截,只在“缓存没命中”时才触发。意思是,如果你刚好请求了一个被平台缓存住的页面,爬虫拿到的是缓存副本,会返回正常的200,你就会误以为没事。所以自查时一定要在网址后面加个随机参数,逼平台绕开缓存、回到真正的服务器: curl -s -o /dev/null -w "%{http_code}\n" -A "ClaudeBot/1.0" "https://你的域名/某篇核心文章/?nocache=$(date +%s)" 加上 ?nocache=时间戳 这一串,强制绕开缓存,这时拿到的状态码,才是AI爬虫真实会遇到的待遇。那个银饰站第一次自查,就是没加这个参数,curl回了一片正常的200,差点就放过去了——后来加上强制绕缓存重跑,才看到清一色的429。这个坑不是想出来的,是实打实栽进去过一次才记住的。想把整条“抓取—渲染—收录”的链路对AI爬虫到底通不通系统排一遍,可以接着看 AI爬虫抓取量已超Googlebot那篇 (https://zhangwenbao.com/ai-crawlers-surpass-googlebot-seo-strategy.html)里的诊断流程,curl自查只是第一道关。 有条件的话,别只在自己电脑上curl。家里的网络出口、机房的网络出口,触发的规则可能不一样。最稳的做法,是在一台云服务器上把这组对照连着跑几十次,看状态码的分布——单看一次的200下不了结论,要看的是“绕开缓存之后,AI爬虫这边返回429的比例,是不是明显比浏览器那边高”。要用比例去看,而不是单点去看。这也是它跟普通封禁最不一样的地方:它不是非黑即白地全拦,而是按概率限速,你得用统计的眼光才能确诊。 ## 返回码不只有200和429,怎么读懂它在说什么? 自查时你不会只看到漂亮的两种结果。AI爬虫遇到的待遇是一个谱系,每种返回码背后是托管商不同的态度,读懂它,你才知道该怎么应对: 返回码 | 它在说什么 | 对你的含义 | 200 + 正常内容 | 放你进来了 | 这个爬虫这条路是通的 | 200 + 空白/极短页 | 表面放行,实际给了个空壳 | 最阴的一种,容易被误判成“通了” | 304 | 内容没变,用你上次的缓存 | 正常,不是拦截 | 403 | 明确拒绝,没得商量 | 硬封,多半是规则写死了 | 429 | 来太勤了,先回去待会再来 | 限速,是概率性的,最常见 | 503 | 服务暂时不可用 | 有时是真过载,有时是变相软拦 | 重点盯两行。一是 200但内容是空的——这是最容易骗过自查的:状态码漂漂亮亮200,你以为通了,其实平台给爬虫返了一个没有正文的空壳。自查时不能只看返回码,要顺手把返回内容的长度也打出来(curl加 -w "%{size_download}"),同一个页面,浏览器拿到几万字节、爬虫只拿到几百字节,就是这种情况。二是 429和403的区别:429是限速,态度是“现在不行待会儿行”,靠工单放宽配额、靠降低并发往往能缓解;403是硬拒,规则写死了,工单不松口就只能搬家。分不清这两个,你会在该搬家时空等、在该谈判时白搬。 更重要的是,这件事不能查一次就完。托管商的规则会悄悄变,今天通的下个月可能就429了,而它依然不会通知你。所以正确的做法是把自查变成例行——挑五到十个核心页面,每周用一个定时任务,分别用浏览器和几个主要AI爬虫的身份各打一遍(记得带绕缓存参数),把返回码和内容长度记进一个表。逻辑很简单,就这么几行意思: 对每个核心URL: 对每个身份(浏览器 / GPTBot / ClaudeBot / PerplexityBot): curl带绕缓存参数请求,记下 状态码 和 返回字节数 和上周同一格对比 若某AI爬虫从200转429/403,或字节数骤降 → 触发告警 关键不是脚本多精巧,而是“从200变成429”这个跳变要能自动报警。这件事的全部杀伤力,就来自它发生时悄无声息。你监控了,它就是个有提前量的预警;你不监控,它就是几个月后某天突然发现“怎么AI里全没我了”的那记闷棍。把它和你的排名监控、可用性监控放在一起,当成同一级别的常规盘——这是这套打法里最该固化成习惯、却最常被省掉的一步。 ## 为什么托管商既不告诉你,也不让你关? 确诊之后,大多数人的第一反应是:进后台关掉它。然后会撞上这件事的第二层坑——你关不掉,也问不出来。WP Engine在被追问规则细节时的官方回复,几乎一字不差是这句: > 关于我们的防火墙,无法提供更多信息,因为这可能危及其安全完整性。 翻译成人话就是:规则是平台定的、对你不可见、不能改、不解释。它不是你网站里那行你能删的设置,也不是你防火墙面板里一条你能关的规则——它在你够不着的那一层,客户那边连个开关都没有。这跟你自己主动写规则屏蔽某个爬虫,是完全两码事:前者是平台替你做主还藏着不说,后者是你自己做的决定你随时能改。 更要命的是,不是所有托管商都这么干,所以问题高度取决于你“恰好用了哪一家”。把主流几家公开说过的话放一起对照,差别一目了然: 托管商 | 是否默认在平台层拦训练类AI爬虫 | 对外的说法 | WP Engine | 是(最外层拦掉,客户看不见也关不掉) | “涉及防火墙安全,不便透露” | Kinsta | 否 | 技术负责人明确表态“不会在平台层拦” | Pressable | 否 | “默认不禁止这些爬虫” | Pantheon | 否 | “我们不拦截已识别的爬虫流量” | 这张表的价值在于:它把一个听起来很玄的“AI可见性”问题,一下降维成了一个非常具体、能拍板的运维事实——你用的是哪家托管,直接决定了你的内容默不默认对Claude这类模型可见。这不是“GEO做得好不好”的程度问题,是“门开没开”的有无问题。商业动机也不必往阴谋论想:对一个跑着几十万个网站的平台,那种突发海量的抓取确实是真实的成本和稳定性威胁,从基础设施角度默认挡掉,是说得通的。问题不在“拦”本身,在“默认拦 + 不告知 + 不给开关”这三件事叠在一起——它把一个本该由站长按品牌战略来权衡的取舍,变成了平台单方面替你定、还不让你知道的既成事实。 ## 自己能控的那一层,到底该铺什么? 平台那道墙你管不着,但你自己网站这一层能控的东西,很多人也没铺对。这里说清三样,每样都讲到“放什么、别放什么”,不停在“要重视”的空话上。 第一样,robots.txt要按引擎分开写,别一把梭。很多人要么对所有爬虫一个规则,要么干脆复制网上一段“屏蔽所有AI”的模板贴上去——后者正是前面说的最糟做法。正确的写法是把训练类和检索类拆开:训练类(GPTBot、ClaudeBot、Google-Extended这些)按你的品牌策略决定放不放;检索类和助手类(Perplexity、各家search爬虫)一律明确Allow,一个都别误伤。还有个常被忽略的点:robots.txt是“君子协议”,正经爬虫认,坏爬虫不认——所以它管的是“你想让谁抓”,真要把谁挡死,得靠服务器规则那一层,两者分工别搞混。具体到不同引擎在2026年的写法差异、虚拟和物理文件谁优先这些细节,WordPress robots.txt那篇2026版指南 (https://zhangwenbao.com/wordpress-add-robots-txt-files-and-optimize-website-collection.html)里一条条列过,照着配就行。 第二样,llms.md值得放,但别指望它替你做主。说人话,llms.md就是放在网站根目录的一个纯文本文件,用来主动告诉AI:我这站最值得你看的是哪几篇、它们讲什么、规范链接是哪个。它解决的是“被抓到之后,让AI更快抓对重点”,对一个内容结构清晰的站,是低成本的加分项。但要清醒两件事:一,它是新约定,不是所有AI都认、认的程度也不一样,别当成开关;二,它压根解决不了“爬虫根本进不来”的问题——门都没进,门内放张说明书没意义。所以它的位置是“锦上添花”,排在确认门是开的之后,不是之前。 第三样,结构化数据和sitemap,作用真实但有边界。清晰的结构化标注,确实能帮AI更准地理解“这段是答案、这段是步骤、这是谁说的”,提升被精准引用的概率——但它是“帮AI读懂”,不是“逼AI收录”,更不能把进不来的门撬开,别把它当万灵药。sitemap里有个真实的坑值得单独提:别为了催抓取去伪造lastmod(内容没动却天天改成今天)。一开始可能骗到几次抓取,时间一长,引擎发现你这个站“天天说有更新、其实没动”,会反过来降低对你sitemap的信任,得不偿失。lastmod要和真实修改对齐,这种地方老实,长期才占便宜。 这三样铺对了,你这一层就算尽到本分了。但记住它们的共同前提——全部建立在“爬虫进得来”之上。门是关的,这三样做到满分也是零。所以顺序永远是:先验门,再铺这一层,最后才谈精雕细琢。 ## 已经中招了,怎么把AI可见性抢回来? 确诊之后,按这个顺序来,从代价最低的开始: - 先把损失范围摸清楚,别急着搬家。用上面那组curl,把“哪类被拦、哪类没事”画出来。如果你发现查询类的爬虫(Perplexity这些)其实是通的,只有训练类被限——那你当下能带真实点击的那块流量其实没断,损失主要在长线那块。这决定了你到底有多急。 - 提工单,但要会说话。别泛泛地问“你们是不是拦了AI爬虫”,客服会用那句安全话术挡回来。要带着curl的复现结果去:把“同一个网址、绕开缓存、浏览器返回200、AI爬虫返回429”的完整对照贴上,直接要求转给工程团队,并明确问一句“有没有更高一档的套餐、或者哪个配置项,能为我这个账号放行指定爬虫”。有数据的工单和没数据的抱怨,处理速度差一个量级。 - 谈不拢再准备搬,但先想清楚值不值。搬到Kinsta、Pressable、Pantheon这类默认不在平台层拦的托管,是釜底抽薪。但搬站本身有SEO风险,要拿第一步那张损失地图来掂量:如果查询类没断、只是训练类被限,很多中小站其实可以先不搬。 - 搬不搬,先把自己能控的那层做对。在你自己的robots.txt和相关规则里,把意图写清楚:查询类、助手类全部明确放行,训练类按你的品牌策略决定放不放。这一层平台拦不拦你管不着,但至少表明你自己的态度是清楚的,日后也方便举证“被拦不是我自己设的”。具体每样该铺什么、不同引擎怎么分开写,前面“自己能控的那一层到底该铺什么”那节已经逐条讲过,照着做就行。 - 建立AI引用的常规监控,别再只盯搜索后台。至少每两周,拿一组核心问题,去ChatGPT、Claude、Perplexity里实测一遍品牌露出和引用,把它当成跟搜索后台同等级的常规仪表盘。这件事最大的教训就是:你监控什么,才发现得了什么。从不测AI引用,就永远活在“工具全绿、其实早就消失”的幻觉里。 那个银饰站,最后走的是第二条加第四条:带着绕缓存的curl复现把工单怼到工程团队,同时把自己这层的放行规则全部重写。两周后,ClaudeBot被限的比例从六成压到个位数;又过了一个多月,Claude的回答里开始零星出现这个品牌。没有搬站——因为损失地图一直显示查询类是通的,当下的真实点击其实没断,急的只是长线那块。就这一个判断,省下了一次本来很可能白做的搬站工程。这不是什么独门绝技,就是“先量清楚再决定”这条最朴素的原则,在一个新场景里又应验了一次。 ## 当抓取开始明码标价,游戏规则会怎么变? 前面讲的还是“拦或不拦”的二选一。但2026年已经冒出第三个选项,值得你提前知道:抓取开始能明码标价了。 Cloudflare在2026年推的按次计费抓取(pay-per-crawl)就是个信号——它让网站不再只能“放行”或“拦死”,而是多了一档“想抓可以,按次付费”。对那些两万比一只薅不还的训练类爬虫,站点第一次有了一个不撕破脸的中间选项:你要喂我的内容训模型,行,那别白嫖。这件事的意义不在那几个钱,而在它把“能不能抓到你”从一个纯技术问题,变成了一桩商业谈判。 对内容站来说,这是机会,也是新麻烦,得分清楚。机会在于:原创内容多、被AI反复来薅的站,手里第一次有了筹码——要么换钱,要么换“引用时必须署名带链接”这种更值钱的条件。麻烦在于:谈判桌是有门槛的。有议价权的,是手握独家内容、流量体量大的站;绝大多数中小站根本上不了那张桌子,平台和大模型之间怎么谈,小站只能接受结果。所以别一听“能收费了”就高兴,先掂量自己有没有那个筹码。 保哥的一个判断是:未来两三年,“你的内容对AI怎么开放”会越来越像今天“你的内容对搜索引擎怎么开放”——从一个发布完就不管的默认设置,变成一个要定期复盘、有策略、甚至要谈条件的运营动作。今天还在纠结“要不要让AI抓”的人,明年要回答的问题已经升级成“按什么条件、对哪几家、收不收费、怎么验证它有没有守约”。能不能被抓到、以什么条件被抓到,正在从技术细节,变成内容生意的一个谈判筹码。早点把这事当回事的人,会比临到头才反应过来的人,多出一整轮准备时间。 ## 这件事对独立站和内容站,意味着什么长期变化? 把镜头拉远。这不是某一家托管商的孤立的坑,它是“流量正在向AI转移”这个大趋势里一个很典型的切片。过去十几年,SEO的全部假设都建立在一个前提上:搜索引擎想抓你、你也想被抓,双方利益一致,Googlebot抓取和回流大致五比一,是个良性循环。AI爬虫把这个前提打碎了——训练类爬虫两万比一地索取、几乎不回流,于是基础设施这一层第一次有了强烈的动机去“拦住想抓你的人”,而这件事,发生在你和你的监控工具都看不到的地方。 对内容站和独立站,有三个判断值得记下来。第一,“能被抓到”本身,正在重新变成一种要主动争取、主动盯着的东西,而不是默认就有。十年前没人需要担心Googlebot进不进得来;今天,你得定期验证AI爬虫进不进得来。第二,被AI引用,正在变成一种新的“外链”——它带来的不只是点击,更是品牌在模型“常识库”里的存在感,这层逻辑在 外链建设下一个时代那篇 (https://zhangwenbao.com/link-building-next-era-citation-optimization.html)里专门展开过;而你要是连门都进不去,这层东西根本无从积累。第三,托管和服务器选型,第一次成了一个跟AI可见性挂钩的决定;过去选托管看速度、稳定、价格,现在得再加一栏:它默认怎么对待AI爬虫、给不给你开关。这一栏的分量,只会越来越重。 说到底,这件事最大的教训不是“WP Engine不好”——它从基础设施角度做的取舍有它的道理。教训是:在“AI决定谁被看见”的时代,你不能糊里糊涂地,把“谁能抓到我的内容”这个生死开关,外包给一个用省钱逻辑、而不是用品牌逻辑做决策、还不告诉你的第三方。你至少得知道,那扇门,是开是关。十秒钟一条curl,先去验一下你自己那扇门。 ## 常见问题解答 ## 怎么快速判断我的站有没有被托管平台拦了AI爬虫? 用同一个真实网址,分别用浏览器身份和ClaudeBot、GPTBot的身份各curl一次,网址末尾加上 ?nocache=时间戳 强制绕开缓存。浏览器返回200、AI爬虫返回429或403,就是中招了。一定要带那个绕缓存的参数,否则缓存命中会给你一个假的“正常”。 ## 我直接在自己网站的规则里把AI爬虫全放行,能解决吗? 不能。平台层的拦截发生在最外面,在你网站的规则被读到之前,请求就已经被打回去了,你这层的放行根本轮不到生效。这层规则该写,但它解决的是“你自己的态度”,解决不了平台替你设的那道墙——后者只能走工单或者搬家。 ## 是不是干脆把所有AI爬虫都挡掉,反正它们白嫖内容? 不要。AI爬虫分训练、检索、助手三类。检索类和助手类会带来真实点击和引用回流,全挡掉等于亲手掐死眼下唯一能变现的那块AI流量。只对训练类按品牌策略取舍,检索类和助手类必须放行。 ## 哪些托管商默认会在平台层拦? 目前公开信息里,WP Engine会在最外层默认限速训练类AI爬虫,且客户看不见也关不掉。Kinsta、Pressable、Pantheon公开口径都是不在平台层拦。选托管前直接问对方“是否默认在平台层拦AI爬虫、有没有客户侧开关”,并要一个书面答复。 ## 被拦了但不想搬站,有没有补救空间? 有。先用curl画损失地图:如果检索类(Perplexity这些)其实是通的、只有训练类被限,说明当下带点击的AI流量没断,损失主要在长线那块。这种情况优先走带数据的工单要求放行,多数能把被限比例压下去,不一定非搬家。 ## 训练类爬虫几乎不带流量,放它进来图什么? 图的是长线的、靠概率的“模型记忆”。训练类把你的品牌和观点吸进模型,模型以后不联网回答相关问题时,有概率原生说出你。它不带即时点击,但决定你在AI的“常识库”里有没有名字。值不值,看你的品牌战略,不能只用即时回报一刀切判死。 ## 这和之前说的AI爬虫抓取量暴涨,是同一件事吗? 是同一个趋势的两面。抓取量暴涨,是“训练类爬虫海量索取、几乎不回流”在成本侧的表现;平台默认拦截,是基础设施对这个成本的防御反应。站长要做的不是站队,而是分层:把吃成本不回流的挡在策略闸后,把带回流的检索类全程放行,并持续盯着AI引用。 ## 权威参考资料 ## Schema聚合实战:WP站5步接入Agentic Web - URL:https://zhangwenbao.com/yoast-schema-aggregation-agentic-web-seo.html - 分类:WordPress SEO - 发布:2026-03-06 | 更新:2026-05-16 - 摘要:Yoast Schema聚合如何让WordPress一键接入Agentic Web?保哥拆解Schemamap端点架构、实体消歧机制与NLWeb协议生态,附5步部署清单与3个站点AI爬虫访问验证数据。 - 关键词:WordPress SEO,结构化数据,Schema,Schemamap,MCP > **TLDR**:摘要:Yoast的Schema聚合怎么让WordPress一键接入Agentic Web?本文拆解Schemamap这个站点级结构化数据图谱、实体消歧为什么是核心价值、NLWeb协议的底层逻辑,给从启用到验证AI Agent接入的五步部署清单,讲清结构化数据正从页面装饰变成AI基础设施,附三个站点的AI爬虫访问验证数据。 > 摘要:Yoast的Schema聚合怎么让WordPress一键接入Agentic Web?本文拆解Schemamap这个站点级结构化数据图谱、实体消歧为什么是核心价值、NLWeb协议的底层逻辑,给从启用到验证AI Agent接入的五步部署清单,讲清结构化数据正从页面装饰变成AI基础设施,附三个站点的AI爬虫访问验证数据。 ## 引言:结构化数据正从"页面装饰"变成"AI基础设施" 2026年3月,Yoast SEO在27.1版本中推出了一项名为Schema Aggregation(Schema聚合)的新功能。这不是又一个微小的插件更新,而是一个信号——它标志着结构化数据在Web生态中的角色正在发生根本性的转变。 过去十年,我们对Schema.org (https://schema.org/)的理解大多停留在"帮Google展示Rich Snippets"这个层面:给文章加上Article标记,给产品加上Product标记,然后祈祷搜索结果页出现那个漂亮的星级评分。但现在,游戏规则变了。 随着ChatGPT (https://zhangwenbao.com/chatgpt-citation-content-strategy.html)、Google AI Overviews、Perplexity等AI搜索引擎的崛起,以及Microsoft NLWeb (https://github.com/microsoft/NLWeb)、MCP(Model Context Protocol (https://modelcontextprotocol.io/))等Agentic协议的推进,结构化数据正在从"SEO的锦上添花"升级为"AI系统理解你网站的核心接口"。保哥认为,这次Yoast的Schema聚合功能,正是这场变革中第一个真正面向大众WordPress用户的落地实现。 本文将从技术原理、架构设计、实体消歧机制、NLWeb生态整合和实操部署五个维度,深入拆解这个功能为什么重要、它做了什么、以及你现在应该怎么做。 ## Schemamap是什么?理解"站点级结构化数据图谱" ## 传统Schema的页面孤岛问题 在Schema聚合功能出现之前,WordPress站点的结构化数据是以"页面"为单位输出的。每个URL页面各自携带一份JSON-LD,描述该页面包含的实体:这篇文章是什么类型、作者是谁、属于哪个组织。 这种模式对传统搜索引擎来说足够了——Google爬取每个页面时,会读取页面级别的JSON-LD并索引。但对于AI Agent来说,这种分散式的结构化数据是低效的。一个AI系统要理解"这个网站有哪些作者、这些作者分别发布了哪些文章、文章与产品之间有什么关联",它必须爬取整个站点的每一个页面,然后自行拼接这些分散的数据片段。 这不仅效率极低,还容易产生实体重复的问题。比如同一位作者出现在100篇文章的JSON-LD中,AI系统需要自行判断这100个Person实体其实是同一个人。 ## Schema聚合的核心概念 Yoast的Schema聚合功能引入了一个全新的概念:Schemamap。 Schemamap是一个通过REST API端点(Endpoint)暴露的站点级结构化数据图谱。它把整个网站的所有可索引内容——文章(Article)、作者(Person)、产品(Product)、组织(Organization)、事件(Event)、食谱(Recipe)等——聚合到一个统一的输出中。 这个端点的技术实现基于WordPress的REST API: GET /wp-json/yoast/v1/schema-aggregator/get-xml 它返回一个类似于Sitemap的XML索引文件,列出按内容类型(post type)分割的Schema数据端点。然后,每个内容类型的端点以JSON Lines(JSON-L)格式返回该类型下所有实体的完整结构化数据。 例如获取所有文章的Schema: GET /wp-json/yoast/v1/schema-aggregator/get-schema/post 支持分页,大型站点可以逐页获取: GET /wp-json/yoast/v1/schema-aggregator/get-schema/post/2 ## 技术架构亮点 从技术架构上看,Schemamap有几个值得注意的设计决策: 缓存优先:端点响应带有Cache-Control: max-age=300的缓存头,确保在5分钟内重复请求不会命中数据库。官方声称响应时间可以控制在100毫秒以内。 robots.txt自动注册:启用后,Schemamap的XML索引地址会自动添加到robots.txt中,类似于Sitemap的声明方式。这意味着任何遵循robots.txt规范的爬虫或AI Agent都能自动发现这个端点。 隐私与索引设置联动:Schemamap只会暴露已标记为可索引(indexable)的公开内容,如果你在Yoast中将某些页面设置为noindex,它们不会出现在聚合输出中。 插件生态兼容:如果你使用了Yoast WooCommerce SEO来扩展产品Schema,或者使用了第三方的食谱、事件插件,这些扩展的结构化数据也会被自动拉入Schemamap中。 ## 实体消歧(Entity Disambiguation):为什么这才是核心价值 ## 什么是实体消歧? 实体消歧是自然语言处理和知识图谱领域的一个核心概念。简单来说,就是确定"同一个名字指的是同一个东西"。 在Web的语境下,实体消歧的挑战在于:同一位作者"张三"可能出现在你网站的200篇文章中,每篇文章的JSON-LD里都有一个Person类型的结构化数据描述他。对于AI系统来说,这200个Person节点到底是同一个人还是200个不同的人?如果每个节点的@id不一致,或者描述信息有细微差异,AI系统就可能产生困惑。 ## Schema聚合如何解决这个问题 Schemamap采用了去重合并策略:在聚合输出中,每个实体只以一个节点的形式出现。即使"Author X"出现在多篇文章中,聚合后的输出也只包含一个该作者的实体节点,而文章通过@id引用关联到这个唯一的作者节点。 这种做法的技术意义在于: - 消除冗余:减少了AI系统处理重复数据的开销 - 建立明确的实体关系图:Author到Article到Organization的关系链变得清晰可遍历 - 提升语义准确性:AI系统不需要做模糊匹配来判断实体同一性,因为聚合层已经完成了这项工作 ## 从知识图谱视角理解 如果你熟悉知识图谱(Knowledge Graph),可以把Schemamap理解为站点级别的轻量知识图谱导出。传统上,构建知识图谱需要专门的图数据库和复杂的ETL流程。而Schema聚合本质上是在WordPress插件层面完成了一个"图谱构建 + 序列化导出"的工作: - 遍历站点所有可索引内容 - 提取每个页面的Schema图谱片段 - 按@id去重合并实体 - 建立实体间的引用关系 - 以JSON-L格式序列化输出 这虽然不是一个完整的RDF图数据库,但对于AI Agent来说已经足够——它们不需要SPARQL查询能力,它们需要的是一份干净、去重、关系完整的结构化数据集。 ## NLWeb协议:理解Agentic Web的底层逻辑 ## NLWeb是什么? Yoast的Schema聚合功能并非孤立存在,它是与微软NLWeb(Natural Language Web)项目协作开发的。要理解Schema聚合的战略意义,必须先理解NLWeb。 NLWeb是由R.V. Guha主导的开源项目。Guha是Schema.org、RSS和RDF的创建者之一,目前担任微软的CVP和技术院士(Technical Fellow)。NLWeb的目标是为任何网站提供一个自然语言接口层,使其能够被AI Agent以对话方式查询。 NLWeb的核心工作流程是这样的: - 数据摄入:爬取网站的Schema.org标记数据(JSON-LD格式为首选) - 向量化存储:将结构化数据转化为向量嵌入,存入向量数据库 - 语义查询:当AI Agent发起自然语言查询时,NLWeb基于语义相似性检索相关内容 - LLM增强返回:使用大语言模型理解查询意图,结合检索结果生成精确的结构化响应 ## NLWeb与MCP的关系 NLWeb的一个关键设计决策是:每个NLWeb实例同时也是一个MCP(Model Context Protocol)Server。MCP是Anthropic提出的AI Agent工具调用协议标准,它定义了LLM如何与外部工具和数据源交互。 这意味着当一个网站部署了NLWeb之后,它就自动成为了MCP生态的一部分。任何支持MCP的AI Agent——无论是Claude、ChatGPT还是其他系统——都可以通过标准化的协议直接查询这个网站的内容,而不需要传统的HTML爬取和解析。 微软的CTO Kevin Scott曾将MCP比喻为AI应用互联时代的HTTP。如果说HTTP定义了浏览器如何获取网页,那么MCP定义了AI Agent如何获取和操作数据。NLWeb在这个类比中扮演的角色类似于HTML——它定义了网站内容如何被结构化和表达,以便AI Agent能够理解和使用。 ## Schema聚合在NLWeb生态中的位置 理解了NLWeb的架构,Yoast Schema聚合的战略定位就清晰了:它是NLWeb数据摄入层的上游供给。 NLWeb需要高质量的Schema.org JSON-LD数据作为输入。过去,NLWeb需要自行爬取网站的每个页面来收集这些数据。现在有了Schemamap端点,NLWeb可以通过一次API调用获取整个站点的完整、去重、关系完整的结构化数据图谱。 这大幅降低了WordPress站点接入NLWeb生态的技术门槛。根据Yoast官方的说法,开发者现在可以直接使用Schemamap端点的输出来部署NLWeb,构建站点的对话式查询接口。 ## 实操指南:如何配置与优化Schema聚合 ## 启用Schema聚合 前提条件: - Yoast SEO 27.1或更高版本(免费版即可使用此功能) - WordPress站点的Schema功能已在Yoast设置中启用 启用步骤: 更新到Yoast SEO 27.1后,登录WordPress后台时会看到一个引导式的功能介绍界面。按照提示操作即可,核心就是一个开关切换(Toggle)。也可以在Yoast SEO设置中手动找到Schema Aggregation选项并启用。 启用后,Schemamap的XML索引地址会自动出现在你站点的robots.txt文件中。 验证启用是否成功: 访问以下地址验证: https://你的域名/wp-json/yoast/v1/schema-aggregator/get-xml 如果返回了XML格式的Schema端点索引列表,说明功能已成功启用。 ## 进阶开发者配置 Yoast为开发者提供了丰富的Filter Hook,可以对Schema聚合的行为进行细粒度的定制: 自定义包含的文章类型: add_filter( 'wpseo_schema_aggregator_post_types', function( $post_types ) { $post_types[] = 'portfolio'; $post_types = array_diff( $post_types, ['attachment'] ); return $post_types; }); 自定义大分页的文章类型(适用于商品等数量庞大的内容类型): 通过wpseo_schema_aggregator_big_schema_post_types筛选器,可以指定哪些文章类型使用大分页策略。默认情况下,product类型使用此策略。 自定义Schema过滤策略: 如果你需要更细粒度的控制——比如过滤掉某些Schema类型或修改聚合逻辑——可以实现自定义的Filtering_Strategy_Interface: add_filter( 'wpseo_schema_aggregator_filtering_strategy', function( $default_filter ) { return new My_Custom_Schema_Filter(); }); ## Schema质量优化清单 Schema聚合的价值取决于底层Schema数据的质量。如果你的Schema标记本身就不完整或关系断裂,聚合后的Schemamap也不会有多大意义。以下是保哥建议的优化清单: 实体互联性检查: - 确保每篇文章的author字段通过@id正确引用到Person实体 - 确保Person实体包含sameAs属性,链接到外部权威来源(LinkedIn (https://zhangwenbao.com/linkedin-b2b-marketing-guide.html)、GitHub、维基百科 (https://zhangwenbao.com/wikipedia-bans-ai-generated-content-seo-impact.html)等) - 确保Organization实体与发布的内容之间有明确的publisher/author关联 Schema完整性审计: - 使用Google的Rich Results Test检查代表性页面的Schema输出 - 使用Schema.org Validator验证JSON-LD语法和类型正确性 - 检查是否存在空字段或占位符数据 内容类型覆盖检查: - 确保所有重要的自定义文章类型(Custom Post Type)都有对应的Schema支持 - 如果使用WooCommerce,确保产品Schema包含完整的定价、库存、品牌等信息 - 如果有事件、食谱等特殊内容类型,确保安装了对应的Schema扩展插件 关系图谱一致性: - 检查不同页面上同一实体的@id是否保持一致 - 确保没有"孤岛实体"——即没有被任何其他实体引用的独立节点 - 验证层级关系的合理性:Organization到Person到Article到Product ## 5步实战部署:从启用到验证AI Agent接入 把前面的概念落地到一个可复现的5步流程。这是保哥在3个WordPress站点(保哥笔记站、1个DTC品牌站、1个B2B SaaS站)上验证过的标准化部署路径。 ## 升级Yoast并启用Schema聚合 登录WordPress后台,进入"插件 - 已安装的插件",找到Yoast SEO,点击"更新"升级到27.1+版本。升级完成后会自动弹出新功能介绍界面,按引导启用Schema Aggregation功能即可。 启用后立即访问https://你的域名/wp-json/yoast/v1/schema-aggregator/get-xml,正常情况下浏览器会返回一个XML索引文件,列出按内容类型(post、page、product等)划分的Schema端点。如果返回404或权限错误,先检查Yoast的Schema主开关是否启用、再检查WordPress REST API是否被某些安全插件拦截。 ## 审计现有Schema数据质量 启用聚合功能不代表数据质量自动达标。立即用Google Rich Results Test和Schema.org Validator对站点的10-20个代表性页面(首页、最热门文章、典型产品页、作者归档页)做一次完整审计。重点检查:每篇文章是否都有完整的Article schema;每个author是否都有可识别的Person schema;publisher是否正确指向Organization;产品页面是否包含Product schema完整字段。 保哥在3个站点的审计中发现,平均30%的页面存在Schema字段缺失或关系断裂问题——这些问题在聚合输出中会被放大,必须先修复再谈接入Agentic Web。 ## 补全实体的sameAs链接 这一步是改善实体消歧效果的关键。在Yoast的"作者"和"组织"设置中,为每个核心实体添加sameAs字段,链接到外部权威来源: - 作者的sameAs应该包含:LinkedIn个人页、GitHub账号、Twitter/X账号、维基百科条目(如果有的话) - 组织的sameAs应该包含:维基百科条目、Crunchbase页面、领英企业页、官方YouTube频道 - 产品的sameAs可以指向:Amazon产品页、其他电商平台的对应SKU页面 sameAs是AI Agent判断"网站上的张三"和"维基百科上的张三"是否同一个实体的关键线索。没有这一步,AI Agent即使拿到聚合数据也很难做跨数据源的实体对齐。 ## 用ChatGPT/Claude/Perplexity做对话式查询测试 启用聚合并完成数据补全后,需要验证AI能否真正"读懂"你的网站。打开3个主流AI助手,分别用以下查询测试: - "请告诉我[你的网站域名]上有哪些主要的内容主题,分别由哪些作者撰写" - "[你的域名]最近发布的关于[你的核心话题]的文章有哪些" - "[你的产品类目]在[你的域名]上提供了哪些SKU,价格区间是多少" 记录每个AI助手的回答质量。在保哥的3个站点测试中,启用Schema聚合后AI助手的回答准确率平均提升40%-60%——尤其在"作者-文章关联"和"产品-类目关联"这类需要跨页面理解的查询上。 ## 监控Schemamap端点的爬虫访问 部署完成后通过服务器access log监控Schemamap端点的访问情况。重点关注User-Agent中包含AI爬虫 (https://zhangwenbao.com/ai-crawlers-surpass-googlebot-seo-strategy.html)标识的请求:GPTBot、ClaudeBot、PerplexityBot、Bingbot、Google-Extended等。这些访问的频次和深度直接反映了你的站点是否被Agentic Web生态发现并消费。 保哥的3个站点在启用Schema聚合后6周内,平均GPTBot对Schemamap端点的访问频次从0增长到周均14次,PerplexityBot的访问从0增长到周均22次——说明AI爬虫确实在主动发现和消费这个新通道。 ## 战略视角:Agentic SEO的新范式 ## 从"排名优化"到"可被查询" 传统SEO的核心指标是"排名"——你的页面在搜索结果中排第几?但在Agentic Web时代,更重要的指标可能是"你的网站能否被AI Agent正确理解和引用"。 AI搜索引擎不会给你一个"排名位置"。它们会直接消化你的内容,然后在对话式回答中引用或不引用你。在这个模式下,结构化数据的作用不再是"触发Rich Snippets",而是"确保AI系统能够精确理解你的实体及其关系"。 Schema聚合正是这个转变的技术基础。它让你的WordPress站点从一个"需要被逐页爬取的网站"变成一个"提供结构化API接口的数据源"。 ## 与llms.md的对比 值得注意的是,在AI可读性方面,业界此前已经出现过llms.md的提案——一种类似于robots.txt的文件,告诉AI系统如何处理网站内容。但这种方案主要停留在"权限声明"层面,并没有提供实际的结构化数据接口。 相比之下,NLWeb + Schema聚合的方案更加务实:它不仅声明了网站对AI访问的态度,还提供了一个高效的数据获取通道。AI Agent无需猜测页面内容的含义,因为所有实体和关系都已经以标准化的Schema.org格式准备好了。 ## 对电商和内容站点的特殊意义 Schema聚合对两类站点的影响尤为显著: 电商站点:产品目录天然是结构化的。通过Schema聚合 + NLWeb,AI Agent可以直接查询"你网站上有哪些售价低于200元的蓝牙耳机"并获得精确答案。这意味着你的产品信息可以直接参与AI Agent的购物推荐流程,而不是等待传统搜索引擎爬取和索引。 内容出版站点:新闻网站、博客、知识库等内容密集型站点可以通过Schema聚合让AI系统快速理解整个站点的内容图谱。当用户向AI助手提问时,AI系统可以精准地定位到你站点中最相关的文章和作者。 ## 保哥的优先级行动清单 基于以上分析,以下是建议的优先级行动清单: 第一优先级(本周就做): - 更新Yoast SEO到27.1版本 - 启用Schema Aggregation功能 - 访问Schemamap端点验证输出是否正确 第二优先级(两周内完成): - 审计全站Schema标记质量,修复断裂的实体关系 - 为所有Author添加sameAs属性链接到外部权威来源 - 检查自定义文章类型的Schema覆盖情况 第三优先级(持续优化): - 关注NLWeb项目的进展,评估是否在自己的站点上部署NLWeb实例 - 建立Schema数据的版本控制机制,像管理代码一样管理结构化数据 - 模拟AI Agent的对话式查询,测试你的Schema数据能否支撑准确的回答 ## 技术展望:Agentic Web的基础设施正在成型 回顾这几年的技术演进,可以看到一条清晰的脉络: - 2011年:Schema.org诞生,搜索引擎开始理解网页的语义 - 2019年:Yoast率先在WordPress中实现了站点级Schema图谱API - 2024-2025年:MCP协议标准化,AI Agent的工具调用有了统一的接口规范 - 2025年中:微软推出NLWeb,网站可以直接作为AI Agent的数据源和交互端点 - 2026年3月:Yoast推出Schema聚合,让上亿WordPress站点可以一键接入Agentic Web生态 这不是单一功能的更新,而是一整套Web基础设施的重构。Schema.org是数据层,NLWeb是协议层,MCP是接口层,而Schema聚合是让这些技术栈对普通站长可用的"最后一公里"。 保哥认为,2026年将是Agentic SEO元年。那些今天就开始构建高质量结构化数据、并主动接入AI Agent生态的站点,将在未来的AI搜索格局中占据先机。 这不再是"要不要做Schema"的问题,而是"你的Schema数据质量够不够撑得住AI Agent的查询"的问题。 ## 常见问题解答 ## Schema聚合功能是Yoast SEO付费版独有的吗? 不是。Schema Aggregation是Yoast SEO 27.1+免费版即可使用的功能,不需要购买Premium版。这与Yoast的战略定位有关——他们希望让所有WordPress站点都能接入Agentic Web生态,因此选择把这个基础设施级别的功能开放给免费用户。 ## 启用Schema聚合会拖慢我的WordPress站点性能吗? 不会。Schemamap端点使用了5分钟级别的缓存(Cache-Control: max-age=300),重复请求不会命中数据库。即使是大型站点,首次生成聚合数据的开销也只在300毫秒以内,且对前台页面加载没有任何影响——聚合查询走的是独立的REST API路径,不在用户访问页面的关键路径上。 ## 使用其他SEO插件(如Rank Math、SEOPress)的站点能用Schema聚合吗? 目前Schema Aggregation功能是Yoast独家。如果你使用其他SEO插件,需要等待对方推出类似功能或考虑迁移到Yoast。但从技术原理上看,Schemamap实现并不复杂——预计未来6-12个月内Rank Math、SEOPress、AIOSEO等主流插件都会推出对标功能。 ## 启用Schema聚合后,AI Agent会立即开始爬取我的站点吗? 不会立即。需要1-4周的时间让AI爬虫发现新增的Schemamap端点。可以主动加快这个过程:把Schemamap的URL提交到Bing Webmaster Tools和Google Search Console;在LinkedIn、Twitter等社交平台发文宣布站点支持Schemamap;联系合作的AI Agent项目方主动告知端点地址。 ## 启用Schema聚合后,传统的页面级JSON-LD还需要保留吗? 需要保留。Schema聚合是页面级JSON-LD的"上层聚合视图",但传统的页面级JSON-LD仍然是Google理解单个页面的关键信号。删除页面级JSON-LD会导致Google Rich Results失效、SERP的富媒体卡片消失。正确的姿势是两者并存——页面级JSON-LD服务传统搜索引擎,Schemamap服务AI Agent。 ## 怎么验证AI Agent确实"读懂"了我的Schemamap? 有3种验证方法:第一,在ChatGPT/Claude/Perplexity中用具体的查询测试(如"网站xxx上某个作者发布了哪些文章"),观察回答准确性;第二,监控服务器访问日志中AI爬虫(GPTBot、ClaudeBot、PerplexityBot等)对Schemamap端点的访问频次;第三,部署一个NLWeb实例使用你的Schemamap作为数据源,做对话式查询的端到端测试。 ## Schema聚合对中文站点和英文站点的接入效果有差异吗? 有差异,但差异在收窄。当前AI Agent生态对英文Schema数据的支持更成熟,但中文Schema的支持在2025年已经显著改善。保哥实测中文站点启用Schema聚合后,ChatGPT和Perplexity对中文内容的"实体识别准确率"都有30-40%的提升。Gemini对中文支持仍有差距,但也在快速追赶。中文站点不应该因为这些差距而放弃接入。 ## 权威参考资料 ## WordPress分类和标签怎么用?SEO区别、索引治理与着陆页打法 - URL:https://zhangwenbao.com/wordpress-category-vs-tag-seo.html - 分类:WordPress SEO - 发布:2024-10-15 | 更新:2026-03-09 - 摘要:标签不是越多越好——八成标签页是拖垮你站的薄内容。本文按骨架与网的分工、打标签的克制法则、标签页noindex策略、分类页着陆页化、分类树深度、关键词蚕食、多语言本地化、老站清理八个维度,帮WordPress与独立站把分类法理顺。 - 关键词:WordPress SEO,信息架构,独立站运营,分类与标签 > **TLDR**:摘要:大多数人以为标签是多多益善的好东西,给文章狂打十几个标签,觉得这样“覆盖更多关键词”。真相恰恰相反:一个普通独立站里,八成的标签页都是在拖垮你的站——它们是薄内容、是重复切片、是吞掉抓取预算的垃圾归档。保哥接手过一个美妆独立站,博客攒了三百多篇攻略,却生生造出一千两百个标签页,每个标签底下平均不到两篇文,搜索引擎一看:这站怎么全是空壳页?整体质量评分被硬生生拉下来。分类和标签不是“都用上就对了”,它们一个是骨架、一个是网,用错了位置,再多内容也撑不起排名。这篇把分类与标签的SEO分工、标签页该不该索引、分类页怎么翻身成着陆页、分类树挖多深、泛滥老站怎么收拾,一次讲透。 > 摘要:大多数人以为标签是多多益善的好东西,给文章狂打十几个标签,觉得这样“覆盖更多关键词”。真相恰恰相反:一个普通独立站里,八成的标签页都是在拖垮你的站——它们是薄内容、是重复切片、是吞掉抓取预算的垃圾归档。保哥接手过一个美妆独立站,博客攒了三百多篇攻略,却生生造出一千两百个标签页,每个标签底下平均不到两篇文,搜索引擎一看:这站怎么全是空壳页?整体质量评分被硬生生拉下来。分类和标签不是“都用上就对了”,它们一个是骨架、一个是网,用错了位置,再多内容也撑不起排名。这篇把分类与标签的SEO分工、标签页该不该索引、分类页怎么翻身成着陆页、分类树挖多深、泛滥老站怎么收拾,一次讲透。 分类(Category)和标签(Tag),是每个用WordPress、Typecho这类系统写博客的人天天打交道的两个东西。可真要问“这篇该归哪个分类、打哪几个标签”,多数人是凭手感乱来的。做了二十多年搜索优化,见过太多内容不错的站,就栽在分类标签这套分类法(Taxonomy)的混乱上——文章是好文章,架构却像一团缠死的毛线,搜索引擎理不清,用户也找不着。这事看着琐碎,却直接决定你的站在搜索引擎眼里是“结构清晰的专家站”,还是“一盘散沙的内容农场”。两者的流量差距,往往就是几倍。 ## 分类和标签,到底谁是骨架谁是网? 先把最根本的差别立住,后面所有判断都从这儿往外推。 分类是层级骨架。它是一棵树:有父分类、有子分类,从宽到窄一层层往下分。一个美妆站的分类树可能是“护肤”下挂“面部护理”“身体护理”,“面部护理”再挂“精华”“面膜”。分类的使命是给整站搭出一个清晰的主题层级,让搜索引擎和用户都能顺着树枝找到想要的那片叶子。核心规矩:一篇内容只归一个主分类。归多了,这篇文就被切进好几个归档页,重复内容立刻冒出来,等于自己拿刀砍自己的权重。 标签是平行的网。它没有层级、没有父子,是一组横切的关键词,用来描述内容里那些跨越分类的细节属性。同样一篇“敏感肌精华测评”,分类归在“精华”,但它可能横跨“敏感肌”“抗老”“平价”这几个主题——这些就是标签该干的活:把分散在不同分类下、但有共同细节属性的文章,横向串成一张网。分类是纵向的“它属于哪一类”,标签是横向的“它还沾哪些边”。 维度 | 分类(Category) | 标签(Tag) | 结构 | 有层级、父子树状 | 无层级、平行网状 | 数量 | 少而精,整站几个到十几个 | 按需,但绝不是越多越好 | 归属 | 一篇只归一个主分类 | 一篇可打多个,但要克制 | 必要性 | 必选,是站点骨架 | 可选,没有也能跑 | SEO角色 | 主题枢纽,可做品类着陆页 | 横向聚合,多数该noindex | 把这张表记死,你就抓住了分工的命脉:分类回答“这是关于什么大主题的”,标签回答“这还涉及哪些横切的细节”。一个管纵向归属,一个管横向关联,谁也别抢谁的活。说到内容类型这一层更底下的纵向选择——什么内容用文章、什么用页面,WordPress文章和页面怎么选那篇 (https://zhangwenbao.com/wordpress-pages-vs-posts-seo.html)里专门讲过。文章与页面是第一层,分类与标签这套是架在文章之上的第二层骨架,两层叠起来,才是一个完整、立得住的信息架构。少了哪一层想清楚,整个站的结构都会松垮。 ## 一篇文章该归几个分类、打几个标签? 这是落地时最高频的纠结,给你一套能直接套用的规矩,不用再凭手感。 分类:一篇文章只归一个主分类,最多再挂一个父分类。别贪心。很多人写一篇“平价敏感肌精华推荐”,顺手归进“精华”“敏感肌护理”“平价好物”三个分类,觉得这样能多吃几个归档页的流量。结果呢?这篇文被三个分类归档同时收录,三个归档页内容高度重叠,搜索引擎要么挑一个、要么都打折,权重被自己稀释了。你以为撒了三张网,其实是把一条鱼劈成三半。归一个最贴切的主分类,干净利落,权重不散。 标签:按“跨分类的横切主题”来打,控制在3到5个,宁缺毋滥。判断一个标签该不该打,问自己一句:这个标签下,将来能不能攒够一批真正相关的文章?能,就打;只有这一篇会用到的标签,坚决别建。给一篇文打“2024春季新品”“某某品牌限定”这种一次性标签,等于专门造一个永远只有一篇文的垃圾归档页,纯属给自己添堵。 这里有个反直觉的点值得记牢:标签的价值不在于“描述得多全”,而在于“能不能聚合”。很多人把标签当成内容的关键词清单,恨不得把文章里每个名词都打成标签——这是彻底用反了。标签不是给单篇文做注解的,它是给一群文章做归集的。判断标准永远是“这个词底下能不能站住一队文章”,而不是“这篇文里有没有提到这个词”。想通这一层,你打标签的手就会克制下来。 这里要特别警惕各种“自动打标签”插件和AI工具。它们的逻辑通常是扫描正文、抽取高频词当标签——这恰恰是最容易制造标签泛滥的做法。机器不懂“能不能聚合一队文章”,它只会把每个名词都标上,几百篇文跑下来,轻轻松松给你造出上千个一次性标签。用这类工具不是不行,但一定要人工复核,把那些“只描述单篇、无法聚合”的标签筛掉。工具帮你提速没问题,放任它替你做判断,最后收拾烂摊子的还是你自己。标签这事,宁可手动慢一点,也别让机器飞快地把站搞乱。 ## 为什么说你站里八成的标签页都是垃圾页? 这是标签这套机制自带的最大暗坑,也是独立站质量评分莫名其妙被压低的常见元凶。它不报警,只是闷声拖你后腿。 每建一个标签,WordPress就自动生成一个标签归档页 (https://wordpress.org/documentation/article/posts-tags-screen/)。问题是,绝大多数标签底下只有一两篇文。一个只列着一两篇文章摘要的归档页,在搜索引擎眼里就是典型的薄内容(Thin Content):没有独立价值、和别的页面高度重复、纯粹是系统自动拼出来的空壳。当你的站里这种空壳页占了八成,搜索引擎对整站的判断就是“低质量内容农场”,连带着你那些真正优质的正文也跟着被怀疑——这就是所谓的“一颗老鼠屎”效应,只不过这里是八百颗。 那个“5到10篇门槛”不是随便拍脑袋定的。它背后的逻辑是:一个归档页要有被索引的资格,得先有足够的内容厚度撑起独立价值。低于这个量级,归档页提供的信息还不如直接看那一两篇原文,搜索引擎留它何用?关于“已抓取但未编入索引”这类状态怎么来的、薄归档页在里头扮演什么角色,谷歌索引覆盖状态的判定机制那篇 (https://zhangwenbao.com/gsc-index-coverage-states-discovered-crawled-canonical-mechanism.html)拆得很细,可以对照着看,里头不少状态的根因就是这种薄聚合页。 更要命的是抓取预算。爬虫每天爬你的站,请求次数是有限的。它们把大把次数花在爬这些一两篇文的空标签页上,留给真正赚钱的产品页、攻略文的预算就少了,新内容上线好几周进不了索引,急也没用。清理垃圾标签页,本质上是在给搜索引擎做减法——让它别再为一堆空壳浪费力气,把注意力还给你真正想被收录的内容。做减法这件事,在SEO里常常比做加法更值钱。 给你算个更直观的账:假设你的站有300篇正文、1200个标签页。爬虫每来一次,本该把宝贵的抓取次数花在那300篇正文和它们的更新上,结果四分之三的请求被那1200个空壳标签页吃掉了。换句话说,你辛辛苦苦写的新攻略,要排在一千多个垃圾页后面排队等着被爬——收录慢、更新慢,全是这么拖出来的。标签泛滥不是“多了点无用页面”这么轻描淡写,它是在实打实地抢占你正文的生存资源。想明白这笔账,你就不会再对随手建一个标签这件事掉以轻心了。 ## 标签页到底该不该让搜索引擎索引? 结论先放这儿:默认对所有标签页noindex, follow,只对极少数够格的标签页放开索引。 “follow”这个细节别漏。用noindex, follow而不是noindex, nofollow,意思是:不让这个薄标签页本身进搜索结果,但允许爬虫继续顺着它里头的链接爬到正文页,权重照样流动。要是连follow都掐了,标签页就成了权重黑洞,正文反而更难被发现。这个分寸用Yoast、Rank Math这类插件在“搜索外观—分类法”里一键设,把标签整体默认noindex,再单独给够格的标签开绿灯。具体到noindex怎么正确实现,可以对照谷歌官方关于合并重复网址的说明 (https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls)里的相关处理。 什么样的标签够格放开索引?同时满足这几条,缺一不可: - 底下有10篇以上真正相关的优质内容,归档页内容厚实,点进去像个正经专题而不是空架子; - 这个标签词本身有人搜、有真实搜索意图(比如“敏感肌”是个真实的搜索词,“2024春季新品”不是); - 你愿意给这个标签页配上独一无二的标题、描述和一段原创导语,把它当个正经着陆页来养,而不是发完就不管。 三条全中,才放开索引;满足不了,就老老实实noindex。设完别忘了回头用网址检查工具抽查几个标签页,确认noindex真的生效了,而不是插件装了个样子——见过太多人以为设了就完事,结果插件配置冲突,noindex根本没下发,白忙一场。 noindex之外还有一步常被漏掉:把这些标签页从sitemap里排除。sitemap是你主动递给搜索引擎的“重点页面清单”,要是你一边给标签页设了noindex、一边又把它们塞进sitemap,等于一边说“这页别收”一边又把它推到爬虫面前,自相矛盾,白白消耗抓取预算。正确做法是noindex的页面就别进sitemap,让sitemap里只留你真心想被收录的正文和够格的着陆页。Yoast、Rank Math这类插件在设了分类法noindex后,通常会自动把它们移出sitemap,但设完最好打开sitemap文件亲眼确认一遍,别想当然地以为插件都替你办妥了。 ## 分类页怎么从“重复内容”翻身成“品类着陆页”? 分类页比标签页金贵,因为它是主题骨架,天生有当品类着陆页排名的潜力。但前提是你得先治好它自带的重复内容病,不然它就是个排不上去的鸡肋。 分类归档页的重复内容问题出在两处:一是它默认自动抓取每篇文的开头一段当摘要,这些摘要拼起来就是别处已有内容的复制;二是分页(第2页、第3页……)会生成一串高度相似的URL。治理动作是这样几条,每条都配好验证方法: - 给分类页写独一无二的标题和元描述。别让所有分类页套同一个模板标题,那样它们在搜索引擎眼里几乎是同一个页。做完用搜索结果预览工具看一眼实际显示效果对不对。 - 给分类页加一段原创的分类导语。在归档列表上方放一两百字真人写的介绍,说清这个品类是什么、有哪些值得关注的子主题,让这个页面有了别处没有的独立内容——这是它能排名的根。 - 用手写摘要替代自动截取。给每篇文配一段独立的摘录(Excerpt),避免归档页摘要和正文开头一字不差地重复。 - 处理好分页的规范化。分页URL用自引用canonical,别一股脑全指向第一页(那是个常见的错误操作,会让第2页之后的文章在索引里凭空消失)。 怎么给WordPress的分类页定制这些标题、关键词、描述字段,WordPress分类目录SEO自定义TDK的现代化方案 (https://zhangwenbao.com/wordpress-categories-seo-add-custom-titles-keywords-descriptions.html)那篇讲了termmeta和REST字段的具体落地做法。把这套做扎实,分类页就能从“爬虫眼里的重复负担”翻身成“能排品类大词的流量入口”——一个美妆站的“精华”分类页要是养到能排“精华推荐”这种大词,带来的流量比单篇测评高一个量级。这是标签页给不了的战略价值。 还有个常被忽略的动作:给分类页主动织内链。分类页不像文章会自动进“相关文章”模块,它得靠你手动把它挂进导航、织进相关文章的正文里。一个没人链向它的分类页,就算优化得再漂亮,也是座孤岛页面——搜索引擎要么爬不到,要么爬到了也觉得它无足轻重。每养一个重点分类页,就在几篇高权重的相关文章里自然地链向它,再把它放进主导航,让权重从四面八方往它身上汇。内链给够了,分类页的排名才托得起来;给不够,那就是空有一身好装备却没人搭理的孤魂。 ## 分类树该挖多深?三层基本就是天花板 分类是层级树,那是不是分得越细越好、挖得越深越专业?恰恰相反,分类树挖太深,是另一个常见翻车点。 问题出在两头。一头是 URL路径:分类层级会反映到URL里,挖到第四第五层,URL就变成 /skincare/face/serum/anti-aging/sensitive/ 这种又长又绕的串,用户看着头晕,权重也被一层层稀释。另一头是归档页厚度:层级越深,每个末端分类底下分到的文章就越少,又回到了薄内容那个老问题——你以为分得专业,其实造出一堆只有两三篇文的深层空壳分类。 保哥的经验值是:分类树控制在两到三层,绝大多数独立站三层就是天花板。第一层是大品类(护肤、彩妆),第二层是子品类(精华、面膜),真有必要再分第三层。超过三层,先别急着建,问自己:这个末端分类底下三年内能不能攒够十几篇文?攒不够,就把它降级成一个标签,或者并回上一层。分类宁可扁平一点、每个节点都厚实,也别为了显得专业挖出一棵枝枝丫丫却全是空壳的树。 层级URL还有个隐藏福利:它天然就是一条面包屑。/skincare/serum/ 这样的路径,搜索引擎顺着就能读出从属关系,给你的页面在搜索结果里带上面包屑导航。但这个福利只在层级合理时成立——挖太深,面包屑长到一行放不下,反而成了负担。深度这件事,克制就是专业。 ## 分类和标签会互相抢排名吗? 会,而且这是个隐蔽的内耗。它有个专门的名字:关键词蚕食(Keyword Cannibalization)。 典型场景:你有一个分类叫“精华”,又手贱建了个标签也叫“精华”。两个归档页瞄准同一个关键词,内容还高度重叠,搜索引擎面对“精华”这个查询,不知道该推哪个,干脆两个都不给好排名,或者今天推这个明天推那个,排名飘忽不定。你以为做了两个页面双保险,其实是让它俩自相残杀,谁也别想赢。 避坑的原则很简单:分类和标签的命名绝不撞车,瞄准的关键词要明确区隔。分类用宽泛的品类大词(精华、面膜),标签用横切的属性词(敏感肌、抗老、平价)。一个管纵向品类,一个管横向属性,词不重叠,自然就不会打架。如果历史上已经造出了同名的分类和标签,留分类、并标签——把那个标签底下的文章重新归一归,标签删掉或合并,再做好301,让权重往分类页那边汇。 怎么提前发现蚕食?有个土办法很管用:在谷歌里搜 site:你的域名 关键词,看同一个词底下有没有冒出好几个你自己的归档页在打架。要是一个查询返回了你站内的分类页、标签页好几个结果,那就是蚕食的信号灯亮了。更系统的做法是定期把分类和标签清单导出来比对,凡是命名相近、主题重叠的,趁早合并。蚕食这东西越早治成本越低,拖到一堆页面互相缠死,再理就得伤筋动骨。分类法这套要像修剪盆栽,定期动手,别等长成一片乱草丛才想起来管。 ## 标签还能反过来当“主题枢纽页”用吗? 能,这是标签的进阶玩法,也是把“垃圾标签”逆转成“流量资产”的关键一招。 前面说八成标签页是垃圾,那剩下两成怎么用出价值?思路是精选少数高价值标签,把它们养成主题枢纽页(Hub)。挑一个真实有搜索量的属性词,比如“敏感肌护肤”,把站内所有相关的优质文章用这个标签串起来,再给这个标签页配上原创导语、清晰的内链结构、合理的内容排序——它就从一个自动生成的空壳,变成了一个围绕“敏感肌护肤”这个主题的内容中枢,既能自己排名,又能把权重分发给底下的每篇文,一举两得。 实现这种标签聚合页,技术上有讲究。WordPress默认的标签相关文章调用经常用了低效甚至反模式的写法,拖慢页面还不准。保哥之前专门拆过这块,WordPress标签相关文章的实战那篇 (https://zhangwenbao.com/wordpress-adds-related-article.html)讲了怎么用WP_Query重写、加三层缓存、用Jaccard相似度提升相关性,想把标签页做成真正的枢纽页可以接着看。记住一句话:标签不是不能索引,是绝大多数不配;少数配得上的,要往死里养,养成站内的内容地标。 哪些标签值得这么养?给你几个判断信号:它对应一个真实的细分人群或场景(比如“孕妇可用”“油痘肌”这种用户会主动搜、还会反复回来看的词);它能横跨多个分类把内容聚起来(“平价好物”可以横切护肤、彩妆、工具);它背后有持续产出的内容供给,不是一锤子买卖。符合这几条的标签,一个站有那么三五个、十来个就够了,把它们当成微型专题站来运营——配导语、配内链、配定期更新的内容排序。剩下那几百个标签,安安静静noindex待着就行。养精兵,别养乌合之众,这是标签运营的核心心法。 ## 多语言美妆站,分类和标签怎么本地化? 出海美妆站迟早要做多语言,这时候分类和标签的规划又多了一层讲究,搞砸了整个分类法在非英语市场就是一团乱码。 最常见的翻车点是别名(slug)没本地化。很多人图省事,德语站、法语站的分类URL里还夹着一串英文slug,甚至是拼音,比如德语用户看到的精华分类URL是 /de/jinghua/。这既不利于当地用户理解,也削弱了URL里的语义信号——搜索引擎读不出这个slug和德语搜索词的关联。正确做法是每种语言的分类、标签都配本地化的slug,让URL在每个市场都说当地话。 结构上的原则是:每种语言各有一套独立的分类树和标签体系,再用hreflang把对应关系焊起来。不要试图让多语言共用一套分类、只翻译显示名——那样URL和归档机制会乱套。具体到操作: - 每种语言独立建分类树,slug用当地语言,层级深度同样控制在两到三层; - 标签体系也各做各的,别把英文标签机器翻译一遍硬套,不同市场的关注属性可能根本不同(欧美在意“纯素”“无残忍测试”,东亚市场更在意“美白”“抗老”); - 分类页的原创导语必须是原生撰写,不是把英文导语翻译过来——本地化的搜索意图和表达习惯,机器翻译接不住。 说白了,多语言站的分类标签规划,是把单语言这套“骨架加网、克制深度、治理薄页”原封不动复制到每种语言,再用hreflang串起来。地基逻辑不变,只是要诚实地为每个市场重做一遍,而不是翻译了事。偷懒翻译出来的多语言站,搜索引擎一眼就看穿是同一套东西换了层皮。 ## 已经标签泛滥的老站,怎么收拾? 多数人读到这儿会发现:坏了,我的站早就标签泛滥了。别慌,收拾是有章法的。那个一千两百个标签的美妆站,保哥就是这么一步步理顺的。 第一步,盘点。导出所有标签和每个标签下的文章数,按文章数排序。你会看到一条触目惊心的长尾:少数标签底下几十篇文,海量标签底下只有一两篇。这条长尾就是你要动手的地方,心里先有个数。 第二步,分三类处理。底下文章多、词有搜索量的,留下来精养成枢纽页;底下有几篇文、但主题相近能合并的,合并到一个标准标签(比如把“敏感肌”“敏感皮肤”“敏感肌肤”这三个意思一样的合成一个);底下只有一两篇、纯属一次性的,直接删。这一步要狠得下心,舍不得删,就永远理不干净。 第三步,处理好删除和合并后的善后。删标签会留下死链,被删标签页的URL要么做301跳到合并后的标签或相关分类,要么确保它返回正确的状态码,别让搜索引擎反复来撞墙浪费抓取。合并标签时,把文章重新打标、旧标签301到新标签,权重一点不浪费地导过去。 那个美妆站理完之后,标签页从一千两百个缩到不到两百个,每个都内容厚实。三个月后整站的抓取效率明显提升,新发的攻略文进索引比以前快了不少——因为爬虫不再被一千个空壳页拖着空转了。判断收拾得有没有效,盯三个指标:抓取统计里归档页的请求占比有没有降、整站被索引页数里薄页占比有没有降、新内容的收录速度有没有变快。三个都往好的方向走,才算真正理顺了。 ## AI搜索时代,分类和标签谁更像“实体”? 这是近两年冒出来的新维度,也是这两年边做边琢磨的方向。当搜索越来越多地由AI来组织答案,分类和标签在“被机器理解”这件事上的角色又分了岔。 分类更接近实体的层级。一棵清晰的分类树,本质上是在告诉机器“这个领域由哪些子主题构成、它们之间是什么从属关系”——这正是知识图谱和大模型理解一个领域时需要的结构。分类树做得清晰、命名规范、深度克制,等于给AI喂了一份现成的领域地图,它在组织相关答案、判断你这个站的主题权威性时,会更容易认账,也更可能在回答里引用你。 标签更接近实体的属性。横切的属性标签,描述的是内容在多个维度上的特征。养得好的属性枢纽页,能成为某个细分主题下被引用的来源。两者配合:用规范的分类树立起领域骨架,用精选的属性标签补上横切维度,再把这套结构通过清晰的内链和结构化数据表达出来——这样的站,无论是给传统搜索还是给AI看,都是一个结构分明、容易被理解和引用的专家站,而不是一团理不清的乱麻。 说到底,分类和标签从来不是“都用上就好”的二选一,而是各管一摊的分工。分类立骨架、定纵向归属、克制深度,标签织属性网、补横向关联,剩下的垃圾标签该noindex就noindex、该删就删。把这套理顺,你的内容才不会在自己造的归档迷宫里互相稀释,而是顺着清晰的结构,把权重一层层送到该去的地方。结构这东西,理顺一次,受益好几年。 ## 国内站从织梦、帝国搬到WordPress,分类标签最容易栽在哪? 国内做内容站的,早年十有八九是从织梦(DedeCMS)、帝国CMS、ZblogPHP这类系统起家的。这几年要做出海、要上多语言、要接更现代的主题生态,搬家到WordPress几乎是必经一步。可保哥经手的搬家项目里,分类标签这一块翻车的比例高得吓人——不是数据丢了,是搬完之后整个分类法(Taxonomy)变成一团乱麻,搜索引擎重新认站,老排名哗哗往下掉。 第一个坑是栏目与分类的概念错位。织梦的“栏目”和WordPress的“分类”看着像,底层逻辑不一样:织梦栏目天生绑定一套独立的列表模板和URL目录,很多老站把栏目当成了页面在用,底下挂着大量单页内容。直接一对一映射成WordPress分类,结果就是一堆本该是独立页面的东西全被塞进了归档页,归档页瞬间臃肿、重复内容暴增。正确做法是搬家前先把旧栏目盘一遍,哪些是真分类、哪些其实是单页、哪些该降级成标签,分门别类对应过去,别图省事一键全导。 第二个坑是tag全量导入造成的泛滥。帝国、织梦的老站往往积了成千上万个tag(很多是早年为了堆关键词随手打的),搬家插件默认会把这些tag原样导进WordPress,一导就是上万个标签页,瞬间满足前面说的“八成是垃圾页”的所有特征。保哥的硬规矩是:搬家时tag不全量导,先在旧库里按文章数排序,只导文章数不低于5的,剩下的长尾tag全部丢掉,搬完再按需重建。导进来容易,清出去就得一个个做301,费时十倍。 第三个坑是URL结构变了却没做跳转。织梦的分类URL多是/list-12-1.html这种带ID的结构,WordPress换成/category/skincare/的语义结构,两套URL对不上。搬家后旧的分类页URL全成了死链,老排名和外链权重一起蒸发。这一步必须在搬家当天就把旧分类URL到新分类URL的301映射表做全,一条都不能漏——这是搬家项目里最不能省的活,省了就是拿几年积累的权重去填坑。 ## 一刀切把标签全noindex,为什么有人反而掉了流量? 前面反复说“默认对标签页noindex”,但这话有个要命的前提常被忽略——是“默认noindex,再给够格的开绿灯”,不是“无脑一刀切全部noindex”。保哥见过不止一个站,读了几篇SEO科普就热血上头,用插件把所有分类、所有标签整体noindex,结果一两个月后自然流量不升反降,急得来问怎么回事。 翻车的根子在于:他们站里本来就有几个标签页或分类页是在实打实带流量的——可能是早年无心插柳养厚的某个属性聚合页,已经排在某个长尾词前列、每月稳定进几百个访问。一刀切noindex,等于亲手把这几个正在下蛋的页面从搜索结果里抹掉,流量当然掉。SEO里最忌讳的就是这种“听了个原则就全站套用”的操作——原则是对的,但执行前你得先盘清楚自己站里哪些归档页其实是资产。 正确的顺序是反过来的:动手前先用GSC的“页面”报告或者第三方工具,把所有分类页、标签页按近三个月的点击和展现拉个清单。先把带流量、有排名的那几个挑出来保护好(这些就是该精养成枢纽页的种子),剩下那些零点击的空壳页再批量noindex。先识别资产,再做减法,这个顺序错了,减法就会减到自己的肉上。 还有个相关的翻车变种:noindex之后又手贱把这些标签页从导航和内链里全部撤掉。noindex只是不让标签页自己进搜索结果,但它身上的follow还在帮正文传递权重;你要是连内链入口都拔了,等于把权重流动的管子也掐断了,正文反而更难被发现,原本还能给正文导权的页面彻底成了孤岛页面。减法要做在“索引”这一层,别一路砍到“链接”那一层——这两层是两码事,混在一起砍,掉的就不止是标签页了。 ## 常见问题解答 一篇文章到底能不能归多个分类? 技术上能,但SEO上强烈不建议。归多个分类会让这篇文被多个分类归档同时收录,归档页内容高度重叠造成重复内容,权重被自己稀释。规矩是一篇只归一个最贴切的主分类,最多再挂它的父分类。 标签和分类可以用同一个词吗? 绝对不要。同名的分类和标签会瞄准同一个关键词、内容高度重叠,造成关键词蚕食,搜索引擎不知道推哪个,结果两个都排不好。分类用品类大词,标签用横切属性词,命名明确区隔。 所有标签页都要noindex吗? 默认对所有标签页用noindex, follow,只对极少数够格的放开索引。够格的标准是:底下有10篇以上优质内容、标签词本身有搜索量、你愿意给它配原创导语当正经着陆页养。满足不了就noindex。 分类树分到几层比较好? 两到三层,绝大多数独立站三层就是天花板。挖太深URL又长又绕、权重被稀释,末端分类还容易变成只有两三篇文的薄页。宁可扁平一点每个节点都厚实,也别为显得专业挖出一棵全是空壳的深树。 删掉一堆没用的标签,会不会影响SEO? 正面影响居多,前提是做好善后。删标签会留下死链,被删标签页URL要做301跳到合并后的标签或相关分类。清理掉大量空壳标签页能提升抓取效率、改善整站质量信号,新内容收录反而更快。 一篇文章打几个标签合适? 3到5个,宁缺毋滥。判断标准是这个标签未来能不能攒够至少5到10篇真正相关的文章,以及它能不能聚合成一队内容。只有这一篇会用到的一次性标签坚决别建。 ## 权威参考资料 ## WordPress文章和页面怎么选?讲透收录、URL与权重的决策逻辑 - URL:https://zhangwenbao.com/wordpress-pages-vs-posts-seo.html - 分类:WordPress SEO - 发布:2024-07-09 | 更新:2026-02-14 - 摘要:文章还是页面选错了,权重会在归档稀释、URL定型、内链截流三处悄悄漏光。本文按决策树、URL与归档、CPT产品页、枢纽辐条内链、hreflang多语言、AI引用六个维度,帮WordPress与独立站运营者把内容放到对的位置。 - 关键词:WordPress SEO,信息架构,内容类型,独立站运营 > **TLDR**:摘要:多数人纠结“这条内容该发文章还是发页面”,以为选错了无非是后台点错一个按钮,改回来就行。真正的代价从来不在按钮上,而藏在三个地方:URL结构定型后难改、归档页悄悄稀释你的抓取预算、内链权重被错误的内容类型截流。保哥带过的一个户外装备独立站,就因为把几十个促销落地页全做成了“文章”,半年后发现这些页面在搜索结果里被日期归档反复挤压,权重散得到处都是,广告质量得分跟着往下掉。这篇把文章与页面的SEO分野讲透:不是教你认识两个按钮,而是给一套“什么内容用什么类型”的决策逻辑,外加归档治理、产品页该用自定义类型、内链怎么织不漏、多语言站怎么搭、AI搜索时代谁更容易被引用这些源头上没人讲的坑。 > 摘要:多数人纠结“这条内容该发文章还是发页面”,以为选错了无非是后台点错一个按钮,改回来就行。真正的代价从来不在按钮上,而藏在三个地方:URL结构定型后难改、归档页悄悄稀释你的抓取预算、内链权重被错误的内容类型截流。保哥带过的一个户外装备独立站,就因为把几十个促销落地页全做成了“文章”,半年后发现这些页面在搜索结果里被日期归档反复挤压,权重散得到处都是,广告质量得分跟着往下掉。这篇把文章与页面的SEO分野讲透:不是教你认识两个按钮,而是给一套“什么内容用什么类型”的决策逻辑,外加归档治理、产品页该用自定义类型、内链怎么织不漏、多语言站怎么搭、AI搜索时代谁更容易被引用这些源头上没人讲的坑。 先把话挑明:文章(Post)和页面(Page)这两个概念,几乎每个用WordPress、Typecho这类内容管理系统建独立站的人第一天就会碰到,但能在SEO层面把它们说清楚的人不多。做了二十多年搜索优化,经手的出海独立站里,因为内容类型用错导致收录混乱、权重分散的,比想象中多得多。这不是新手才犯的错——不少运营了三五年的站,后台归档页一抓一大把重复内容,根子就在最初没想明白这件小事。它小,却像地基里的一道裂缝,越往上盖问题越大。 ## 文章和页面,差的根本不是“有没有日期”? 翻开大部分教程,区分文章和页面就一句话:文章有发布日期、会进博客流,页面是静态的、没有时间。这话没错,但它只描述了表象,没碰到SEO真正在意的内核——连 WordPress官方对页面(Pages)的说明 (https://wordpress.org/documentation/article/pages/),落脚点也在它和文章的归档、模板差异上,而不是“有没有日期”这么浅。日期只是结果,不是原因。 从搜索引擎的视角看,文章和页面的差别其实是这样四条: - 归属关系不同。文章天生属于分类法(Taxonomy)体系——它必须归进某个分类,可以打标签,会被分类归档页、标签归档页、日期归档页、作者归档页反复聚合。页面则是孤立的,不进任何归档,只靠你手动织的内链和导航活着。 - 时间轴属性不同。文章是“时间轴内容”,搜索引擎会读取它的发布与更新时间,把它放进新鲜度(Freshness)的判断里。页面没有强时间信号,它被默认当作“常青节点”,一立起来就该长期稳定地待在那里。 - 模板自由度不同。页面可以套用完全不同的模板,做出独立的版式——这正是落地页、活动专题需要的。文章基本只能跑主题给定的单篇模板,侧边栏、评论区、相关文章一个都甩不掉。 - 可订阅性不同。文章会进RSS/Atom订阅流、会被“最新文章”“相关文章”模块抓取,天然有内容分发的命。页面进不了这些流,它不指望被订阅,只指望被搜到、被链到。 把这四条记住,你就会发现“有没有日期”只是其中一小块。决定一条内容该用哪种类型的,是它在你整个站点信息架构里扮演什么角色——是要持续被聚合、被订阅的流水内容,还是要长期稳定、独立成站的锚点。角色定了,类型自然就定了。 ## 一篇内容到底该用文章还是页面?给你一套决策逻辑 与其背“静态用页面、动态用文章”这种含糊的口诀,不如用几个能直接判断的问题过一遍。保哥这些年带团队就用这套,落到每一条内容上都能秒出答案,不用再凭感觉拍脑袋。 问自己这几个问题,命中任意一条偏“是”,就倾向用文章: - 这条内容会持续迭代、需要标注更新时间吗?(比如“2026年最新关税政策解读”) - 它需要被读者订阅、进“最新”“相关”这类流量分发吗? - 它属于某个内容专题、需要被分类聚合成簇吗? - 它的价值有一部分来自时效性吗? 反过来,命中下面这些就倾向用页面: - 它是常青的、内容三年后基本不变吗?(关于我们、退换货政策、品牌故事) - 它需要独立的版式、要做转化落地吗? - 它是站点结构里的固定锚点、要进主导航或页脚吗? - 它需要层级关系、是某个父页面下的子页面吗? 还有第三条路,很多人压根没想到——如果它是产品、案例、客户评价这种成规模的结构化内容,既不该用文章也不该硬塞进页面,而应该用自定义文章类型(Custom Post Type,简称CPT)。这一点后面单开一节讲,因为独立站在这里栽跟头的最多。 这套判断的好处是,它不让你在“静态还是动态”这种模糊词上打转,而是直接问内容的角色与命运。见过太多人把“品牌故事”做成文章,结果它被夹在一堆促销推文中间,发布三个月后就沉到归档第八页,再也没人点开——明明它该是一个永远挂在导航里的页面,一个能反复被新访客读到的品牌锚点。一念之差,命运两样。 ## 为什么页面的URL天生比文章更“短平快”? URL结构是文章与页面差异里最容易被低估、却最难回头改的一块。一旦内容发出去被收录了,URL再动就要做301跳转、要承担权重损耗,所以最好一开始就想清楚,别等收录了几百页才后悔。 在WordPress里,文章的永久链接(Permalink)受全局结构控制,常见的几种长这样: 默认结构: /?p=123 日期型: /2024/06/18/sample-post/ 带分类型: /outdoor-gear/sample-post/ 纯名称型: /sample-post/ 而页面的URL不吃这套全局结构,它永远跟着层级走。一个父子结构的页面,URL天然就是路径式的: 父页面: /about/ 子页面: /about/team/ 孙页面: /about/team/founder/ 这里藏着两个对SEO很实在的好处。第一,页面的层级URL本身就是一条天然的面包屑,搜索引擎顺着 /about/team/ 这样的路径就能读出从属关系,不需要你额外铺设备。第二,页面URL里不会被塞进日期,而文章如果用了日期型永久链接,/2024/06/18/ 这段会让这条URL看起来有保质期——对常青内容是负担,因为读者和搜索引擎都会下意识觉得“这是2024年的旧东西,还能信吗”。 保哥的建议很直接:文章的永久链接一律用纯名称型 /%postname%/,把日期从URL里彻底拿掉;落地页、政策页、品牌页这些用页面,让它们吃到层级URL的红利。如果你的站已经在用日期型结构,想改成纯名称型,务必先把旧URL到新URL的301映射做全——这一步漏了,等于把多年攒下的收录和外链权重一把扔进水里。怎么验证迁移没出岔子?发布后用Google Search Console的网址检查工具逐条点旧链接,看是否正常301到新地址,再盯一两周抓取统计里的404曲线有没有翘起来。曲线平的,才算落了地。 ## 归档页正在悄悄稀释你的抓取预算? 这是文章这个内容类型自带的“暗债”,也是独立站收录出问题时最常被忽略的源头。它不报警,只是慢慢拖。 每发一篇文章,WordPress默认会顺手生成或更新好几个归档页:它所在的分类归档、它打的每个标签的标签归档、它发布那个月的日期归档、还有作者归档。这些归档页本质上都是同一批文章的不同切片——内容高度重叠。搜索引擎的爬虫预算(Crawl Budget)是有限的,它们爬这些重复度极高的归档页,就少爬了你真正想被收录的正文页。更糟的是,这些薄弱的归档页一旦被索引,还会反过来摊薄整站的质量信号,让本来不错的正文也跟着背锅。 关于“已抓取但未编入索引”这类状态到底怎么来的、归档页在其中扮演什么角色,谷歌索引覆盖各种状态的判定机制之前专门拆过一篇,想深挖的可以去看谷歌索引覆盖状态背后的判定逻辑那篇 (https://zhangwenbao.com/gsc-index-coverage-states-discovered-crawled-canonical-mechanism.html),这里只讲落地动作。 处理归档页,标准打法是这样一张表: 归档类型 | 默认处理 | 什么情况下保留索引 | 日期归档 | noindex, follow | 几乎永远不留,纯新闻站才偶尔考虑 | 作者归档 | noindex, follow | 多作者专家站、要做作者E-E-A-T时保留 | 标签归档 | 多数noindex | 该标签下有5到10篇以上优质文、能当主题枢纽页时保留 | 分类归档 | 建议保留索引 | 分类是主题骨架,优化好可当品类着陆页 | 注意这里全都用 noindex, follow 而不是 noindex, nofollow。差别很关键:follow让爬虫继续顺着归档页里的链接爬到正文页,权重照样流动;如果连follow都掐了,等于把这些页面变成权重黑洞,正文页反而更难被发现。这个分寸,用Yoast、Rank Math这类插件在“搜索外观”里按文章类型逐个设就行,不用碰代码;具体到noindex该怎么正确实现、follow为什么不能一起省掉,可以对照谷歌官方关于用noindex阻止索引的说明 (https://developers.google.com/search/docs/crawling-indexing/block-indexing)。设完别忘了回头用网址检查工具抽查几条归档页,确认noindex真的生效了,而不是插件在装样子。 至于决定保留索引的分类归档,光留着不够,得真把它当着陆页来养。一个能排名的品类归档页,需要独一无二的标题和元描述、一段原创的分类导语(而不是让它空着或自动堆一串摘要)、再用清晰的内链把它挂进导航和相关内容里。怎么给WordPress的分类页定制这些标题、关键词和描述字段,WordPress分类目录SEO自定义TDK的现代化方案 (https://zhangwenbao.com/wordpress-categories-seo-add-custom-titles-keywords-descriptions.html)那篇讲了termmeta和REST字段的具体落地做法,配合这里的归档治理一起用,分类页才能从“爬虫负担”翻身成“流量入口”。 再说抓取预算这笔账具体怎么算清楚。打开Google Search Console的抓取统计报告,看爬虫每天把多少次请求花在了归档页、分页、参数URL这些低价值地址上。如果一个中小独立站,爬虫一大半的预算都耗在日期归档和标签分页上,正文页自然就爬得慢、收录得慢,新品上架好几周还进不了索引。把这些噪声URL用noindex配合robots规则收拾干净,等于把省下来的预算重新分配给真正赚钱的产品页和攻略文——这不是玄学,是实打实能在收录速度上看到回报的调整,尤其对成千上万个SKU的电商站,差别会很明显。 页面在这件事上就干净得多——它不进任何归档,不生成这些重复切片,天生就没有这笔暗债。这也是为什么常青的核心内容用页面更省心:一次立好,长期稳定,不用反复替它擦屁股。 ## 把落地页做成文章,会踩哪些坑? 开头提的那个户外装备独立站,问题就出在这。他们做促销活动图省事,每个活动落地页都用“发文章”的方式建,因为后台熟、模板现成,点几下就上线。坑是慢慢显形的,等发现时已经积了几十页。 第一,这些落地页被卷进了日期归档和分类归档。一个本该独立存在、专门承接广告流量做转化的页面,被搜索引擎当成普通博文,和上百条产品资讯混在同一个归档里互相挤压排名。第二,它们吃不到独立模板,全套用了博客单篇的版式,侧边栏、相关文章、评论区一个不少,转化路径被各种干扰元素切得稀碎,访客看完三屏还没看到“立即购买”。第三,活动一过,这些“文章”还赖在博客流里,新访客点进“最新内容”看到一堆过期促销,体验直接崩,跳出率肉眼可见地往上窜。 反过来的坑也常见:有人把本该是文章的博客内容做成了页面。结果这条内容进不了RSS、进不了“相关文章”推荐、读者没法订阅追更,它在站内彻底变成一座孤岛页面,只能靠你手动织内链续命。一篇需要持续被分发、被聚合的深度攻略,被做成页面,等于自断流量分发的经脉,写得再好也只能孤零零地等人偶然路过。 后来帮那个户外站做的迁移,分三步:先把所有活动落地页从文章转成页面(用类型转换插件批量改,注意保留原URL或做好301);再给转化型页面套上无干扰的独立模板;最后把日期归档、作者归档一律noindex。三个月后,那批落地页的广告质量得分回升,自然搜索带来的精准流量也比之前稳了——因为它们终于不再被一堆博文稀释。判断迁移有没有奏效,盯三个指标:落地页的索引状态是否从“重复内容”转为正常收录、广告平台的着陆页体验评分有没有回升、归档页在抓取统计里的占比有没有降下来。三个都对,才算真翻篇。 ## 独立站的产品页,凭什么不该用“页面”来做? 这是出海独立站最该警惕的一个误区,尤其是从某些建站工具迁过来、习惯了“万物皆页面”思路的卖家。 产品,既不该用文章,也不该用普通页面,它应该用专门的自定义文章类型。在WooCommerce里,product 本身就是一个独立注册的CPT,它有自己的字段(价格、库存、SKU、变体)、自己的归档(商店页、品类页)、自己的结构化数据(Product schema)。这套机制不是摆设——它让产品能输出Product富媒体结果,在搜索里带上价格、星级、库存状态,这是普通页面给不了的待遇。 如果你图省事,用一个个普通“页面”去堆产品,会丢掉一连串东西:丢掉自动生成的品类归档页(也就是能当着陆页排名的类目页)、丢掉产品专属的结构化数据、丢掉变体和库存的原生支持、丢掉和购物车结算的天然衔接。等于你拿一把水果刀去干电锯的活,能砍,但费劲还砍不齐,最后两头不讨好。 这里也牵出文章与页面之外的第三维认知:成规模、强结构、有专属字段的内容,都该用CPT——产品用 product,案例研究可以自定义一个 case,客户评价可以用 testimonial。保哥之前专门讲过产品详情页怎么摆脱供应商的通用文案、做出搜索引擎认可的唯一内容,那篇产品详情页原创内容工程的拆解 (https://zhangwenbao.com/product-detail-page-onpage-seo-unique-content-engineering.html)可以接着看;而品类页、集合页这种靠归档机制吃饭的着陆页怎么优化,则在电商类目页SEO的机制详解 (https://zhangwenbao.com/ecommerce-plp-collection-page-seo-mechanism-complete-guide.html)里讲透了。把产品交给CPT,把品类交给归档,把品牌故事交给页面,把资讯攻略交给文章——各就各位,整站的信息架构才立得住,权重才有清晰的河道可走。 ## 文章和页面的内链权重,到底该怎么织才不漏? 内容类型分清楚了,下一步才是真正决定排名的——内链怎么织。文章和页面在内链网络里扮演的角色不一样,混着用就会漏权重。 一个健康的站,内链结构通常是枢纽与辐条(Hub and Spoke)的样子:少数几个枢纽页负责汇聚和分发权重,大量辐条页负责承接长尾、再把权重回流给枢纽。问题是,哪类内容当枢纽、哪类当辐条? - 页面更适合当枢纽。常青、稳定、主题集中的页面(比如一个“品类总览”或“主题指南”页),适合做内容簇的中心,向下链到一组相关文章,向上挂进主导航,权重在它身上沉淀得住。这种页面也就是常说的基石内容(Cornerstone Content)。 - 文章更适合当辐条。具体、垂直、各打一个长尾的文章,适合做辐条:每篇都从正文里自然链回所属的枢纽页和兄弟文章,把权重一层层往枢纽汇。 这里最容易漏的,是那些没人链向它的内容——也就是孤岛页面。页面尤其危险,因为它不进任何归档、不进“相关文章”,如果你又忘了给它织内链,它就成了一座谁也到不了的孤岛,搜索引擎要么爬不到,要么爬到了也觉得它不重要。每立一个新页面,第一件事就是问:有哪些已有内容该链向它?它又该链向谁?这个动作做顺了,孤岛页面的隐患基本就堵死了。 文章这边漏权重的方式不太一样:它太容易被归档页“假链接”了。日期归档、标签归档里塞满了指向文章的链接,看起来内链很多,其实全是低价值的聚合链,真正该有的、来自正文的上下文内链反而稀缺。所以织内链别数后台显示的链接总数,要数正文里有多少条带语义锚文本、从相关内容自然指过来的链接——那才是搜索引擎真正认账的权重通道。织内链的具体手法和避坑,独立站老SEO圈子里有不少行话,落地时记得让锚文本带主题、别全用“点击这里”这种废话锚。 ## 内容衰退了,文章和页面的刷新策略一样吗? 不一样,而且差别直接影响你sitemap里给搜索引擎的信号。 文章天生适合迭代刷新。一篇“某品类选品指南”随着市场变化要不断更新数据、补新案例,每次实质性更新都该刷新它的modified时间——这个新鲜度信号对时效相关的查询很有用。在sitemap里,这类文章的 changefreq 可以标得勤一点,lastmod 老老实实跟着真实更新走。但要警惕一种作弊冲动:只改个标点就刷新时间。搜索引擎现在能识别“实质更新”和“假装更新”,后者不但没用,频繁了还可能被当成操纵新鲜度的信号反过来扣分。 页面是常青的,但常青不等于发完就不管。退换货政策会随合规要求变、关于我们会随团队变、品牌故事会随定位变。页面的刷新频率低,可一旦内容过时,伤害比文章更大——因为页面往往是转化路径上的关键节点,一条写着旧政策的退换货页,可能直接劝退一个本来准备下单的客户。靠谱的做法是给核心页面排一个季度审计表,逐条核对内容是否还准确,而不是任它们“常青”到长草。 落到sitemap:文章按真实更新动态给lastmod,页面则给一个稳定的、反映最近一次实质审计的时间。两类内容用一套粗暴的全局changefreq是偷懒,搜索引擎会从你历史更新的真实节奏里学到你在不在认真维护——这一点上,诚实比技巧管用。装勤快装不久,爬虫比你有耐心。 ## 多语言独立站,文章和页面的结构该怎么搭? 出海独立站迟早会碰到多语言,这时候文章和页面的分工又多了一层讲究,搭错了hreflang一团乱,搜索引擎根本对不上各语言版本的关系。 核心原则是:每种语言的每个内容,都要有独立URL、独立的文章或页面实体,再用hreflang把它们互相标注成对应关系。不要试图在一个页面里用切换器塞进多语言内容,那样搜索引擎只会看到一个语言版本,其余的等于不存在。 具体到类型: - 政策页、关于我们、品牌故事这些常青页,每种语言各做一个页面,挂进对应语言的导航,用hreflang串起来。它们结构稳定,最适合做各语言市场的固定锚点。 - 本地化的博客、攻略、市场资讯,每种语言各做文章,进各自语言的分类体系和订阅流。注意别把英文原文机器翻译一遍就当本地化——不同市场的搜索意图、案例、关注点都不一样,原生再创作出来的内容才接得住当地的长尾词。 - 产品仍然走CPT,配合多语言插件让每个产品在每种语言下有独立可索引的URL和本地化的Product结构化数据。 一个常见的翻车点:分类和标签的别名(slug)忘了本地化,结果德语站的URL里夹着一串英文分类名,既不利于当地用户理解,也削弱了URL里的语义信号。多语言站的文章与页面规划,本质上是把单语言那套“类型分工 + 归档治理 + 内链织网”原封不动复制到每种语言,再用hreflang焊接起来——地基没打好,盖几层都是歪的。 ## 不用WordPress的站,这套逻辑还成立吗? 会有人问:我的独立站不跑WordPress,是Typecho、Shopify,或者干脆是Headless架构,前面这套文章与页面的分工还管用吗?管用,因为分的从来不是某个系统的某个按钮,而是内容在信息架构里的角色——壳换了,核不变。 挨个平台说: - Typecho。它和WordPress几乎是一套思路:同样分“文章”和“独立页面”,文章一样进分类、标签、日期归档,页面一样独立常青。本站这个博客就跑在Typecho上,分类标签归档要不要noindex、永久链接用不用日期,前面那套打法可以原样照搬,连插件逻辑都大同小异。 - Shopify。概念换了名字,本质一模一样:blog post对应文章、page对应页面、product是独立资源(功能上就是WooCommerce里CPT的角色)、collection是品类归档。Shopify自带的分页、标签、筛选器同样会生成一堆重复URL,canonical和noindex那套治理一个都不能少,只是设置入口从插件挪到了主题和后台。Shopify上商品交叉分类带来的URL膨胀怎么治,独立站圈子里早有成熟解法,思路和归档治理是相通的。 - Headless / Astro / Next这类现代架构。内容类型由你自己在CMS里定义(很多框架叫content collection),自由度更高,但也意味着“常青节点vs时间轴流”的二分得由你亲手设计,没有现成按钮兜底。哪些走稳定URL、哪些带lastmod、sitemap里谁勤谁懒,全要你自己想清楚——平台越灵活,越考验你对类型分工的理解。 所以别把这件事当成“WordPress的特性”来记。文章与页面,说到底是“流水内容”与“常青节点”这对永恒分类在某个系统里的具体名字。换个系统,名字变了,你要做的判断一字不差:这条内容是要被持续聚合订阅,还是要长期稳定独立。想明白这个,用什么平台都不慌。 ## AI搜索时代,文章和页面谁更容易被引用? 这是2024年之后冒出来的新维度,也是这两年边做边观察的方向。当用户的提问越来越多地由AI概览、对话式搜索来回答,被AI“引用”就成了一种新型的可见度。这时候文章和页面的命运又分岔了。 常青的页面更容易成为实体锚点。一个把“某个概念是什么、怎么定义、有哪些要素”讲得清楚、稳定、结构化的页面,正是大模型在组织答案时喜欢抓取和引用的那种来源——它不带时效噪声,定义明确,适合被当作事实依据。这类内容用页面承载,长期稳定,反而比一篇会不断改版的文章更适合沉淀成被引用的权威。 而文章的优势在时效信号。“最新动态”“某政策刚刚变化”这类查询,AI需要新鲜来源,文章带着真实的更新时间戳,正好接得住。两者并不矛盾:把常青的概念、定义、方法论用页面做成稳定锚点,把追踪变化、复盘实战的内容用文章持续更新,再用 llms.md 这类机制把你最希望被引用的核心页面清单告诉AI爬虫——这套组合拳,比纠结“到底用哪个”有意义得多。 说到底,文章和页面不是二选一的对立,而是分工。理解了它们各自的命运——谁进归档、谁吃层级URL、谁带时效、谁当枢纽、谁更易被引用——你才能让每一条内容待在它该待的位置上,让整站的权重顺着你设计的路径流动,而不是在错误的内容类型里漏得到处都是。建站这件事,方向比手速重要,第一步踩稳了,后面才省心。 ## 常见问题解答 已经发布的文章,能直接转成页面吗?会影响SEO吗? 能转,但URL通常会变(文章和页面的永久链接结构不同),所以转换后必须给旧URL做301跳转到新地址,否则会丢收录和外链权重。用类型转换插件批量改,改完逐条用网址检查工具确认跳转正常再收工。 分类归档页到底该不该让搜索引擎索引? 分类归档建议保留索引,因为分类是站点的主题骨架,优化好标题、描述和摘要后能当品类着陆页排名。但日期归档、作者归档一般noindex, follow,标签归档则看该标签下内容够不够多、够不够优。 独立站的产品页用普通页面做行不行? 强烈不建议。产品应该用WooCommerce的product这类自定义文章类型,它自带价格、库存、变体字段和Product结构化数据,能在搜索里输出富媒体结果。用普通页面堆产品会丢掉品类归档、结构化数据和结算衔接。 文章的永久链接用哪种结构对SEO最好? 优先用纯名称型,也就是 /%postname%/,把日期从URL里去掉。日期型URL会让常青内容看起来过期,纯名称型更简洁、更稳定、更利于长期收录。已经在用日期型想换的,记得把301映射做全。 页面没有日期,是不是就不用管更新了? 不是。页面常青不代表内容永远准确,退换货政策、关于我们、品牌故事都可能过时,而页面往往在转化路径的关键节点上,过时信息的杀伤力比博文更大。建议给核心页面排季度审计,定期核对内容时效。 归档页用noindex会不会把整站权重也掐掉? 不会,前提是用noindex, follow而不是noindex, nofollow。follow让爬虫继续顺着归档页的链接爬到正文,权重照常流动;只是不让薄弱的归档页本身进索引。千万别用nofollow,那会把归档页变成权重黑洞。 ## 权威参考资料 ## WordPress换域名后台跳转登不上,三种改法和迁移避坑细节 - URL:https://zhangwenbao.com/wordpress-change-domain-access-management-login-jump-solution.html - 分类:WordPress SEO - 发布:2022-11-23 | 更新:2026-06-01 - 摘要:WordPress换完域名进不去后台,根子在siteurl和home两个字段。本文从原理讲起,给出三种解法:phpMyAdmin直接改wp_options、用WP-CLI或插件做全库替换并处理序列化数据、在wp-config.php用常量应急,再附九条迁站细节和SEO权重转移实测。 - 关键词:WordPress换域名,WordPress后台,WP-CLI,siteurl,域名迁移 > **TLDR**:摘要:WordPress换完域名进不去后台,根子在siteurl和home两个字段。本文从原理讲起,给三种解法——phpMyAdmin直接改wp_options、用SQL批量替换全库并处理序列化数据、在wp-config.php里硬编码常量覆盖,再讲换域名容易被忽略的九个细节、SEO权重转移实测、备份与回滚预案和多站点换域名。 > 摘要:WordPress换完域名进不去后台,根子在siteurl和home两个字段。本文从原理讲起,给三种解法——phpMyAdmin直接改wp_options、用SQL批量替换全库并处理序列化数据、在wp-config.php里硬编码常量覆盖,再讲换域名容易被忽略的九个细节、SEO权重转移实测、备份与回滚预案和多站点换域名。 保哥这两年帮人迁过的 WordPress 站点不下三十个,每一次只要换域名,就一定会有一个用户来问同一个问题:"我新域名能打开首页,但点登录就跳回老域名,根本进不去后台,怎么办?" 网上能搜到的攻略基本都是一句"改 wp_options 表就行",但实际操作起来要踩的坑远不止改一行 SQL 那么简单。本文把我在自家站点和朋友站点上反复跑过的三种方法、每种方法的应用场景、以及迁移时附带要处理的图片路径、邮件签名、Cookie 域、CDN 缓存、SSL 证书等所有相关问题写清楚。读完应该可以一次性把 WordPress 换域名问题解决干净。 ## 为什么换域名后后台会跳转 WordPress 在数据库里存了两个跟域名有关的核心选项,藏在 wp_options 表里: - siteurl —— 这是 WordPress 自己用的安装地址,决定了 wp-admin 的入口、主题样式表 URL、后台资源的加载源。 - home —— 这是站点对外展示的地址,决定了首页、文章、归档页的链接前缀。 当你把站点文件搬到新服务器、改了域名解析、用新域名访问 wp-login.php 时,WordPress 看到 URL 是新域名,但读数据库发现 siteurl 仍然是老域名,就会做一次"安全跳转"——把你跳到 siteurl 指向的地址。这就是后台始终跳到老域名的根因。 同样的逻辑也解释了几个相关现象:换域名后首页能开但样式丢了(CSS URL 还是老域名)、文章里图片 404(图片绝对路径写死了老域名)、提交评论或登录时 Cookie 写不进去(Cookie 域跟当前域名不匹配)。这些问题本质上都是一类:数据库里的旧域名残留没有清理干净。 下面三种方法按从简单到复杂排开,你按自己的能力选一种。 ## 方法一:直接改 wp_options 表的 siteurl 与 home 这是最朴素的做法,适合刚迁移完、数据库里其他地方还没怎么写过老域名的站点。 - 登录服务器或托管面板的 phpMyAdmin。如果用宝塔面板 (https://zhangwenbao.com/bt-panel-automatic-disk-mount.html),左侧"数据库" → 选你的 WP 数据库 → 点"管理"进入 phpMyAdmin。 - 左侧表列表找 wp_options,进入后顶部按"option_name"列排序,或在搜索框里搜 siteurl。 - 双击 siteurl 那一行的 option_value 字段,把老域名改成新域名,回车确认。 - 同样的操作处理 home 行。 - 清空浏览器 cookie,访问新域名的 /wp-login.php,应该能正常登录。 注意几个容易踩的细节: - 新域名要写完整带 https:// 协议头,不要写成 //example.com 或者只写 example.com。 - 末尾不要带斜线 /,写 https://www.new.com 而不是 https://www.new.com/。带斜线会让某些插件的 URL 拼接出现双斜线。 - 如果你站点没装 SSL,写 http:// 也行,但建议趁迁移把 SSL 一起装上,国内国外搜索引擎都已经把 https 当作排名因子。 方法一的缺点是只改了两个核心字段,文章正文里写死的图片绝对路径、菜单项里的页面链接、widget 里的 URL 都没动。如果你站点里图片不多、菜单都是页面 ID 引用而不是绝对 URL、widget 没有自定义 HTML,方法一够用了。否则继续看方法二。 ## 方法二:用 SQL 命令批量替换全数据库 这是迁移老站点最常用的方案。一条 SQL 把所有跟老域名相关的字段一次性换掉。phpMyAdmin 顶部"SQL"标签里粘贴下面命令,依次执行: -- 1. 改 wp_options 的 siteurl 和 home UPDATE wp_options SET option_value = REPLACE(option_value, 'https://www.old.com', 'https://www.new.com') WHERE option_name IN ('siteurl', 'home'); -- 2. 改文章正文里的旧域名引用(图片、附件、自定义链接) UPDATE wp_posts SET post_content = REPLACE(post_content, 'https://www.old.com', 'https://www.new.com'); -- 3. 改文章 GUID(注意:GUID 严格意义上不应该改,但实际很多插件会读它做 URL) UPDATE wp_posts SET guid = REPLACE(guid, 'https://www.old.com', 'https://www.new.com'); -- 4. 改 postmeta 表里的元数据(部分主题/插件会把 URL 存这里) UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, 'https://www.old.com', 'https://www.new.com'); -- 5. 改 commentmeta 表(评论里的链接) UPDATE wp_comments SET comment_content = REPLACE(comment_content, 'https://www.old.com', 'https://www.new.com'); UPDATE wp_comments SET comment_author_url = REPLACE(comment_author_url, 'https://www.old.com', 'https://www.new.com'); -- 6. 改 termmeta(分类与标签的元数据) UPDATE wp_termmeta SET meta_value = REPLACE(meta_value, 'https://www.old.com', 'https://www.new.com'); 这套命令几乎覆盖所有正常情况下会出现 URL 的位置。但还有两个特殊情况要单独处理。 ## 特殊情况一:序列化数据无法直接 REPLACE WordPress 里很多 widget、主题选项、插件设置存在 wp_options 的 option_value 里时,是 PHP 序列化后的字符串,长这样:a:2:{s:5:"title";s:10:"老网站名";s:3:"url";s:24:"https://www.old.com/img";}。注意 s:24 是字符串长度。如果你直接 REPLACE 把 https://www.old.com 换成 https://www.new.com,长度从 24 变成 24(碰巧相同)就没事,但如果新域名比老域名长(比如老的是 old.cn,新的是 www.newdomain.com),s:24 这个长度数字没跟着改,整个序列化字符串会损坏,反序列化时报错。 处理办法两种: - 用专门的工具走全库替换。WP-CLI 有 wp search-replace 命令,自动处理序列化数据: wp search-replace 'https://www.old.com' 'https://www.new.com' --all-tables --skip-columns=guid 跑完之后所有序列化字段会被正确重写。 - 用 Better Search Replace 这个 WP 插件。后台装好后在"工具 → Better Search Replace"里输入新旧域名,勾选所有表,先勾"模拟运行"看效果,确认没问题再去掉模拟跑实际替换。 保哥强烈推荐 WP-CLI 那条命令,比手敲 SQL 安全很多,而且处理速度也快。不会用 WP-CLI 的就用 Better Search Replace 插件,效果一样。 ## 特殊情况二:含老域名的不止一种形式 老站点的数据库里可能同时存在 http://www.old.com、https://www.old.com、http://old.com、//old.com 几种写法。一条 REPLACE 只能替换一种。建议把所有可能的形式都跑一遍: wp search-replace 'http://www.old.com' 'https://www.new.com' --all-tables --skip-columns=guid wp search-replace 'https://www.old.com' 'https://www.new.com' --all-tables --skip-columns=guid wp search-replace 'http://old.com' 'https://www.new.com' --all-tables --skip-columns=guid wp search-replace 'https://old.com' 'https://www.new.com' --all-tables --skip-columns=guid wp search-replace '//old.com' '//www.new.com' --all-tables --skip-columns=guid 跑完之后用 wp db search 'old.com' 全库搜一次,确认没有任何残留。这一步很重要,否则总会有边边角角的 URL 漏掉。 ## 方法三:在 wp-config.php 里硬编码覆盖 这是应急方案,适合"我连数据库都打不开"的极端情况。在网站根目录的 wp-config.php 文件最顶部(紧跟 wpdb_$(date +%F).sql。 - SSL 证书备份:旧域名的 fullchain.pem 和 privkey.pem 复制一份到本地,万一新证书签发失败可以临时回切。 - DNS 记录截图:旧域名的 A、MX、TXT、CNAME 记录全部截图存档,避免改 DNS 后忘了原来什么记录。 有了这四件,万一迁移中途出问题,回滚就是文件还原 + 数据库导回 + DNS 切回,最快 30 分钟回到迁移前状态。我经手的三十多次迁移有两次中途出问题,靠这套预案救了回来。 ## 多站点 WordPress(Multisite)换域名 如果你跑的是 WordPress 多站点(Network),换主域名要单独处理 wp_blogs 和 wp_site 两张表: -- 改主站点表 UPDATE wp_site SET domain = 'www.new.com' WHERE domain = 'www.old.com'; -- 改子站点表(多站点的每个子站都在这里有一行) UPDATE wp_blogs SET domain = REPLACE(domain, 'old.com', 'new.com'); -- options 表里每个子站点都有自己的 wp_2_options、wp_3_options 等 -- 用 WP-CLI 批量处理: -- wp search-replace 'old.com' 'new.com' --network --all-tables 多站点 WP-CLI 必须加 --network 参数才会处理所有子站。少这个参数只会改主站,其他子站还指向老域名。 ## 国内换域名绕不开的备案、解析与缓存三道坎 前面三种方法和九条细节,本质上都在处理“软件层面”的旧域名残留。但保哥发现,真正让国内站点换域名翻车的,往往不是数据库里那几行 SQL,而是国内特有的备案、解析、缓存三道坎。这三道坎一道都绕不过去,而且都得排在改数据库之前考虑。 第一道:备案坎。国内服务器上的网站,工信部 ICP 备案是绑在“域名 + 主体 + 接入商”这个三元组上的。换主域名,等于换了三元组里的域名,新域名如果没接进备案就指向境内 IP,接入商会在 24 到 48 小时内识别到“未备案域名”,直接把 80 和 443 端口阻断,页面根本打不开,这跟 siteurl 跳转完全是两码事。正确顺序是:先去阿里云、腾讯云的备案系统提交“新增网站(原主体)”,拿到新备案号确认通过后再切流量上线;老域名的备案别急着注销,留着继续承载 301 跳转。这里还有个细节,如果新老域名同属一个主体、只是想替换接入域名,走的是“变更备案”而不是“新增网站”,但无论哪种,核验快则 3 天、慢则 20 天,所以它必须排在整个迁移计划的最前面,而不是临到上线才想起来。 第二道:解析坎。国内 DNS 生效严重受运营商 LocalDNS 缓存拖累。你在阿里云、DNSPod 后台把 A 记录改到新服务器,但电信、联通、移动各地的 LocalDNS 并不一定听你设的 TTL,有的会强制缓存 24 到 48 小时。这意味着改完解析的头两天,新老域名是并存的:一部分用户和蜘蛛走新域名,一部分还卡在老域名。所以迁移期老域名的服务器至少要多留 7 天,千万别一改解析就把老站关掉,否则 DNS 还没全球收敛的地区,用户和搜索引擎蜘蛛全都吃 404。保哥的做法是用 dig +trace 配合几个跨运营商的在线检测工具,各地查一遍,确认收敛了再动老站。 第三道:缓存坎。国内 CDN(阿里云、腾讯云、又拍云、七牛)的回源 Host 和缓存 key 经常写死了老域名。换域名后必须进 CDN 控制台改回源配置、刷新并重新预热全部缓存,否则边缘节点吐给用户的还是带老域名的 HTML,数据库改得再干净也白搭。除了 CDN,还有一类容易被忘掉的“国内特供”缓存:微信、QQ 分享用的业务域名、小程序的请求域名、JS 安全域名,全都绑在老域名上。换域名后要去微信公众平台和微信开放平台,把这些白名单逐个改成新域名,否则页面在微信里打不开,或者分享时直接报“不在以下合法域名”的错。这一步在纯技术教程里几乎从不提,却是国内站点换域名后用户投诉最集中的地方。 ## 一次“只改数据库没管备案”的换域名翻车复盘 保哥团队 2024 年接手过一个外贸建站客户,老板急着把又长又拗口的老域名换成一个更短的新域名做品牌升级。开发同学按本文方法二,用 WP-CLI 把全库 REPLACE 得干干净净,新域名在本地和测试机上一切正常,首页、后台、图片路径全对,当天晚上就信心满满地把老站关了。结果第二天一早客服群就炸了:全国大批用户反馈“网站打不开”。 保哥连夜远程排查,发现是两个坑连环爆雷: - 新域名压根没做备案。开发只顾着技术迁移,完全没人管备案这件事。新域名指向境内 IP 后,接入商在不到一天里就识别为未备案域名,把 80 端口阻断了。这时候用 GSC 的 URL 检查和百度抓取诊断去看,蜘蛛抓到的全是接入商返回的拦截提示页,而不是网站内容。 - 老域名关得太早。解析改过去还不到 12 小时,DNS 远没有全球收敛,部分用户的 LocalDNS 还指向已经被关掉的老服务器,等于新域名被备案卡住、老域名又被人为关停,新老两头都瘫。 急救方案是:先把老站重新拉起来、恢复老域名解析,让大部分用户至少能正常访问;同时给新域名补提备案,走了加急通道还是等了 5 天;备案通过后才正式把流量切到新域名并配 301。这一通折腾下来,自然搜索流量掉了整整三周才追平迁移前的水平,期间还接到几个老客户“你们网站是不是倒闭了”的电话,对品牌信任的折损比流量本身更难估量。 这次事故被保哥写进了团队的换域名 SOP,核心就一句:换域名的第一步永远是“先把新域名备案办妥、再切解析、老站至少多留两周”,而大家最害怕的数据库 REPLACE,反而是整个流程里最不容易出事、最可控的一环。把精力全压在改库上、却忽略了备案与解析这两件“非技术但卡脖子”的事,才是国内换域名翻车的真正原因。 为了避免重蹈覆辙,保哥还把上线后的核验固化成一张“当天必查”清单:第一,用手机 4G 网络(而不是公司 WiFi)直接访问新域名,确认接入商没在端口层阻断;第二,在站长平台用真实蜘蛛 UA 做一次抓取诊断,看返回的是正版页面还是拦截页;第三,拿一部手机在微信里点开新域名的分享链接,确认不是灰屏;第四,跨电信、联通、移动各查一次解析,确认 A 记录已经收敛到新服务器。这四步十分钟就能跑完,却能在第一时间发现备案、解析、微信这三类“技术教程不教、却最容易让国内站点翻车”的隐患,比等用户投诉再回头救火主动得多。保哥经手三十多次迁站之后越来越确信一件事:换域名这道题,技术分只占一半,另一半全在国内这套备案与监管的“隐形规则”里,谁把这半张卷子也答好了,迁站才算真正稳。 ## 常见问题解答 ## 方法二的 SQL 命令在 phpMyAdmin 里运行报错怎么办? 多半是表前缀没改对。WordPress 默认表前缀是 wp_,但很多人为了安全改成了别的比如 wp123_。命令里所有 wp_ 前缀都要换成你实际的前缀。在 phpMyAdmin 左侧表列表里能看到完整的表名。改完前缀再跑一次。 ## 用 WP-CLI 命令行报错说找不到 wp 命令怎么办? WP-CLI 不是 WordPress 自带的,需要单独安装。Linux 服务器一条命令安装:curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && chmod +x wp-cli.phar && mv wp-cli.phar /usr/local/bin/wp。装好后 wp --version 能输出版本号即可。如果你用的是宝塔面板,软件商店里搜 wp-cli 直接安装。 ## 换域名后老链接的 SEO 权重会丢吗? 不会,前提是配好了 301 重定向。Google 和百度都明确说过 301 跳转会传递 95% 以上的 PageRank 权重。但是没做 301 直接弃用老域名,权重会快速衰减,3 个月后基本归零。所以 301 是必做的一步,不能省。 ## 子域名的资源(比如 cdn.old.com)也要替换吗? 要。如果你之前用了 cdn.old.com 来加载图片或静态资源,迁移后这些 URL 还是指向老的 CDN,需要在 WP-CLI 替换命令里多加一条 wp search-replace 'cdn.old.com' 'cdn.new.com'。如果新域名没用 CDN,那就替换成 www.new.com 或省略 CDN 直接用主域名。 ## 插件激活信息和许可证里的域名要不要改? 付费插件如 Elementor Pro、WP Rocket 等的许可证绑定老域名的话,需要在插件官网后台手动解绑老域名再绑定新域名,否则插件会显示"许可证无效"。这个操作不在数据库层面,要去插件官网账户中心做。 ## 方法二跑完后还有部分页面跳老域名怎么办? 检查这几个地方:1)主题自定义模板里有没有写死老域名的硬编码(搜源码 grep "old.com");2).htaccess 文件里有没有 RewriteRule 用了老域名;3)某些 cache 插件的配置文件 wp-content/cache/config.php 是否含老域名字符串。这三处不在数据库里,需要 SSH 到服务器改文件。 ## 能不能不换域名只换服务器 IP? 能。换 IP 不影响域名解析以外的任何 WordPress 配置,只需要在 DNS 后台把 A 记录指到新 IP,等待 DNS 全球生效(一般 24 小时内)即可。期间老 IP 上的服务器最好保留几天,避免少数地区 DNS 缓存还没更新的访客访问失败。 ## 写在最后 WordPress 换域名这件事,看上去就是改两个字段,实际牵扯到从数据库到 CDN 到搜索引擎的全链路。本文给的三种方法本质上是一套组合拳:方法三让你先进得去后台,方法二用 WP-CLI 完整替换数据库,方法一适合事后补漏。再加上九条周边细节和 SEO 转移的实测数据,整个迁站流程就能落地。建议第一次迁站的同学按本文清单一项一项打勾,做完之后开无痕模式从 Google 搜你的旧域名关键词,确认搜索结果点开能正确 301 跳到新域名,这次迁移就成了。 ## 权威参考资料 ## WordPress怎么实时推送搜索引擎?百度、Bing IndexNow与异步队列 - URL:https://zhangwenbao.com/wordpress-baidu-active-push.html - 分类:WordPress SEO - 发布:2018-06-28 | 更新:2026-06-01 - 摘要:想让WordPress新文章秒级被收录,正确做法不是简单curl一下百度。本文讲透百度主动推送的接口与配额监控、Bing IndexNow零配置接入、Google Indexing API的官方限制,再给出避免阻塞编辑器的三种异步方案和cron兜底补推漏推链接。 - 关键词:百度推送,IndexNow,百度站长,异步推送,publish_post > **TLDR**:摘要:想让WordPress新文章秒级被收录,正确做法不是简单curl一下百度。本文讲透百度主动推送的API演化与正确域名、配额管理、避免阻塞编辑的异步推送、Bing IndexNow的零配置接入、Google Indexing API的限制与替代,再讲cron兜底批量补推、推送与sitemap什么时候选哪个,以及不该推送的页面类型。 > 摘要:想让WordPress新文章秒级被收录,正确做法不是简单curl一下百度。本文讲透百度主动推送的API演化与正确域名、配额管理、避免阻塞编辑的异步推送、Bing IndexNow的零配置接入、Google Indexing API的限制与替代,再讲cron兜底批量补推、推送与sitemap什么时候选哪个,以及不该推送的页面类型。 WordPress 站点发完文章希望搜索引擎第一时间收录——百度提供"主动推送 (https://zhangwenbao.com/baidu-post-real-time-push-tool.html)"接口,能让 URL 直接进入抓取队列,不用等爬虫自然发现。但网传的"挂 publish_post hook 调 curl 推百度"的代码在 2026 年有几个绕不过去的问题:百度推送 API 域名已迁移、curl 没设超时会卡住编辑器、单次只支持 ≤ 2000 条 URL、没区分新发 vs 更新、Bing IndexNow 和 Google Indexing API 的新机会被完全忽略。 这一篇把"WordPress 实时推送给搜索引擎"这件事重新讲透:百度推送 API 的现代用法(含失败重试、配额监控)、Bing IndexNow 的零配置接入、Google Indexing API 的限制与替代、避免 publish_post 阻塞用户编辑的异步队列做法、推送有效性验证方法、Cron 兜底批量推送等。 ## 百度主动推送:API 演化与正确域名 百度链接提交在 2010-2024 年间经历过几次接口变化。2026 年的标准做法: 接口 | 状态 | 用途 | API endpoint | 主动推送 (PUSH) | 当前主流 | 实时新链接 | http://data.zz.baidu.com/urls | HTTPS 主动推送 | 2022 年起推出 | 同上但 HTTPS | https://data.zz.baidu.com/urls | 快速收录 | 已迁移到 ziyuan.baidu.com | 移动端高优先级 | 需站长平台开通权限 | Sitemap 提交 | 当前主流 | 批量历史链接 | 站长平台 → Sitemap | API 提交(旧接口) | 已下线 | 2018 年前的旧版 | 不要再用 | 原帖代码 http://data.zz.baidu.com/urls 仍然能用,但建议改用 HTTPS 版本——百度逐步在 deprecated HTTP 推送,2026 年下半年可能完全切到 HTTPS。token 在站长平台 → 链接提交 → 主动推送 → 接口调用地址。每个站点 token 不一样,泄漏会被别人冒名推送。 ## 现代化代码:含超时 + 错误处理 + 配额监控 // 推荐放 wp-content/mu-plugins/baidu-push.php,比 functions.php 更稳 if (!function_exists('baidu_push_url')) { function baidu_push_url($post_ID) { // 已推送过不再推 if (get_post_meta($post_ID, '_baidu_pushed', true) == 1) return; $post = get_post($post_ID); if ($post->post_status !== 'publish') return; if ($post->post_type !== 'post' && $post->post_type !== 'page') return; $site = 'yoursite.com'; $token = '【你的 token】'; // 站长平台拿 $url = get_permalink($post_ID); $api = "https://data.zz.baidu.com/urls?site=" . urlencode($site) . "&token=" . urlencode($token); $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $api, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $url, CURLOPT_HTTPHEADER => ['Content-Type: text/plain'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, // 5 秒超时,绝不卡编辑器 CURLOPT_CONNECTTIMEOUT => 3, ]); $raw = curl_exec($ch); $err = curl_error($ch); curl_close($ch); if ($err) { error_log("[BaiduPush] curl 错误: $err url=$url"); return; } $result = json_decode($raw, true); if (!is_array($result)) { error_log("[BaiduPush] 响应非 JSON: $raw"); return; } // 关注几个关键字段 if (isset($result['success']) && $result['success'] > 0) { update_post_meta($post_ID, '_baidu_pushed', 1); update_post_meta($post_ID, '_baidu_pushed_at', time()); error_log("[BaiduPush] OK url=$url remain=" . ($result['remain'] ?? '?')); } else { // 失败原因细分 $reason = ''; if (isset($result['not_same_site'])) $reason .= '域名不匹配 '; if (isset($result['not_valid'])) $reason .= 'URL 非法 '; if (isset($result['error'])) $reason .= '错误码 ' . $result['error']; error_log("[BaiduPush] FAIL url=$url reason=$reason raw=$raw"); } // 配额警报:剩余 < 100 时记录,方便扩容 if (isset($result['remain']) && $result['remain'] < 100) { error_log("[BaiduPush] WARN 配额告急 remain={$result['remain']}"); } } add_action('publish_post', 'baidu_push_url', 10, 1); add_action('publish_page', 'baidu_push_url', 10, 1); // 文章更新时也推(更新过的内容百度会重新评估) add_action('post_updated', function ($post_ID, $post_after, $post_before) { if ($post_after->post_status === 'publish' && $post_before->post_status === 'publish') { // 已发布的更新,重置推送状态强制再推 delete_post_meta($post_ID, '_baidu_pushed'); baidu_push_url($post_ID); } }, 10, 3); } 关键改进: - 5 秒 timeout:绝对不能让百度网络抖动卡住编辑器。原帖代码无超时,百度某次响应慢 30 秒,编辑器就卡 30 秒。 - HTTPS 接口:迁到 https://data.zz.baidu.com。 - 配额监控:响应里的 remain 字段是当日剩余配额,< 100 时告警。 - 多种失败原因细分:not_same_site(域名不匹配)/ not_valid(URL 非法)/ error(系统错误)分别 log,便于排查。 - 更新文章也推:post_updated hook 处理"已发布文章再编辑后保存"——百度会按"更新过的内容"重新评估排名。 - 用 update_post_meta 而不是 add_post_meta:原帖用 add 会导致同一 post 多个 meta 行,update 才是 upsert 语义。 ## 避免阻塞用户编辑:异步推送 publish_post hook 是同步执行的——文章保存按钮按下后,PHP 必须等 hook 全部完成才返回响应给浏览器。即使加了 5 秒 timeout,用户偶尔还是会感觉到"保存按钮卡了一下"。生产环境最稳的做法是异步: ## 用 wp_schedule_single_event 延迟执行 add_action('publish_post', function ($post_ID) { // 延迟 5 秒后执行推送,不阻塞编辑器 wp_schedule_single_event(time() + 5, 'mysite_baidu_push', [$post_ID]); }); add_action('mysite_baidu_push', 'baidu_push_url', 10, 1); 这个用 WordPress 自带的 cron 系统延迟跑——但 WP-Cron 是"模拟 cron",需要有人访问网站才触发。低流量站可能延迟更久。 ## fastcgi_finish_request 立即断连 add_action('publish_post', function ($post_ID) use_existing { // 推送代码放到 shutdown hook,等 PHP 响应已发出后再执行 add_action('shutdown', function () use ($post_ID) { if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); // 断 HTTP 连接 } baidu_push_url($post_ID); // 用户已看到保存成功,后台慢慢推 }); }); 这种方式用户体感"保存秒成",推送在后台异步走。 ## 真正的队列:Redis + worker 对中大型站,用 Redis 队列分离: // 入队 add_action('publish_post', function ($post_ID) { $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $redis->lPush('baidu_push_queue', $post_ID); $redis->close(); }); // 后台 worker 出队(独立 PHP 进程,supervisord 守护) $redis = new Redis(); $redis->connect('127.0.0.1', 6379); while (true) { $task = $redis->brPop(['baidu_push_queue'], 30); if (!$task) continue; $post_ID = (int)$task[1]; baidu_push_url($post_ID); } 这种架构的好处:① 编辑器零阻塞;② worker 失败可重试;③ 配额满时可暂停 worker 等次日再跑。 ## Bing IndexNow:零配置接入 Bing 在 2021 年推出 IndexNow 协议(Yandex 也加入),让站长可以直接 ping 一个端点告知"这个 URL 有更新"。比百度推送简单得多——不需要登录后台拿 token,只要在站点根放一个 verification 文件证明域名归你即可。 ## 接入步骤 - 生成一个 32 位随机字符串作为 key(比如 e7d8f9a1b2c3...,UUID 也行); - 把它放到站点根:https://yoursite.com/.txt(文件内容就是 key 自身); - 调 POST https://api.indexnow.org/indexnow 推送 URL 即可。 ## WordPress 集成代码 function indexnow_push($post_ID) { if (get_post_meta($post_ID, '_indexnow_pushed', true) == 1) return; $key = 'e7d8f9a1b2c3d4e5f6a7b8c9d0e1f2a3'; // 你的 IndexNow key $host = parse_url(home_url(), PHP_URL_HOST); $url = get_permalink($post_ID); $payload = json_encode([ 'host' => $host, 'key' => $key, 'keyLocation' => "https://{$host}/{$key}.txt", 'urlList' => [$url], ]); $ch = curl_init('https://api.indexnow.org/indexnow'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => $payload, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, ]); $resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($code === 200 || $code === 202) { update_post_meta($post_ID, '_indexnow_pushed', 1); } else { error_log("[IndexNow] FAIL code=$code resp=$resp"); } } add_action('publish_post', 'indexnow_push', 11); ## IndexNow 的真实效果 实测(中型 WordPress 站): - Bing:推送后平均 30 分钟到 4 小时被抓取,1-3 天进入索引; - Yandex:3-12 小时内抓取; - Naver / Seznam:也加入了 IndexNow,对应市场(韩国 / 捷克)的曝光受益。 IndexNow 不能用于 Google——Google 至今没有接入 IndexNow 协议,Google 推送要走它自己的 Indexing API(见 §4)。 ## Google Indexing API:限制与替代方案 Google 有 Indexing API 但限制非常严——官方明确说仅限以下内容类型: - JobPosting(招聘信息) - BroadcastEvent(直播流嵌入 VideoObject 的) 普通博客文章、产品页、新闻文章都不在支持范围。即便代码上能调通,提交也会被忽略,长期使用甚至可能触发账号警告。 ## Google 普通内容的推送替代 三条路径: - Google Search Console URL Inspection 工具:每个 URL 手动提交"请求编入索引"。每天有限额(约 10-15 个 URL),适合最重要的页面。 - Sitemap 自动 ping:每次更新 sitemap.xml 后调 https://google.com/ping?sitemap=https://yoursite.com/sitemap.xml。Google 会重读 sitemap 并发现新 URL。 - 提升网站整体内链密度:新文章在首页 / 分类页有强内链,Googlebot 自然抓得快。 ## sitemap ping 的代码 add_action('publish_post', function () { $sitemap_url = home_url('/sitemap.xml'); wp_remote_get('https://www.google.com/ping?sitemap=' . urlencode($sitemap_url), [ 'timeout' => 5, 'blocking' => false, // 不等响应直接返回 ]); }, 12); 注意 2026 年 Google 已经正式弃用 sitemap ping 端点——他们的 Search Central 博客建议直接用 Search Console 的 sitemap 提交。所以这条 ping 只对 Bing / Yandex 有效,Google 部分需要靠 sitemap 在站长平台预先提交。 ## 推送有效性验证 推完之后怎么确认搜索引擎真的收到了? ## 百度 登录百度站长平台 → 资源提交 → 主动推送(推送记录)。能看到当天提交的总数 + 成功数 + 失败数。如果数字对得上,推送链路 OK。 ## Bing 登录 Bing Webmaster Tools → URL Inspection → 输入推送过的 URL,看抓取状态。 ## 站点级日志 看自家服务器日志,搜索引擎爬虫的 UA 出现频率(百度的 Baiduspider、Bing 的 bingbot): tail -10000 /var/log/nginx/access.log | grep -E "Baiduspider|bingbot" | wc -l # 推送前后对比,活跃数应明显上升 ## 配额管理:每日推送上限 搜索引擎 | 每日配额 | 怎么提升 | 百度普通主动推送 | 10 万条/日(默认) | 站长平台申请提升,需站点权重 | 百度快速收录 | 需开通,配额另算 | 站长平台 → 开通"快速收录"权限 | Bing IndexNow | 10K 条/日(建议) | 无明确硬上限,过量会被节流 | Yandex IndexNow | 同上 | 同上 | Google Indexing API | 200 条/日(仅 JobPosting) | 普通内容用不了 | 百度的 10 万条/日对绝大多数博客够用——日均发 1-10 篇文章 + 历史文章一次性补推,远不到上限。但电商 / UGC 站点动辄日新增几千上万 URL,要开通"快速收录"额外通道。 ## cron 兜底批量推送 publish_post hook 触发的实时推送可能漏(网络抖动、配额满)。建议加一个 cron 每日扫一遍"未推送过"的文章批量补推: // 注册每日 cron register_activation_hook(__FILE__, function () { if (!wp_next_scheduled('mysite_daily_push_backfill')) { wp_schedule_event(strtotime('tomorrow 03:00'), 'daily', 'mysite_daily_push_backfill'); } }); add_action('mysite_daily_push_backfill', function () { global $wpdb; $posts = $wpdb->get_col(" SELECT p.ID FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} m ON m.post_id = p.ID AND m.meta_key = '_baidu_pushed' WHERE p.post_status = 'publish' AND p.post_type IN ('post','page') AND m.meta_id IS NULL ORDER BY p.post_date ASC LIMIT 500 -- 一次最多补推 500 条 "); foreach ($posts as $id) { baidu_push_url($id); usleep(200000); // 200ms 间隔避免限流 } }); 设凌晨 3 点跑,避开用户活跃高峰,且配额是按整日重置,这时候用最划算。 ## 推送 vs sitemap:什么时候选哪个 两种机制各有优势: 维度 | 主动推送 | Sitemap | 实时性 | 秒级 | 小时-天级 | 配额 | 有上限 | 无上限 | 覆盖率 | 新增/更新都需要单独触发 | 一次性全量 | 失败回溯 | 需要 cron 兜底 | 站长平台显示完整结果 | 实战建议:两者都做。新发文章靠主动推送抢实时,sitemap 兜底全量覆盖(包括内部链接修改、TDK (https://zhangwenbao.com/wordpress-categories-seo-add-custom-titles-keywords-descriptions.html) 调整等不触发 publish_post 但搜索引擎需要重新抓取的情况)。 ## 不该推送的页面类型 原帖列了几条标准建议,2026 年补充几条: - 分页页(?paged=2、/page/3/):搜索引擎能自己沿着分类页发现,主动推会浪费配额。 - 带 noindex (https://zhangwenbao.com/is-meta-robots-noindex-nofollow-needed-with-canonical.html) meta 的页面:推过去也不索引,纯浪费。 - 登录态页面 / 后台 URL:有 paywall / 需要 cookie 才能看的内容,搜索引擎抓到也是拒绝页。 - 自动生成的标签页 / 作者页:内容一般跟首页相似,重复度高,谨慎推。 - WP REST API 端点(/wp-json/...):这是 API 不是内容页面,不要推。 主动推送只推"高质量、原创、新增"内容是核心原则。 ## 常见问题解答 ## 百度推送返回 success 但搜索 site:yoursite.com 看不到,是怎么回事? 推送成功 ≠ 立即收录。百度推送只是把 URL 放进抓取队列——后续是否抓取、是否索引,由百度自己的算法决定。新站、低权重站、重复内容多的站点可能推了很久也不收录。建议结合内容质量优化(原创度、字数、外链等)综合处理。 ## token 泄漏被别人冒名推送怎么办? 立刻到百度站长平台 → 链接提交 → 主动推送 → "重置 token"。新 token 立刻生效,旧 token 失效。所有调用代码同步更新。如果是大量恶意推送已造成排名波动,写工单给百度反馈。 ## 怎么验证 IndexNow key 文件配对是否正确? 访问 https://yoursite.com/.txt,浏览器应能直接看到 key 字符串(应跟你 POST 提交时的 key 字段完全一致)。如果 404 或返回 HTML 而不是纯文本,配对失败,IndexNow 会拒推送。文件内容必须只有 key 字符串本身(无换行、无 BOM、无其它字符)。 ## publish_post hook 同时运行了百度和 IndexNow,编辑器卡 10 秒怎么办? 多个推送串行同步执行就会累计。三种解法:① 用 §2.2 的 fastcgi_finish_request 让所有推送都在断连后跑;② 把多个推送合并到一个 wp_remote_get 多线程实现(curl_multi_init);③ 上 Redis 队列彻底异步,编辑器零等待。 ## Google Indexing API 说能用,但实际推普通博客文章为什么不索引? Google 官方政策:Indexing API 仅限 JobPosting 和 BroadcastEvent 两种 schema 类型的内容。其它类型即使 API 调用 200 OK,也不会被索引——后台静默忽略。这条限制 2022 年起明确公布。普通博客文章别再走 Indexing API,去 Search Console 用 URL Inspection 手动提交。 ## 主动推送对 Google 排名有帮助吗? 没有直接帮助——百度的主动推送只对百度生效,跟 Google 排名无关。Google 排名靠:① Sitemap 提交 + Search Console 验证;② 高质量外链;③ 站内技术 SEO(速度 / 移动友好 / Schema);④ 持续高质量内容。这些做好后,Googlebot 抓取和索引速度自然就快。 ## 已发布老文章怎么补推到百度? 用文中第七节的 cron 兜底脚本,扫描没有 _baidu_pushed meta 的文章批量补推。如果想一次性全量推(比如新站迁移),可写一次性脚本:扫所有 publish post,按发布日期倒序,每批 500 条 + 200ms 间隔。配额够的话一两天能推完几千篇。 ## 推送了 URL 后能撤销吗? 百度推送不能撤销——一旦提交 URL 就在百度抓取队列里。但你可以:① 给该 URL 加 noindex meta;② robots.txt (https://zhangwenbao.com/tools/robots-generator.php) 屏蔽该 URL 路径;③ 如果是错误内容,删除该 URL 让百度抓 404,自然从索引中淘汰。Bing IndexNow 也无撤销机制,同样靠 noindex / 404 让其自然淘汰。 ## 同一个 URL 反复推送会被惩罚吗? 不会被惩罚,但消耗配额。百度官方建议同一 URL 不要在 24 小时内重复推超过 3 次。频繁重复推也不会让搜索引擎更早收录——抓取队列里第 5 次推和第 1 次推是同一个 URL,不会跳到队首。代码里用 _baidu_pushed meta 标记已推送、24 小时内不重推是常见做法。 ## 移动 App / 小程序内容也能推送吗? 移动 App 是 Activity 不是 URL,不能直接推。微信小程序、App 内 H5 页面可以单独配置 deep link 后推它们对应的 https URL。原生 App 内容的推送要走百度的"小程序推送 API"或"应用搜索 API",工作流跟 Web 完全不同。 ## 权威参考资料 ## WordPress免插件sitemap实战指南:动态优先级、image:image、sitemapindex分页与缓存策略 - URL:https://zhangwenbao.com/wordpress-free-plug-in-automatically-updates-sitemap-xml.html - 分类:WordPress SEO - 发布:2018-06-20 | 更新:2026-05-29 - 摘要:中大型WordPress站动辄十万级URL,现成sitemap插件未必扛得住。本文给出免插件的sitemap.php完整实现:按五类内容输出、按文章新旧动态算changefreq和priority、嵌入特色图,再扩展sitemapindex分卷、文件缓存、定时生成和各平台提交流程。 - 关键词:sitemap.xml,WordPress站点地图,站点地图,WordPress sitemap,sitemap.php > **TLDR**:摘要:中大型WordPress站动辄十万级URL,现成sitemap插件未必扛得住。本文给免插件的sitemap.php完整增强版实现——按五类内容输出、按文章新旧动态算changefreq和priority、嵌入特色图,再讲暴露成sitemap.xml的rewrite配置、分页sitemapindex应对超大站、缓存策略的性能优化、提交到搜索引擎和常见故障。 > 摘要:中大型WordPress站动辄十万级URL,现成sitemap插件未必扛得住。本文给免插件的sitemap.php完整增强版实现——按五类内容输出、按文章新旧动态算changefreq和priority、嵌入特色图,再讲暴露成sitemap.xml的rewrite配置、分页sitemapindex应对超大站、缓存策略的性能优化、提交到搜索引擎和常见故障。 WordPress 生态里 sitemap 插件多到挑花眼:Yoast SEO、Rank Math、Google XML Sitemaps、All in One SEO 都自带 sitemap 功能,WordPress 5.5+ 还内置了原生 wp-sitemap.xml。但插件大多数把 sitemap 当作附属功能,配置项分散、URL 形态不可控、对超大站点(10 万+ URL)性能差。本文给出基于 wp-blog-header.php 直接生成 sitemap 的免插件方案,可定制 URL 类型组合、按 lastmod 优先级排序、自动分页输出 sitemapindex、支持百度移动 sitemap 命名空间,并扩展到与 WordPress 6.x 原生 sitemap 共存、CDN 缓存策略、与 GSC/百度站长平台的提交细节。 ## WordPress sitemap 的几种实现路径 ## 路径一:原生 wp-sitemap.xml WordPress 5.5+ 自动生成 wp-sitemap.xml,访问任意 WP 站点的根域加 /wp-sitemap.xml 都能看到。优点:零配置;缺点:URL 形态固定(每页 2000 条、按文章类型分页),无法自定义优先级、无法过滤特定栏目、无法加百度移动命名空间。 如果你完全没特殊需求,原生 sitemap 够用。本文方案适合需要定制的场景。 ## 路径二:插件方案 Yoast、Rank Math 等插件覆盖了大多数定制需求。月流量 10 万以下的站点用插件最省事。但插件的代价是:增加 PHP 内存占用、与其它插件可能冲突、部分高级功能(lastmod 精确控制)需要付费 Pro 版。 ## 路径三:自定义 PHP 文件(本文方案) 把 sitemap.php 放在站点根目录,require wp-blog-header.php 加载 WordPress 完整环境,然后用 get_posts、get_pages、get_terms 等 WP API 直接生成 XML 输出。优点:完全可控、零依赖、性能可调优;缺点:需要懂 PHP,超大站点要手写分页逻辑。 ## 完整 sitemap.php 代码(增强版) 以下代码放到 WordPress 站点根目录的 sitemap.php: 1000, // 单 sitemap 文件最多 URL 数(协议上限 50000) 'include_pages' => true, 'include_categories' => true, 'include_tags' => true, 'include_authors' => false, // 多作者站点可开 'exclude_post_types' => ['attachment', 'revision', 'nav_menu_item'], 'exclude_categories' => [], // 隐藏栏目 term_id 数组 'exclude_tags' => [], ]; echo '' . "\n"; echo '' . "\n"; /* 工具函数:输出一条 url */ function output_url($loc, $lastmod = '', $changefreq = 'weekly', $priority = '0.5', $images = []) { echo ' ' . "\n"; echo ' ' . esc_url($loc) . '' . "\n"; if (!empty($lastmod)) { $time = is_numeric($lastmod) ? $lastmod : strtotime($lastmod); echo ' ' . gmdate('Y-m-d\TH:i:s+00:00', $time) . '' . "\n"; } echo ' ' . $changefreq . '' . "\n"; echo ' ' . $priority . '' . "\n"; foreach ($images as $img) { echo ' ' . "\n"; echo ' ' . esc_url($img['url']) . '' . "\n"; if (!empty($img['title'])) { echo ' ' . "\n"; } echo ' ' . "\n"; } echo ' ' . "\n"; } /* 1. 首页 */ $last_modified = get_lastpostmodified('GMT'); output_url(home_url('/'), $last_modified, 'daily', '1.0'); /* 2. 文章 */ $post_types = get_post_types(['public' => true]); $post_types = array_diff($post_types, $config['exclude_post_types']); $args = [ 'post_type' => $post_types, 'post_status' => 'publish', 'numberposts' => $config['posts_per_page'], 'orderby' => 'modified', 'order' => 'DESC', ]; $myposts = get_posts($args); foreach ($myposts as $post) { setup_postdata($post); /* 取文章首图 */ $images = []; if (has_post_thumbnail($post->ID)) { $thumb_url = get_the_post_thumbnail_url($post->ID, 'large'); if ($thumb_url) { $images[] = ['url' => $thumb_url, 'title' => get_the_title($post->ID)]; } } /* 优先级算法:根据更新频率与点击量动态计算 */ $age_days = (time() - get_the_modified_time('U', $post->ID)) / 86400; if ($age_days < 7) { $changefreq = 'daily'; $priority = '0.9'; } elseif ($age_days < 30) { $changefreq = 'weekly'; $priority = '0.7'; } elseif ($age_days < 365) { $changefreq = 'monthly'; $priority = '0.6'; } else { $changefreq = 'yearly'; $priority = '0.4'; } output_url( get_permalink($post->ID), get_the_modified_time('U', $post->ID), $changefreq, $priority, $images ); } wp_reset_postdata(); /* 3. 单页面 */ if ($config['include_pages']) { $pages = get_pages(['sort_column' => 'post_modified', 'sort_order' => 'desc']); foreach ($pages as $page) { output_url( get_page_link($page->ID), get_post_modified_time('U', false, $page->ID), 'weekly', '0.6' ); } } /* 4. 分类 */ if ($config['include_categories']) { $cats = get_terms([ 'taxonomy' => 'category', 'hide_empty' => true, 'exclude' => $config['exclude_categories'], ]); if (!is_wp_error($cats)) { foreach ($cats as $cat) { output_url(get_term_link($cat), '', 'weekly', '0.7'); } } } /* 5. 标签 */ if ($config['include_tags']) { $tags = get_terms([ 'taxonomy' => 'post_tag', 'hide_empty' => true, 'exclude' => $config['exclude_tags'], ]); if (!is_wp_error($tags)) { foreach ($tags as $tag) { output_url(get_term_link($tag), '', 'monthly', '0.4'); } } } /* 6. 作者 */ if ($config['include_authors']) { $authors = get_users(['who' => 'authors', 'has_published_posts' => true]); foreach ($authors as $author) { output_url(get_author_posts_url($author->ID), '', 'monthly', '0.3'); } } echo '' . "\n"; echo '' . "\n"; ## 相比原文方案的改进 - 动态优先级:按文章修改时间动态计算 changefreq 与 priority,新文章优先级高、老文章优先级低。Google 抓取调度更友好。 - image:image 子标签:每篇文章带上特色图(如有),让 Google 同步索引图片,带 image search 流量。 - 多 post_type 支持:自动覆盖所有公开的自定义文章类型(products、portfolio、event 等),不局限于普通 post。 - 排除配置:可配置 exclude_categories 与 exclude_tags 跳过隐私栏目(仅会员可见)。 - Authors 可选:多作者博客可开启作者页索引;个人博客关闭。 - X-Robots-Tag:sitemap 本身 noindex (https://zhangwenbao.com/when-does-noindex-page-remove-from-google-search-results.html) 不进 SERP,避免“sitemap.xml”这个 URL 被搜索引擎索引。 - UTF-8 显式声明:避免中文字符在某些编码环境下乱码。 ## 暴露为 /sitemap.xml 的 rewrite 配置 ## Apache (.htaccess) 在 .htaccess 文件 RewriteBase / 之下加: RewriteRule ^sitemap\.xml$ /sitemap.php [L] ## Nginx 站点配置 server 块内加: location = /sitemap.xml { rewrite ^ /sitemap.php last; } ## 避免与原生冲突 WP 5.5+ 自动接管 wp-sitemap.xml 路径。如果你不想走 WP 原生而走自定义,加 functions.php: /* 关闭 WordPress 原生 sitemap */ add_filter('wp_sitemaps_enabled', '__return_false'); ## 分页 sitemapindex 处理超大站 ## 什么时候需要分页 sitemap 协议规定单文件最多 50000 URL 与 50MB(未压缩)。但实际上为了让 Google 抓取更稳定,建议单文件 5000-10000 URL。10 万 URL 站点必须分页。 ## 分页方案 把 sitemap.php 改造为“不带参数输出 sitemapindex,带 page 参数输出 urlset”: publish; $total_pages = max(1, (int)ceil($total_posts / $page_size)); echo '' . "\n"; echo '' . "\n"; for ($p = 1; $p <= $total_pages; $p++) { echo ' ' . "\n"; echo ' ' . home_url('/sitemap.xml?page=' . $p) . '' . "\n"; echo ' ' . gmdate('c') . '' . "\n"; echo ' ' . "\n"; } /* 单独的 sitemap:分类、标签、单页 */ echo ' ' . home_url('/sitemap.xml?type=taxonomy') . '' . "\n"; echo '' . "\n"; exit; } /* 输出某分页的 urlset */ $offset = ($page - 1) * $page_size; $myposts = get_posts([ 'post_type' => 'post', 'post_status' => 'publish', 'numberposts' => $page_size, 'offset' => $offset, 'orderby' => 'modified', 'order' => 'DESC', ]); echo '' . "\n"; echo '' . "\n"; foreach ($myposts as $post) { echo ' ' . "\n"; echo ' ' . esc_url(get_permalink($post->ID)) . '' . "\n"; echo ' ' . gmdate('c', get_post_modified_time('U', false, $post->ID)) . '' . "\n"; echo ' ' . "\n"; } echo '' . "\n"; ## 性能优化:缓存策略 ## 问题:每次请求都查 DB 1 万文章的 sitemap 单次生成耗时 5-10 秒。如果 Googlebot (https://zhangwenbao.com/why-googlebot-ignores-resource-hints.html) 高频请求 sitemap.xml(通常每天 5-20 次),CPU 与 DB 压力都不小。 ## 方案 A:文件缓存 给 sitemap.php 加一段: $cache_file = WP_CONTENT_DIR . '/cache/sitemap_' . md5($_SERVER['QUERY_STRING']) . '.xml'; $cache_ttl = 3600; // 1 小时 if (file_exists($cache_file) && (time() - filemtime($cache_file) < $cache_ttl)) { readfile($cache_file); exit; } ob_start(); /* ... 原 sitemap 生成逻辑 ... */ $content = ob_get_contents(); file_put_contents($cache_file, $content); ob_end_flush(); ## 方案 B:定时任务生成静态文件 WordPress 有 wp-cron,注册定时任务: add_action('wp', function() { if (!wp_next_scheduled('regenerate_sitemap')) { wp_schedule_event(time(), 'hourly', 'regenerate_sitemap'); } }); add_action('regenerate_sitemap', function() { $url = home_url('/sitemap.php'); $content = wp_remote_retrieve_body(wp_remote_get($url)); file_put_contents(ABSPATH . 'sitemap-cache.xml', $content); }); nginx 优先返回静态 sitemap-cache.xml,没有时回源到 sitemap.php。 ## 方案 C:发文章触发增量更新 挂 hook 到 publish_post: add_action('publish_post', function() { /* 立刻重新生成 sitemap,覆盖缓存 */ $url = home_url('/sitemap.php'); $content = wp_remote_retrieve_body(wp_remote_get($url)); file_put_contents(ABSPATH . 'sitemap-cache.xml', $content); }); 这样新文章发布即刻反映到 sitemap,搜索引擎下次抓取就能拿到。 ## 提交到搜索引擎 ## Google Search Console 左侧菜单“站点地图”-填入 sitemap.xml-提交。提交后 Google 通常 24-48 小时内开始抓取。GSC 后台能看到“已发现 N 个 URL”“已索引 M 个 URL”的进度。 ## 百度站长平台 百度搜索资源平台 - 资源提交 - sitemap。注意百度对 sitemap 抓取频率较低,提交后 2-3 天才开始。 ## Bing Webmaster Tools 同 Google 流程。Bing 还能直接 ping:http://www.bing.com/ping?sitemap=https://example.com/sitemap.xml。 ## robots.txt 声明 在 robots.txt (https://zhangwenbao.com/wordpress-add-robots-txt-files-and-optimize-website-collection.html) 里声明 sitemap 位置: Sitemap: https://example.com/sitemap.xml 所有遵守 robots.txt 的爬虫(包括 Google、Bing、Yandex)会自动发现。 ## 常见故障 ## 故障 1:sitemap.xml 404 多数是 rewrite 规则没生效。Apache 检查 .htaccess 是否启用(mod_rewrite 装了吗);Nginx 检查 location 规则放置位置(可能被前面的 location 拦截)。 ## 故障 2:XML 解析错误 sitemap.php 输出前有 BOM 或空白字符。检查 require wp-blog-header.php 这一行之前没有任何 echo / print / 空白行。文件保存为 UTF-8 无 BOM。 ## 故障 3:与 wp-sitemap.xml 内容重复 WP 原生 sitemap 与你的自定义 sitemap 同时存在,搜索引擎会同时抓取造成混乱。在 functions.php 里关掉原生:add_filter('wp_sitemaps_enabled', '__return_false');。 ## 故障 4:内存溢出 get_posts numberposts=-1 拉所有文章会让 PHP 内存爆炸。改成分批:每次取 1000 条,循环输出,用 wp_reset_postdata 释放对象。或者改用 WP_Query 的 paged 参数迭代。 ## 故障 5:sitemap 里的 URL 是 HTTP 但站点已切 HTTPS WP siteurl 设置错误。后台“设置-常规”里 WordPress 地址与站点地址都改成 https。或者 functions.php 强制:force_ssl_admin(true);。 ## 故障 6:分类页在 sitemap 但站点设了 noindex SEO 插件(Yoast/Rank Math)的“分类页 noindex”设置不会自动从 sitemap 排除。要在 sitemap.php 里手动判断: $noindex = get_post_meta($post->ID, '_yoast_wpseo_meta-robots-noindex', true); if ($noindex == '1') continue; ## 故障 7:lastmod 时间错乱 WP 默认时区与 UTC 转换没处理好。统一用 GMT 时间:gmdate('c', $time),时区固定 UTC。 ## 常见问题解答 ## 原生 wp-sitemap.xml 与自定义 sitemap 哪个更好? 原生省事但定制能力弱。如果你需要自定义 priority / 加 image / 排除特定栏目,用自定义。否则原生即可。 ## sitemap 多久更新一次? 用文件缓存方案(1 小时)够新鲜。重要发布触发即时刷新。Googlebot 一般每天访问 sitemap 1-5 次,1 小时缓存能覆盖 90% 抓取请求。 ## 多语言站点怎么做 sitemap? 每个语言一份 sitemap,通过 sitemapindex 列出。每个 url 块加 xhtml:link rel=alternate hreflang 标记其它语言版本。WPML/Polylang 插件有自己的 sitemap 生成器但不一定符合需求,可以参考本文方案魔改。 ## 需要给图片单独建 image-sitemap.xml 吗? 不需要。Google 推荐把图片信息嵌入文章 sitemap 里(image:image 子标签),而不是单独的 image sitemap。本文方案已经做了。 ## sitemap 提交后多久能在 GSC 看到 URL 全部被抓? “已发现 N 个 URL”通常 1-2 天显示。“已索引”需要 1-4 周。新站完成全部索引可能 1-3 个月。 ## 能否用 Action 钩子让插件向 sitemap 注入额外 URL? 能。在 sitemap.php 加 do_action:do_action('custom_sitemap_extra_urls');,其它插件可以 add_action 在这里 echo 额外的 url 块。 ## 百度移动 sitemap 命名空间有什么用? 声明 xmlns:mobile 后,可以给某些 URL 加 标记为移动版本。百度搜索会按移动适配规则索引。Google 不读这个命名空间。 ## sitemap 文件超过 50MB 怎么办? 分页 sitemapindex 是首选。次选 gzip 压缩输出 sitemap.xml.gz,Google 与百度都支持。 ## 能否给 sitemap 设访问频率限制? 能。nginx 层 limit_req 限制 sitemap.xml 每 IP 每分钟 10 次。但建议不限,因为正常爬虫都不会超频。 ## sitemap 里要不要包含已删除文章的 URL? 不要。已删除文章会返回 404,sitemap 里出现死链 (https://zhangwenbao.com/batch-detection-of-site-dead-links.html)会让搜索引擎降低对你的信任度。get_posts post_status=publish 已经自动过滤。 ## 权威参考资料 ## WordPress标签相关文章实战:query_posts反模式拆解、WP_Query重写、三层缓存与Jaccard相关性升级 - URL:https://zhangwenbao.com/wordpress-adds-related-article.html - 分类:WordPress SEO - 发布:2018-06-19 | 更新:2026-05-16 - 摘要:WordPress相关文章功能很多人用query_posts实现,结果污染主循环、Codex早就红框警告。本文从这个反模式讲起,给出WP_Query完整重写、五万文章站的EXPLAIN调优与复合索引、三层缓存与防雪崩、Jaccard相关性升级,再对比YARPP、Jetpack等插件和上线效果测量。 - 关键词:WordPress相关文章,WordPress标签,Transient API,WP_Query,WordPress > **TLDR**:摘要:WordPress相关文章很多人用query_posts实现,结果污染主循环、Codex早就红框警告。本文剖析这个反模式,给出WP_Query的完整生产版重写、五万文章站tag__in的真实SQL计划与复合索引、fastcgi与object cache与transient三层缓存的边界、从纯tag匹配升级到Jaccard相关性,再讲对站内权重传递的影响和与YARPP和Jetpack插件的对比。 > 摘要:WordPress相关文章很多人用query_posts实现,结果污染主循环、Codex早就红框警告。本文剖析这个反模式,给出WP_Query的完整生产版重写、五万文章站tag__in的真实SQL计划与复合索引、fastcgi与object cache与transient三层缓存的边界、从纯tag匹配升级到Jaccard相关性,再讲对站内权重传递的影响和与YARPP和Jetpack插件的对比。 原文那段二十行的"标签相关文章"代码,是十年前 WordPress 教程站的标准答案。它的结构是:取出当前文章的所有 tag,用 query_posts() 拉同标签的最新十篇,不够十篇再用同分类补。看上去合理,跑起来也能出结果——但放在 2026 年的生产站点上,至少踩到了三个反模式、两个性能陷阱和一个 SEO 隐性扣分项。这篇文章把代码逐行拆开,把那些"为什么不能这么写"的细节、以及在 5 万文章站上 EXPLAIN 出的真实 SQL 计划写下来,然后给出从 WP_Query (https://developer.wordpress.org/reference/classes/wp_query/) 重写、三层缓存、Jaccard (https://en.wikipedia.org/wiki/Jaccard_index) 相关性升级、到 Gutenberg / AMP 兼容的完整方案。 ## 原文代码的三个致命缺陷 把原文贴出来再标注问题: $post_num = 10; $exclude_id = $post->ID; $posttags = get_the_tags(); $i = 0; if ( $posttags ) { $tags = ''; foreach ( $posttags as $tag ) $tags .= $tag->term_id . ','; $args = array( 'post_status' => 'publish', 'tag__in' => explode(',', $tags), 'post__not_in' => explode(',', $exclude_id), 'caller_get_posts' => 1, 'orderby' => 'comment_date', 'posts_per_page' => $post_num, ); query_posts( $args ); while( have_posts() ) { the_post(); ?>
  • ID; $i++; } wp_reset_query(); } ## 缺陷 1:query_posts() 污染主循环 WordPress Codex 在 query_posts() 函数文档的最顶上有一行红框警告,原话是 "This function will completely override the main query and isn't intended for use by plugins or themes"。这不是风格建议,是物理事实——query_posts() 内部直接覆盖了 $wp_query 全局变量,等于把页面正在跑的主循环替换掉。 实际触发的 bug 我至少见过三种。第一种最经典:在 single.php 模板末尾用 query_posts() 之后,紧跟的 wp_link_pages() 输出的分页链接全错——因为 $wp_query 已经不是当前文章了。第二种:分页类插件(比如 WP-PageNavi)在 footer.php 里读 $wp_query->max_num_pages,会把"相关文章那个查询"的总页数当成主查询页数显示,于是产生出"第 1 页 共 1 页"这种诡异输出。第三种最隐蔽:用了 SEO 插件(Yoast / RankMath)的站点,head 里的 canonical / og:url 在某些版本会延迟到 footer 之前才输出,query_posts 会让 canonical 指向相关列表里的第一篇,造成大批文章互相 canonical 到一起,三个月后 GSC 里的索引覆盖率会断崖式下跌。 正确做法是 new WP_Query($args) 拿到一个独立对象,循环结束后调 wp_reset_postdata()。注意是 postdata 不是 query——后者是为 query_posts() 配套的,只在用了 query_posts() 之后才需要调。 ## 缺陷 2:caller_get_posts 是 WordPress 3.1 起就废弃的别名 原文里的 'caller_get_posts' => 1 在 2011 年发布的 WP 3.1 之后已经改名叫 'ignore_sticky_posts'。废弃的别名虽然 14 年来仍能跑通——WP 核心保留了向后兼容——但用任何一个 WordPress lint(比如 WPCS,WordPress Coding Standards 工具集)扫描,都会爆 WordPress.WP.DeprecatedParameters.Found_replacement_caller_get_posts。 更关键的是 ignore_sticky_posts 的语义:它告诉 WP_Query 不要把站点置顶文章插到结果集前面。如果站点没设置任何 sticky post,这个参数加不加都一样。如果置顶了几篇文章作为"必看推荐",那么相关文章列表里如果不加这个参数,会被同样的几篇置顶帖塞满——失去了"相关"的意义。 ## 缺陷 3:post__not_in 接收逗号字符串是 PHP 弱类型陷阱 原文写 $exclude_id = $post->ID(整数),下面又写 $exclude_id .= ',' . $post->ID(字符串拼接),最后用 explode(',', $exclude_id) 转回数组传给 post__not_in。PHP 5/7/8 这一连串隐式类型转换不报错,但有两个问题。 第一,explode 出来的数组每一项都是字符串而不是整数,WP_Query 内部会调 array_map('intval', ...) 强转,多此一举。第二,更隐蔽:当 $exclude_id 只有一个 ID 时(比如刚进循环),explode(',', '123') 返回 ['123'];但如果 $post->ID 因为某种主题 hook 被改成了 null 或空字符串,explode(',', '') 返回 ['']——一个包含空字符串的数组。这个空字符串经 intval 变成 0,传给 post__not_in 后生成的 SQL 会变成 AND wp_posts.ID NOT IN (0),等于没过滤,于是相关文章列表里出现了当前正在阅读的这篇文章本身,看上去是"自己引用自己"的循环引用 bug。 正确的写法是用整数数组从头到尾保持类型:$exclude_ids = [(int) $post->ID],循环里 $exclude_ids[] = (int) get_the_ID()。 ## 用 WP_Query 改写的完整生产版本 把上面三个坑都修掉,加上必要的边界处理,下面是我在三个生产站点跑了至少两年的版本: function zwb_related_posts( $post_num = 10 ) { $post_id = get_the_ID(); $post_tags = wp_get_post_tags( $post_id, [ 'fields' => 'ids' ] ); $exclude = [ $post_id ]; $items = []; if ( ! empty( $post_tags ) ) { $q = new WP_Query( [ 'post_status' => 'publish', 'post_type' => 'post', 'tag__in' => $post_tags, 'post__not_in' => $exclude, 'ignore_sticky_posts' => 1, 'orderby' => 'date', 'order' => 'DESC', 'posts_per_page' => $post_num, 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ] ); foreach ( $q->posts as $p ) { $items[] = $p; $exclude[] = $p->ID; } } if ( count( $items ) < $post_num ) { $cat_ids = wp_get_post_categories( $post_id, [ 'fields' => 'ids' ] ); if ( ! empty( $cat_ids ) ) { $q = new WP_Query( [ 'post_status' => 'publish', 'post_type' => 'post', 'category__in' => $cat_ids, 'post__not_in' => $exclude, 'ignore_sticky_posts' => 1, 'orderby' => 'date', 'order' => 'DESC', 'posts_per_page' => $post_num - count( $items ), 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ] ); $items = array_merge( $items, $q->posts ); } } return $items; } 有几个细节值得展开。fields => 'ids' 让 wp_get_post_tags 只返回 term_id 数组,避免把整个 term 对象(含 name、slug、description、count、taxonomy 等十来个字段)从数据库 SELECT 出来。no_found_rows => true 关闭 SQL_CALC_FOUND_ROWS 计算——相关文章列表不需要分页,也就不需要总数。这个开关在 5 万文章的库上能把单次查询从 110 ms 砍到 18 ms(用 Query Monitor 实测)。update_post_meta_cache 与 update_post_term_cache 关掉,避免 WP 自动把每篇文章的所有 postmeta 和 term 关系一起拉过来——相关文章列表只用到标题和 permalink,不用 meta 不用 term。这个组合是 WP_Query 性能优化最常被忽略的细节。 另一个细节:我没用 setup_postdata( $p ); the_title(); the_permalink(),而是直接 $p->post_title 和 get_permalink( $p->ID )。setup_postdata 会触发 the_post 钩子,包括 SEO 插件、社交分享插件挂上去的一堆回调,单次开销在 5–15 ms 之间。对相关文章这种"渲染而不交互"的列表,跳过 the_post 收益明显。 ## 性能:tag__in 在 5 万文章站上的真实 SQL 计划 很多教程会说 "WP_Query 已经够快了",但什么叫够快?把上面那段代码挂到一个 51,800 篇文章 / 8,400 个 tag / wp_term_relationships 表 78 万行的真实站点上,开 Query Monitor 抓 SQL: SELECT wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON ( wp_posts.ID = wp_term_relationships.object_id ) WHERE 1=1 AND wp_posts.ID NOT IN (47221) AND ( wp_term_relationships.term_taxonomy_id IN (134,256,891,1422) ) AND wp_posts.post_type = 'post' AND ( wp_posts.post_status = 'publish' ) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10; EXPLAIN 输出三行(MySQL 8.0.32,innodb_buffer_pool_size 4G): id select_type table type key rows Extra 1 SIMPLE wp_term_relationships range term_taxonomy_id 3211 Using where; Using index 1 SIMPLE wp_posts eq_ref PRIMARY 1 Using where 1 SIMPLE (group by + sort) Using temporary; Using filesort 问题在最后一行——Using temporary; Using filesort 是 MySQL 性能问题的红色信号。GROUP BY wp_posts.ID 加 ORDER BY wp_posts.post_date DESC 让 MySQL 必须先把 3211 行匹配结果生成临时表、再按 post_date 排序。这套站点单次相关文章查询平均耗时 240 ms(p95 480 ms),首页打开因为不调相关查询所以 60 ms 就出,但点进任何一篇文章 TTFB 立刻飙到 600+ ms。 三个层级的优化: SQL 层:加复合索引。给 wp_posts 加 (post_status, post_type, post_date) 复合索引: ALTER TABLE wp_posts ADD INDEX idx_status_type_date (post_status, post_type, post_date); WordPress 默认索引只有 PRIMARY、post_name、type_status_date(顺序是 post_type, post_status, post_date——前缀不匹配 WHERE 子句的写法)。新加的索引让 ORDER BY 能直接用索引顺序读,免去 filesort。同样 8.0.32,加完索引后单次查询从 240 ms 降到 38 ms。 WP 层:把整段 HTML 用 Transient 缓存。相关文章列表对单篇文章是恒定的(只在新发文章时可能变),完全可以用 Transient API 存 12 小时: function zwb_related_html( $post_id, $post_num = 10 ) { $key = "zwb_related_{$post_id}_{$post_num}"; $html = get_transient( $key ); if ( false !== $html ) return $html; $items = zwb_related_posts( $post_num ); if ( empty( $items ) ) { $html = '
  • 暂无相关文章
  • '; } else { $html = ''; foreach ( $items as $p ) { $html .= sprintf( '
  • %s
  • ', esc_url( get_permalink( $p->ID ) ), esc_attr( $p->post_title ), esc_html( $p->post_title ) ); } } set_transient( $key, $html, 12 * HOUR_IN_SECONDS ); return $html; } 注意 cache key 里包含了 $post_num。如果某天调整了显示数量,旧的 transient 不会被命中,自然过期,无需手动清。 失效策略:发新文章时清相关 transient。WordPress 的 save_post 和 deleted_post 钩子触发时,把所有相关该 tag 的 transient 清一次: add_action( 'save_post', function( $post_id, $post, $update ) { if ( wp_is_post_revision( $post_id ) ) return; if ( $post->post_status !== 'publish' ) return; $tag_ids = wp_get_post_tags( $post_id, [ 'fields' => 'ids' ] ); if ( empty( $tag_ids ) ) return; global $wpdb; $tag_in = implode( ',', array_map( 'intval', $tag_ids ) ); $post_ids = $wpdb->get_col( " SELECT DISTINCT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN ($tag_in) " ); foreach ( $post_ids as $pid ) { delete_transient( "zwb_related_{$pid}_10" ); } }, 10, 3 ); 这段代码的成本:每发一篇新文章触发一次 SELECT + N 次 delete_transient。在我的站上,单个 tag 平均关联 9 篇文章,最多关联 240 篇("WordPress" 这种万能标签),删 240 个 transient 大约 80 ms,可以接受。如果想再优化可以走 namespace cache(只删整个 namespace),需要换 object cache 后端。 ## 三层缓存:fastcgi / object cache / transient 的边界 很多人把 cache 当成一个单维度的开关——开了就快,关了就慢。实际生产环境是三层堆叠的金字塔,每一层解决不同的问题。 第一层:fastcgi_cache(nginx 层)。整页 HTML 缓存,命中后甚至不进 PHP-FPM,TTFB 通常 5–15 ms。问题是粒度粗——任何一个页面元素变了(比如评论数 +1)整页就要失效。fastcgi cache 适合纯 GET、无登录态的页面,相关文章如果是页面的一部分自然也跟着缓存。但有个坑:fastcgi cache 默认按 $scheme$request_method$host$request_uri 做 key,不区分 cookie。如果未登录用户和管理员访问同一篇文章,且管理员看到了"编辑此篇"按钮,那个按钮可能被缓存到所有用户的页面上。配置时一定要加 fastcgi_cache_bypass $cookie_loggedin;。 第二层:object cache(Redis / Memcached)。WordPress 的所有 wp_cache_get/set 调用、所有 get_option / get_post_meta / get_term,默认走的是请求级别内存缓存(请求结束即丢)。装了 Object Cache Pro 或免费版 Redis Object Cache 之后,这些调用会写到 Redis 持久化跨请求复用。对相关文章查询的影响:WP_Query 内部调的所有 get_post(拉文章对象)、get_term(拉 tag 对象)都从 Redis 出,不再触发 SQL。同样的查询,object cache 命中时单次 30 ms,不命中 240 ms。 第三层:transient(业务层)。上面那段相关文章 HTML 缓存就是 transient。Transient 在装了 object cache 时自动走 Redis(带过期时间),没装 object cache 时落 wp_options 表。落表的 transient 有个隐蔽问题:过期的 transient 不会自动清,只有调 get_transient() 才被动清。如果 cache key 高基数(比如包含 user_id),wp_options 表会膨胀到几百万行,autoload 慢到 2 秒以上。所以高基数 transient 必须配合 object cache 用,或者写定时任务定期 SQL 清理。 ## 缓存击穿与雪崩的真实案例 有个站点的相关文章 transient 设置过期时间 1 小时,每天凌晨 4 点 cron 重建 sitemap 时会触发 save_post 钩子(因为更新了 modified 时间),把所有 transient 清空。结果是早上 7 点流量起来时所有文章页同时回源——Redis 没数据、object cache 没数据、SQL 同时跑 200 个相关查询,innodb_buffer 命中率从 99% 跌到 70%,CPU 拉满。这就是经典的缓存雪崩。 修复有两种:一种是给 transient 过期时间加随机数(比如 12h ± 1h),让缓存不在同一时刻全部失效;另一种是 probabilistic early expiration(XFetch 算法),在缓存还没过期但快过期时(比如剩 10% 寿命),按概率提前重建。后者实现: function zwb_xfetch_get( $key, $ttl, callable $regen ) { $data = get_transient( $key ); if ( false !== $data && isset( $data['expires'], $data['delta'], $data['value'] ) ) { $now = microtime( true ); $beta = 1.0; $xfetch = $data['delta'] * $beta * log( mt_rand() / mt_getrandmax() ); if ( ( $now - $xfetch ) < $data['expires'] ) { return $data['value']; } } $start = microtime( true ); $value = $regen(); $delta = microtime( true ) - $start; set_transient( $key, [ 'value' => $value, 'delta' => $delta, 'expires' => microtime( true ) + $ttl, ], $ttl + 60 ); return $value; } 用法:$html = zwb_xfetch_get( "zwb_related_$pid", 3600, fn() => build_related_html( $pid ) );。这段代码的关键是 $delta * beta * log( random )——重建越慢的缓存,越容易被提前重建,避免到期瞬间所有请求同时回源。 ## 从纯 tag 匹配升级到 Jaccard 相关性算法 原文那种 tag__in 单纯匹配在标签稀疏的站点会退化。我跑过一个统计:6 万文章 / 1.2 万标签的站点,标签使用频次符合长尾分布——80% 的标签只关联 1–3 篇文章。当读者在那"只关联 1 篇"的文章页停留时,相关文章查询返回空,于是回退到分类查询,列表里都是"同分类最新"——和"相关"已经没什么关系。 更合理的相关性度量是 Jaccard 系数:两篇文章的标签集合交集除以并集。如果文章 A 有标签 {WP, SEO, Cache},文章 B 有 {WP, SEO, JS},Jaccard = 2/4 = 0.5。Jaccard 越高越相关。 实时算 Jaccard 不现实——每个 pageview 要扫整张文章表。可行方案是建一张 wp_related_posts 表,每天凌晨低峰期 cron 算一次: CREATE TABLE wp_related_posts ( post_id BIGINT UNSIGNED NOT NULL, related_id BIGINT UNSIGNED NOT NULL, score DECIMAL(5,4) NOT NULL, rank SMALLINT UNSIGNED NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY (post_id, related_id), INDEX idx_post_rank (post_id, rank) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 每篇文章只存 top 20 关联,按 score 降序 rank 1–20。查询时 SELECT related_id FROM wp_related_posts WHERE post_id = ? ORDER BY rank LIMIT 10——主键覆盖,单次 0.3 ms。 预计算的 PHP 部分: function zwb_rebuild_related_for( $post_id ) { global $wpdb; $my_tags = wp_get_post_tags( $post_id, [ 'fields' => 'ids' ] ); if ( empty( $my_tags ) ) return; $tag_in = implode( ',', array_map( 'intval', $my_tags ) ); $candidates = $wpdb->get_col( " SELECT DISTINCT tr.object_id FROM {$wpdb->term_relationships} tr WHERE tr.term_taxonomy_id IN ($tag_in) AND tr.object_id != $post_id " ); $scores = []; foreach ( $candidates as $cid ) { $their_tags = wp_get_post_tags( $cid, [ 'fields' => 'ids' ] ); $intersect = count( array_intersect( $my_tags, $their_tags ) ); $union = count( array_unique( array_merge( $my_tags, $their_tags ) ) ); $scores[ $cid ] = $union > 0 ? $intersect / $union : 0; } arsort( $scores ); $scores = array_slice( $scores, 0, 20, true ); $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}related_posts WHERE post_id = %d", $post_id ) ); $rank = 1; foreach ( $scores as $rid => $score ) { $wpdb->insert( "{$wpdb->prefix}related_posts", [ 'post_id' => $post_id, 'related_id' => $rid, 'score' => $score, 'rank' => $rank++, 'updated_at' => current_time( 'mysql' ), ] ); } } 这种做法的代价是预计算窗口和增量更新。全站每篇都重算一次,6 万文章在 PHP 单线程下需要约 4 小时。所以应做增量:监听 save_post,只重算这篇文章及其所有候选文章的相关表。增量代码这里就不展开了,原理一致。 ## Jaccard 之外:TF-IDF / Embedding 路线 对于内容更丰富的站点(每篇 3000+ 字),可以考虑基于正文的 TF-IDF (https://zhangwenbao.com/tf-idf-seo.html) 相似度,或者直接用预训练 embedding(比如 m3e、bge-large-zh)算 cosine 相似度。后者效果显著好于 tag 匹配——比如一篇讲"Nginx 反代 WebSocket"的文章,可以正确推出"Apache 反代 WebSocket",而仅靠 tag 匹配可能两者根本没有共同标签。 Embedding 方案的实现路径: - 每篇文章发布或更新时调一次 embedding API(本地 ONNX runtime 跑 m3e,约 800 ms / 篇),把 768 维向量存到 wp_post_embeddings 表。 - 检索时用 pgvector / Milvus / Faiss,或者更简单地直接 PHP 数组算 cosine(小于 1 万篇时性能可接受)。 - 每天 cron 跑相似度更新,写入 wp_related_posts。 对内容丰富、靠搜索流量的站点,这一步带来的"会话深度"收益比所有缓存优化加起来还大。我手上一个站从 tag 匹配换 embedding 后,每会话 PV 从 1.4 上升到 2.1。 ## SEO 维度:相关文章对站内权重传递的真实影响 相关文章列表的本质是站内内链——给每篇文章新增 10 条出链,10 条入链。这件事对 SEO 的影响有几个层面: PageRank 传递:站内 PR 流转模型下,单页有 10 条出链时,每条出链分得的权重是 PR(page) × 0.85 / 10。把相关文章放在所有文章页等于全站任意两篇文章之间最多隔 2–3 跳就能互通。这对深层文章(发布两年以上、外链已枯竭)的复活效果显著——我跟踪的一个站,上线相关文章功能后三个月,旧文章的 GSC 展现量平均增长 47%。 anchor text 多样化:很多人在相关文章列表里把锚文本 (https://zhangwenbao.com/anchor-text-seo-optimization-guide.html)写成"点击查看 >>"或者"阅读全文"。这是浪费——锚文本应该是被链接文章的标题,因为标题里包含真实查询关键词。原文代码里 这部分是正确的。 关于 rel="bookmark" 的迷思:原文加了 rel="bookmark",很多教程站抄来抄去。rel="bookmark" 在 HTML5 规范里有定义,意思是"链接到当前文档/区块的永久链接",仅对 article 内的 self-permalink 链接有意义(比如文章标题自身的链接)。把它用在相关文章列表里语义上是错的,对 SEO 没有任何加成(Google 早就声明不区分 rel="bookmark")。建议删除。 boilerplate 内容的降权风险:2018 年后 Google 多次调整对"boilerplate"(页面间重复内容)的识别。如果相关文章列表的代码生成的 HTML 在每篇文章里都几乎相同(同样的结构、同样的列表项数量),Mueller 在多次 Office Hours 中提到搜索引擎会自动剔除这部分——也就是说,相关文章对当前文章的 keyword cloud 没有正向贡献。但如果列表里的文章标题随上下文变化大(每篇相关文章列表完全不同),那么这部分内容会被算作有效正文,对 long-tail 关键词排名有微弱正向贡献。这反过来印证了第二节里说的"用 ID 数组而非逗号字符串"——正确实现保证每篇相关列表都不同,错误实现可能在某些边界条件下推出相同的"最新文章兜底"列表。 ## Gutenberg / Block Editor 时代的相关文章 Block 2018 年 WP 5.0 引入 Gutenberg 之后,传统的 PHP 函数 + 主题模板调用方式仍然能用——但越来越多的站点把所有页面元素 Block 化。把相关文章封装成 Block 的好处是:编辑可以在文章编辑器里拖动、可以单独控制每篇文章是否显示、可以做 A/B 测试不同布局。 注册 Block 的最简实现(用 server-side rendering 模式): function zwb_register_related_block() { register_block_type( 'zwb/related-posts', [ 'attributes' => [ 'count' => [ 'type' => 'number', 'default' => 10 ], 'layout' => [ 'type' => 'string', 'default' => 'list' ], ], 'render_callback' => function( $attrs ) { $count = max( 1, min( 30, (int) ( $attrs['count'] ?? 10 ) ) ); $layout = $attrs['layout'] ?? 'list'; $items = zwb_related_posts( $count ); if ( empty( $items ) ) return ''; ob_start(); ?> 标签(除了 AMP 自己的 amp-script,受沙盒限制)。 - 所有 必须改成 。 - 不允许 inline style,style 属性必须移到