站点上线三个多月,页面是团队一条条手工打磨的,标题、配图、正文都反复改过,结果在搜索框里搜自己的品牌词,翻了两页都找不到。编辑天天在群里催,技术觉得代码没问题,服务器日志也干干净净。最后把搜索资源平台的后台翻出来一看,推送记录明明白白写着昨天提交了两百多条URL,成功返回一百九十多条,收录数是个位数。这就是很多人第一次接触URL推送时的真实处境:推送和收录之间隔着的不是一层窗户纸,是好几道有淘汰率的关卡。
这篇内容想聊的就是搜索资源平台这套东西到底怎么用才不浪费力气——主动推送URL的正确接入方式、配额怎么分配、推送之前该做哪些质量预审、收录卡住时从哪一层开始排查。适合正在做内容站、企业站、电商详情页的开发和运营看,也适合刚接手站长后台、对着一堆指标不知道从哪下手的人。我不会给你一堆“坚持更新优质内容”的正确废话,只讲能直接抄的操作和踩过的坑。
1. 推送返回成功,为什么搜索结果里还是找不到
1.1 一条URL要过的四道关
先把一件事说透:推送接口返回的“成功”,语义是“平台已经接收了你这批地址”,仅此而已。它不代表抓取,更不代表收录。从提交到能在结果页看到,中间至少四道关,每一道都有淘汰率。
第一道是入队与调度。URL进了待抓取队列,但队列不是先来先抓,调度器会综合站点历史响应速度、页面更新频率、站点整体质量来决定什么时候轮到这条URL。新站或者长期不更新的站,排队时间可能是几小时,也可能是几周。
第二道是抓取。机器人来取页面,这里翻车的原因特别多:服务器超时、返回503、CDN节点拦截了机器人、robots.txt误封、页面要靠JS渲染但首屏是空壳。
第三道是解析与去重。抓到HTML之后要做正文抽取、结构化处理、和已有索引做相似度比对。这一步淘汰掉的是大量采集拼接、模板套壳、正文只有几句话的页面。
第四道才是质量评估与建库。页面会被打上一堆维度的分,够线才进索引。进了索引也不等于有展现,还得看查询匹配和排序。
所以“推了三百条收录三条”不是玄学,是四道关连着过,每道关卡都有损耗。理解这一点,后面的所有优化才有方向:你要做的不是提高推送条数,而是提高每一条通过四道关的概率。
| 环节 | 典型失败表现 | 主要排查入口 |
|---|---|---|
| 入队调度 | 推送成功但抓取频次长期为0 | 后台抓取频次曲线、站点更新活跃度 |
| 抓取 | 抓取诊断显示超时、5xx、内容为空 | 服务器访问日志、CDN与防火墙配置 |
| 解析去重 | 抓取正常但页面不建索引 | 正文可读性、与站内其他页相似度 |
| 质量评估 | 索引量涨了但无展现 | 内容信息密度、标题与正文匹配度 |
1.2 抓取预算与推送配额不是一回事
这两个概念经常被混为一谈,混了之后策略就会做错。
推送配额是接口层面的限流,指的是你每天能通过接口提交多少条URL,通常跟站点信用等级、站点规模、历史表现挂钩。配额用完了,接口会明确告诉你“未准入”或者“超出限制”,这时候再推也没用。
抓取预算则是另一套东西,指的是平台愿意在你的站点上花多少抓取资源。它取决于服务器响应时间、页面平均大小、站点更新规律、历史抓取成功率。一个响应要三秒以上、动不动就502的站,抓取预算会被压得很低,你推一万条它也抓不完。
我见过最典型的错误做法是:把配额当成KPI,每天雷打不动把配额推满,觉得“反正不用白不用”。结果推上去的全是列表页第二页、带一堆参数的筛选页、内容只有三行的标签聚合页。这些页面会拉低整个站点的质量评估,反过来又压缩了抓取预算,形成负循环。
正确的认知是:配额是上限不是目标,抓取预算才是真正要争取的资源。把配额用在最值得被抓的URL上,比推满更有价值。实际做法上,我一般会把每天的配额切成三份——大头给当天新增的原创内容页,中间一部分给有实质更新的旧页面,剩下留一点给需要复抓验证的问题页面。这个比例不用精确,但一定要有分配意识,不能一股脑全推。
2. 主动推送、站点地图、手动提交:三条通道的边界在哪
2.1 三种提交方式的真实时效差异
后台一般会提供三种提交路径,很多人知道有,但说不清什么时候该用哪个。
主动推送接口是时效最好的一条。它的价值在于“即时告知”——内容刚发布,几分钟内就能进待抓取队列。对于新闻、公告、限时活动这类时效敏感的内容,这是唯一合适的选择。代价是需要服务端改造,而且有配额限制。
站点地图是覆盖面最广、维护成本最低的一条。它的定位是“全量声明”,告诉平台我这个站有哪些页面值得抓。时效性差,通常是天级甚至更久,但胜在免费、无配额、可自动化生成。很多站只做了接口推送没做站点地图,一旦接口挂了或者配额用完,就彻底断了告知通道,这是很危险的单点依赖。
手动提交是应急手段,一次提交少量URL,适合验证问题——比如你改了一个页面的canonical,想确认平台能不能正常抓取和识别,手工提交一条去看抓取诊断,比改代码跑一遍推送流程快得多。
| 通道 | 时效 | 覆盖能力 | 成本 | 最适合的场景 |
|---|---|---|---|---|
| 主动推送接口 | 分钟到小时级入队 | 受配额限制 | 需服务端开发 | 新增内容、时效页面 |
| 站点地图 | 天级 | 全量、无配额 | 生成脚本即可 | 全站兜底、历史内容 |
| 手动提交 | 视情况 | 单条或少量 | 人工操作 | 问题验证、紧急补录 |
2.2 组合策略:谁打前锋,谁做兜底
我的习惯是三条通道同时开,各司其职。
接口推送打前锋,只推增量。内容发布成功的回调里挂一个异步任务,把URL丢进队列,由独立的推送worker消费。注意是异步,不要在主发布流程里同步调接口——接口超时或者限流会拖慢整个发布链路,这个坑我在早期项目里踩过一次,发布接口P99直接翻倍。
站点地图做兜底,每天定时重新生成。生成逻辑上有个细节:只收录状态码200、且没有被noindex标记的页面,同时把lastmod写成真实的最后修改时间。很多人图省事,把lastmod统一写成生成时间,这等于告诉平台“我全站每天都更新”,几次之后这个字段就被彻底忽略了,等于白写。
手动提交做验证。每次调整了模板、改了URL结构、修了canonical,我都会挑两三条代表性页面手工提交,然后隔一天去看抓取诊断的结果。这个动作花不了几分钟,但能提前发现问题,比等两周后看索引量掉下去再回滚要划算得多。
三条通道的数据要能对上号。我会给每条推送记录打上来源标记,定期比对“接口推送的URL”和“最终被收录的URL”,算一下各通道的收录转化率。这个数字比收录总量有用得多,它能告诉你哪条通道在真正起作用。
3. 把推送接口接进发布流程:从鉴权到失败重试
3.1 站点验证与推送凭证的落地
所有推送动作的前提是站点验证通过。常见的方式有三种:上传指定文件到站点根目录、在首页head里加一段meta标签、或者做一次DNS记录验证。三种方式里,文件验证最省事,但它有个隐患——如果后续做全站静态化或者换CDN,根目录文件容易被清掉,验证就失效了。我现在的做法是优先用DNS验证,一次配置长期有效,不受部署流程影响。
验证通过后会拿到推送用的凭证,一般是站点标识加token的组合。这个凭证要当密钥对待:放在环境变量里,不要硬编码进代码,更不要提交到代码仓库。我见过把token写在配置文件里然后连配置一起打包发到前端的,等于把自己站点的推送能力公开了。
接入时要确认两件事:一是接口地址和参数格式,不同平台的实现差异不小,有的是GET拼参数,有的是POST传JSON数组;二是单次提交的URL数量上限,通常是几十到几百条,超了会整批失败。稳妥做法是按批次切分,一批控制在几十条,既不会超限,单批失败的影响也小。
3.2 幂等、批量与重试队列的设计
推送逻辑写起来简单,写对不容易。核心是三件事:去重、分批、可控重试。
去重必须在本地做。同一个URL重复提交,多数情况下会占用配额但不产生额外价值,有些平台还会把它计为无效提交,拉低站点信用。我的做法是在数据库里给内容表加一个最后推送时间字段,推送前先按“未推送或距上次推送超过N天”筛一遍。
分批按固定大小切,并且每批之间留一点间隔,别一股脑打过去。下面是一个简化版的推送worker骨架,重点是批次控制和失败落库:
import time import requests from typing import List PUSH_ENDPOINT = "https://api.example.com/push" BATCH_SIZE = 50 BATCH_INTERVAL = 1.0 TIMEOUT = 8 def push_batch(session: requests.Session, token: str, urls: List[str]) -> dict: payload = {"site": "example.com", "token": token, "urls": urls} try: resp = session.post(PUSH_ENDPOINT, json=payload, timeout=TIMEOUT) resp.raise_for_status() return resp.json() except requests.RequestException as exc: # 网络层失败,整批落库等待下一轮重试 return {"ok": False, "reason": str(exc), "failed_urls": urls} def run(queue, token: str): session = requests.Session() while True: batch = queue.take(BATCH_SIZE) if not batch: time.sleep(5) continue result = push_batch(session, token, batch) if not result.get("ok"): # 不立即重试,写回延迟队列,避免短时间内反复触发限流 queue.requeue(batch, delay=600) else: # 记录成功条数、剩余配额,便于监控 queue.ack(batch, remain=result.get("remain")) time.sleep(BATCH_INTERVAL)重试策略上有个反直觉的点:接口报错时不要立刻重试。限流类错误通常是按时间段统计的,你越急着重试,越容易把这一时间段的额度打光。我一般设置十分钟起步的延迟重试,最多三轮,三轮还不行就落成待人工处理的任务,同时告警。
另外要加熔断。如果连续多批都返回未准入,说明配额已经耗尽或者站点状态异常,这时候应该停止推送而不是继续消耗,等下一个配额周期再恢复。没有熔断的推送任务在高频报错时会形成雪崩,把队列堵死。
3.3 返回体怎么读:四种失败原因的处理差异
推送接口的返回体虽然字段名各不相同,但信息结构基本一致,一般会给出四类信息:成功条数、剩余配额、不属于本站的URL数量、格式非法的URL数量。这四类要分开处理,因为根因完全不同。
成功条数低于提交条数但又不是零,通常是批次里混了重复URL或者已删除页面。这种情况要去查去重逻辑是否漏了状态校验,比如内容下线了但队列里还有残留记录。
剩余配额返回为零或者接近零,说明配额已经用完,这时候重试毫无意义,应该直接把任务挂起到下一个周期。
不属于本站的URL数量大于零,说明提交的地址和验证的站点域名不匹配。常见于子域名场景——验证的是主域名,推的却是另一个子域的页面,权限不覆盖。也可能是协议不一致,验证的是https,推的是http。
格式非法数量大于零,一般是URL里带了非法字符、参数没编码、或者长度超限。带中文参数、带富文本片段的链接最容易出这类问题,推之前统一做一次URL规范化能省掉很多麻烦。
养成记录返回体的习惯。每次推送把成功数、剩余配额、各类失败数落成一条日志,出问题时这些历史数据是唯二能回溯的东西。
4. 配额总是见底,问题多半出在选URL的逻辑上
4.1 全量推送是最大的配额黑洞
最常见的错误逻辑是“每天把全站URL全推一遍”。一个几千页的站,配额一天可能就几百条,全量推送意味着配额永远不够,而且绝大多数提交是重复的无效劳动。
全量推送还有更隐蔽的伤害。当平台发现你这个站每天提交的地址里,大部分内容没有任何变化,它对这批提交的信任度会下降。这种信任度下降会体现在后续提交的抓取优先级上,是个慢性的、很难察觉的损失。
替代方案是按更新信号筛。筛选维度至少要有:发布时间在最近N天内、最后修改时间有实质变化、页面状态为正常、没有被标记为不索引。这四个条件叠加之后,需要推送的量通常只有全量的百分之几。
4.2 用增量识别代替“发布即推”
“发布即推”听起来很合理,实际执行时要处理边界情况。内容创建和内容可访问之间有时间差,编辑刚点保存、图片还没传完、模板还在渲染,这时候推上去,机器人抓到的是半成品。抓到一次空页面,它对这条URL的评价就已经定型了,后面再改也难扭转。
我现在用的是延迟推送:内容进入“已发布”状态后,先等一个短暂窗口,再由定时任务统一扫描符合条件的记录入队。这个窗口短的几十分钟,长的几个小时,具体看站点更新频率。好处是能确保推送时页面已经是最终形态,也能把零散的发布行为聚合成批次,减少接口调用次数。
对于更新类内容,判断标准要更严格。不是“字段被写过”就算更新,而是“用户能看到的内容发生了变化”。改个标签、调个排序、换张缩略图,这些不该占用推送额度。我一般只在正文、标题、核心参数发生变化时才触发推送。
4.3 从服务端日志里反挖值得推的URL
这是一个容易被忽略但很好用的方法。把服务端的访问日志拉出来,过滤出机器人访问的记录,按URL聚合,看两个维度:抓取次数和抓取结果。
抓了很多次但一直没进索引的URL,说明这个页面反复被抓但始终没通过后面的关卡,要么是内容质量不行,要么是存在技术障碍。这类URL值得单独拎出来分析。
从来没被访问过的新URL,说明连入队都没成功,那就该检查推送链路是不是断了。
日志里还能看到机器人抓取时拿到的状态码和响应耗时。如果某个目录下的页面普遍响应超过两秒,那这个目录的抓取预算一定被压得很低,优化方向就明确了——别急着推,先把响应时间降下来。
日志分析不需要多复杂的工具,一条grep加一段聚合脚本就够了,关键是养成定期看的习惯。我一般每周跑一次,看看这一周机器人抓了哪些、没抓哪些,和推送记录做对比。
5. 推之前先自检:一份能落地的页面质量预审清单
5.1 内容层:主体信息能不能被直接读到
这一层是最容易出问题也最容易被忽视的。很多单页应用、内容站,页面在浏览器里看着很完整,但原始HTML里正文只有几行,剩下的全靠脚本渲染。机器人拿到的就是那个空壳。
验证方法很简单,不要用浏览器的“查看源代码”看渲染后的DOM,要用命令行工具直接抓原始响应,看返回的HTML里有没有完整的正文。如果正文是空的,说明你的内容依赖客户端渲染,这时候要么做服务端渲染,要么做静态化,指望平台去执行你的脚本,成功率很低。
第二个检查点是正文的信息密度。这里不是让你凑字数,而是看一段话里有没有实质信息。模板套出来的“产品优势一二三”加几句空话,正文看着几百字,实际信息量接近于零。这类页面抓取正常,解析也正常,但会卡在质量评估上,表现就是“抓了很多次,就是不建索引”。
第三个检查点是标题与正文的一致性。标题写得很吸引人,正文内容对不上,这种行为在评估体系里是有明确惩罚的。我在做预审时会随机抽几条URL,只看标题和前两段,判断能不能对得上,对不上的一律退回重写。
第四个检查点是重复度。站内不同URL之间,正文相似度很高的情况特别常见,尤其是做地域分站、产品型号变体的站。这类页面建议要么合并,要么大幅差异化,硬推只会全部卡在去重那一关。
5.2 技术层:状态码、canonical与索引指令
技术层的检查可以做成自动化脚本,接入到发布流程里,不通过就不允许推送。
状态码要保证是200。301和302不是“正常页面”,它们会被当作跳转处理,不进入正常索引流程。404和410是明确的下线信号。503要特别小心,短时间内大量503会被判定为服务不可用,抓取预算直接归零。
canonical要自指且唯一。我见过页面里同时存在两个canonical标签的,一个是模板里写死的首页地址,一个是动态注入的当前页地址。这种情况下平台只能自己猜,猜错的比例不低。检查方法是在原始HTML里搜canonical,确认只有一个,且指向当前页的最终地址。
索引指令要确认没被误伤。meta robots里的noindex、响应头里的X-Robots-Tag,这两处都要看。测试环境复制过来的模板、按条件注入的配置,都可能把noindex带到线上。这类问题最坑的地方在于页面本身完全正常,浏览器访问毫无异常,只有机器人拿到的响应头里有那个标记。
移动适配和首屏渲染速度也要纳入检查。响应式是主流方案,但要注意别搞成两套独立模板却互相指向对方的canonical。首屏渲染时间这个指标,我一般要求移动端在合理区间内,具体数值不同站点差异大,关键是看趋势别恶化。
| 检查项 | 判定标准 | 不通过的后果 |
|---|---|---|
| 原始HTML正文 | 不依赖脚本即可读到主体内容 | 抓取到空壳,不建索引 |
| 标题与正文匹配 | 标题描述的实体在正文中出现 | 质量评估扣分 |
| 站内重复度 | 与站内其他页面正文差异明显 | 去重环节淘汰 |
| 状态码 | 返回200 | 跳转或下线处理 |
| canonical | 唯一且自指 | 索引目标混乱 |
| 索引指令 | 无noindex、无X-Robots-Tag屏蔽 | 完全不进索引 |
5.3 聚合页与筛选页:最容易被误推的一类URL
标签页、分类页、搜索结果页、带参数的筛选页,这四类是推送清单里最容易被误加进去的。
它们的共同特点是URL数量巨大、内容高度模板化、相互之间大量重复。一个电商站,商品筛选参数组合起来能生成几十万个URL,这些地址如果全部推送,配额瞬间清零,而且会给平台留下“这个站大量生产低质页面”的印象,连累正常商品详情页的抓取。
我的处理原则是:聚合页只在内容足够丰富、且有独立检索价值时才推送。比如一个标签页下面聚合了几百篇相关文章,页面上有摘要、有分类、有筛选,这种有独立价值。如果只是把列表换个标题、内容完全依赖翻页,那就不必推,甚至可以在页面上加nofollow,减少机器人的无谓消耗。
筛选页更严格,除了少数几个有明确检索意图的参数组合,其余一律不推。参数顺序、大小写、多余的空值参数,这些变体会被识别成不同的URL,如果不做规范化,光一个筛选功能就能生出成千上万条垃圾地址。URL规范化这件事要在路由层就做掉,别指望推送脚本去兜底。
6. 收录迟迟不动时的分层排查路径
6.1 从机器人访问日志开始倒推
收录出问题,第一反应不该是加大推送量,而是先搞清楚机器人到底来没来。日志里能拿到的信息比后台报表细得多。
先在日志里按机器人标识过滤,看最近一周的访问趋势。如果访问次数是零,说明站点根本没被发现,问题出在验证、robots或者站点地图提交上,往上排查。如果访问次数正常但集中在少数几个页面,说明抓取预算被压缩了,要去看服务器响应时间和站点整体质量。
如果访问次数为零但推送显示成功,重点查三处:robots.txt里有没有整站屏蔽的规则、服务器防火墙或者CDN有没有对特定标识做拦截、站点验证的域名和实际推送的域名是否一致。
日志里还要看返回码分布。如果机器人访问的响应里出现大量5xx,那是服务端的问题,不是推送的问题。如果出现大量302,说明有跳转链在消耗抓取预算,该合并的跳转要合并。
响应耗时这个指标经常被忽略。机器人抓一个页面花三秒和花三百毫秒,能抓的页面数量差了十倍。如果日志里显示某个目录下的平均响应时间明显偏高,那这个目录的页面收录慢就是必然的,优化方向是把数据库查询、外部接口调用这些耗时环节去掉。
6.2 抓取正常但不建索引的几种典型形态
抓取正常、返回200、正文可读,但就是不进索引,这种情况最难查,因为技术上“没毛病”。这时候要从内容侧找原因。
第一种形态是内容太薄。整页除了标题、几张图、一段产品参数,没有任何延展信息。这类页面在评估体系里属于“有页面但价值不足”,抓了也不建。解决思路不是硬凑字数,而是给页面增加真正有用的信息,比如使用场景、常见问题、对比说明。
第二种形态是内容与已有页面高度重复。这个重复不只是站内的,也可能是跨站的。批量生产的模板文案、从别处复制过来的参数表,都会被识别出来。判断方法是随机抽几段正文去搜,看看能不能找到一模一样的内容。
第三种形态是页面结构混乱。正文和导航、推荐、广告混在一起,没有任何语义标记,导致正文抽取失败。这种情况表现是抓取正常、内容也有,但平台识别不出主体是什么。加语义化标签、把正文包在明确的容器里、清理掉正文区的无关模块,能明显改善。
第四种形态是站点的整体质量拖累。当站内低质页面占比过高时,即使个别页面做得不错,也会被整体拖累。这种情况下单条推送没用,得先做减法——把明显低质的页面下线、合并或者设为不索引,把站点的质量基线抬上去。
6.3 整站质量拖累单页的情况怎么判断
判断方法不难:看收录率的结构分布。
如果站内某几个栏目收录率明显高于其他栏目,说明差异来自栏目本身的质量,是局部的。如果全站各个栏目收录率都很低,且抓取频次在下滑,那基本可以判定是整站层面的问题。
整站层面的问题通常有几个来源:大量重复的模板页、大量无内容的空页面、大量失效链接、长期不更新。这四条里任何一条严重到一定程度,都会拖累全站。
处理顺序上,先做减法再做加法。把明显没价值的页面批量处理掉——状态码改成正确的下线码,或者加不索引标记,或者合并到上级页面。这一步做完,等一到两个观察周期,看抓取频次和收录率的曲线有没有回升。回升之后再考虑把优化过的页面重新推一遍。
急着做加法是最常见的错误。站点整体质量没起来,推多少条都是往里填,填进去也是石沉大海。
7. 长期观察:哪些指标值得盯,哪些动作不要做
7.1 索引量、抓取频次、点击量要分开看
这三个指标经常被混着看,导致判断失准。
索引量反映的是“有多少页面进了库”,它是慢变量,短期内波动不大,适合看趋势。抓取频次反映的是“平台愿不愿意来”,它是先行指标,频次下滑往往比索引量下滑早出现一到两周,是预警信号。点击量反映的是“页面在结果里被选中了多少次”,它受排序影响,跟收录质量有关但不完全等价。
我的观察节奏是:每周看一次抓取频次,关注趋势有没有异常下滑;每两周看一次索引量,关注增长曲线是否停滞;每月看一次点击量,结合具体页面的排名变化做归因。三个指标分开看,判断会清楚很多。
还有一个容易被忽略的指标是抓取成功率。日志里把机器人访问的响应码统计出来,2xx的占比就是成功率。这个数字低于一个合理区间,说明服务端稳定性有问题,这时候优化服务器比优化内容更紧迫。
7.2 几个我踩过的操作习惯
避开这几件事,能少走很多弯路。
不要频繁改URL结构。改一次,旧地址全部要跳转,索引要重新建立,中间会有一段明显的真空期。如果非改不可,做好全量301,并且保留至少一个季度再考虑下线。
不要用302做永久跳转。302是临时跳转,平台不会把权重传递过去,长期挂着302等于告诉平台“这个地址早晚要回来”,索引状态会一直悬着。
不要为了让站点地图“看起来更新”而伪造lastmod。这个字段一旦失去可信度,后面所有页面都会受影响,包括真正更新的那些。
不要在站点大面积改版的同时加大推送量。改版期间页面结构不稳定,推上去抓到的可能是过渡态,反而留下负面记录。正确做法是改版期间降低推送频率,等结构稳定后再恢复。
注意服务器时间的时区一致性。内容发布时间、lastmod、日志时间如果时区不统一,在排查“为什么这条没被抓”的时候会带来很大困扰,我自己就被这个问题绕过一次,查了半天发现是时区差了几个小时。
8. 最后聊几句实操里的体会
做这块时间长了,最大的感受是:推送这件事的技术门槛不高,难的是把它当成一个持续运营的系统来对待。写一个能调通的推送脚本,一个下午就够了;但要让它长期稳定产出,需要的是把增量识别、配额分配、失败重试、质量预审这些环节都串起来,形成一个能自己跑、出问题能自己报警的链路。
我现在的习惯是每次新的内容类型上线,先小批量试推十几条,等一个观察周期看收录转化率,转化率能接受再放大到全量。这个动作看着慢,但比一上来就全量推送然后发现方向错了要快得多。前面提到的那个“推了两百条收录个位数”的情况,最后也是靠这个笨办法解决的——把推送清单里的列表页、筛选页、空模板页全部去掉,只留真正有内容的详情页,收录率从个位数百分比回到了一个正常水平。
另外就是别迷信后台的数字。后台看的是结果,日志看的是过程。结果不好时,只有过程数据能告诉你问题出在哪一层。每周花半小时看一次日志,比每天盯着索引量刷新的焦虑值有用得多。