商品上架时间实测:43912件里老货没掉队,漏的是新货
本文目录
- 商品货龄该用哪个时间戳字段判断?
- 三个时间戳字段各自记录什么
- 三个字段的年份分布对比
- 复抓对照下,三个时间戳字段各变动了多少?
- 复抓对照的设计口径
- 一个字段零变动,一个字段全变动
- 分类维度的变动率明显更低
- 这43912件商品到底有多老?
- 整体货龄分布:过半不到一年,一成二超过三年
- 逐站货龄中位与品类的关系
- 五年以上的那批商品是什么类型
- 从建档到上架,created_at与published_at差多少天?
- 建档与上架的差值中位44天
- 109件负差值的成因
- 老商品的sitemap收录率是否低于新商品?
- 按货龄分桶的总量口径看不出规律
- 同站配对之后的收录率对照
- 唯一符合直觉的那个反例
- 老商品会不会掉出首页两跳可达范围?
- 两跳可达这一层,老货确实吃亏
- 三分之一的站会把老货挤出导航
- 各站最老的商品,前台还正常在售吗?
- 56个站的最老商品状态码全部是200
- 缺货比例的同站配对结果
- 3个404逐个核对后只剩1个
- 这轮实测的读数在哪三处出过问题?
- 接口返回顺序与分类页展示顺序对不上
- 脚本通道被限流时浏览器通道畅通
- 地区路由把采集识别成了亚太访客
- 这套货龄审计怎么在自己站上复现?
- 三步复现流程,跑完之前先别删商品
- 三个判据指向的是同一个问题
- 哪些站可以不做这套检查
- 常见问题解答
- 商品的最后更新时间为什么完全不能用?
- 那要判断一个页面有没有真的改过,该看什么?
- 老商品到底该不该下架?
- 新品迟迟不被收录,最该先查哪一步?
- 建档时间和上架时间差很多,说明有问题吗?
- 我的站不是Shopify,这套方法还能用吗?
- 为什么强调要用浏览器核对,脚本不够吗?
- 这些数字多久会过时?
- 权威参考资料
摘要:从60个英文电商站取回43912件在售商品的全部时间字段,三年以上的有5361件,占12.2%;五年以上2331件,占5.3%;最老的一件已经挂在货架上4704天。逐站配对之后,老货被系统性遗忘这个假设没有成立:33个站里只有1个站的老货进sitemap的比例明显低于新货,13个站反而比新货更高。56个站各自最老的那件商品,前台逐个打开全部回200,一个404都没有。
你店里现在卖得最久的那件商品,是哪一年上架的?
大部分人会去后台翻。翻到的通常是一个叫“最后更新”的时间,显示今天或者昨天,于是结论变成:我的商品都很新,都在维护。
这个结论几乎一定是错的。那个字段记录的根本不是你想知道的事。
商品货龄该用哪个时间戳字段判断?
Shopify的商品对象上挂着三个时间戳,名字相近,含义差得很远。
三个时间戳字段各自记录什么
按Shopify官方的product对象文档,created_at是这条商品记录被建出来的时刻,published_at是它对外可见的时刻,updated_at是它最后一次被写入的时刻。前两个由人的动作决定,第三个由系统的动作决定,而系统写入的频率比人高得多。
这次的分母来自各站自己的商品清单出口,就是那个不用登录就能读的/products.json。这个出口保哥单独写过一篇,那篇讲的是它泄露了什么,这次只从里面读三个日期。60个站里有4个拿不到有效清单(域名解析不了或者清单为空),剩下56个站合计43912件商品,每一件都同时带着这三个字段,没有一件缺。
三个字段的年份分布对比
把43912件商品按这三个字段各自的年份摊开,分布差异立刻显出来。
| 年份 | 按created_at | 按published_at | 按updated_at |
|---|---|---|---|
| 2026 | 15869(36.1%) | 23613(53.8%) | 43912(100%) |
| 2025 | 16169(36.8%) | 12532(28.5%) | 0 |
| 2024 | 5929(13.5%) | 3672(8.4%) | 0 |
| 2023 | 1789(4.1%) | 1066(2.4%) | 0 |
| 2022及更早 | 4156(9.5%) | 3029(6.9%) | 0 |
第三列没有分布可言,它是一根竖线。43912件商品的updated_at全部落在采集时刻往前24小时以内,一件例外都没有。中位数是1天,最大值也是1天。
拿这个字段去回答“这件货多久没人碰过”,无论查哪一家店,答案都是“昨天刚碰过”。这个字段在这个问题上的信息量等于零。
复抓对照下,三个时间戳字段各变动了多少?
单次快照最多只能推断出“看起来都很新”,要把字段行为坐实,还得再抓一次。
复抓对照的设计口径
第二天早上用完全相同的方式把同一批站再抓一遍,间隔中位10.2小时,然后按商品id逐件对齐,看三个字段各变了多少件。关键不在于updated_at变没变,而在于同一次测量里还有两个字段可以当基线:三个都变,说明采集不稳;只有一个变,那就是字段本身的行为。补一组对照再下结论这一步,吃过一次亏之后就不再省。
一个字段零变动,一个字段全变动
49个站顺利对齐,共9426件商品可逐件比对,两端的分界干净得不像实测数据。
| 字段 | 10.2小时内变动 | 占比 |
|---|---|---|
| created_at | 0件 | 0.00% |
| published_at | 105件 | 1.11% |
| updated_at | 9426件 | 100.00% |
49个站,每一个站都是100%,每个站的每一件都被写过。同一时刻、同一段网络、同一个脚本,created_at一件都没动。
那105件变了published_at的商品也要看一眼:其中104件出自同一个站,剩下1件出自另一个站。这个字段在47个站里纹丝不动,只有一个站在半夜做过一次批量重新上架。它会变,但变动对应了一次真实的运营动作。
分类维度的变动率明显更低
同一次复抓里还比了7423个分类。分类的published_at变动0个,updated_at变动1764个,占23.76%,商品数变动159个,占2.14%。
如果updated_at的刷新是平台的定时任务,分类那边也该是100%。实际只有不到四分之一。商品那边的100%说明每一件商品每天都真的被写了一次,库存、价格、变体、第三方应用同步,任何一样都够。sitemap里那个修改时间记的是请求时刻,那属于生成环节的问题;这里是数据层面的问题,两者机制不同,后果一样:你拿到的时间戳跟内容改没改无关。
这也解释了很多站的sitemap为什么看起来天天全量更新。平台的lastmod就是从这个字段来的,而这个字段每天都在动。谷歌的sitemap构建文档要求这一列填内容最后一次实质性变更的时间,填得不诚实会被直接忽略。手工改修改日期骗不骗得到搜索引擎是人主动做的另一件事;平台这一侧属于默认行为,店主多半不知道自己每天在向爬虫宣布“我全站都变了”。
这43912件商品到底有多老?
把updated_at放下,改用created_at重新量一遍,站点的年龄结构就清楚了。
整体货龄分布:过半不到一年,一成二超过三年
| 货龄 | 件数 | 占比 |
|---|---|---|
| 不到1年 | 22953 | 52.3% |
| 1到2年 | 12118 | 27.6% |
| 2到3年 | 3480 | 7.9% |
| 3到5年 | 3030 | 6.9% |
| 5年以上 | 2331 | 5.3% |
中位数342天,四分位是189天和649天,P90是1278天。最老的一件建于2013年,到采集那天已经4704天,将近13年。
电商本来就是新品驱动,这个分布本身并不意外。更该对照着看的是它跟“最后更新时间”给出的画面完全对不上:一个说全站昨天刚碰过,另一个说有5361件货已经在架子上待了三年以上。
这里量的是商品的年龄,跟域名年龄是不是排名因素不是一回事,跟用网页存档倒推域名什么时候真正开始有内容也不是一回事。那两件事量的是站,这里量的是站上的商品。
逐站货龄中位与品类的关系
把货龄中位数按站排开,跨度相当大。
| 站点 | 商品数 | 货龄中位 | 三年以上占比 |
|---|---|---|---|
| taylorstitch.com | 3000 | 1510天 | 65.7% |
| wusthof.com | 444 | 1413天 | 82.2% |
| snowpeak.com | 852 | 1175天 | 50.4% |
| decathlon.com | 518 | 700天 | 35.3% |
| allbirds.com | 294 | 643天 | 22.8% |
| beistravel.com | 460 | 161天 | 7.2% |
| dollarshaveclub.com | 128 | 140天 | 24.2% |
刀具站82.2%的商品超过三年,行李箱站只有7.2%,差别来自品类的物理属性,不来自运营水平。一把厨刀的产品周期以十年计,一只箱子的配色一年一换。所以“商品平均多老”这个指标不能跨站横比,只能跟自己的去年比。
五年以上的那批商品是什么类型
五年以上的2331件里抽几件看:allbirds那双womens-wool-runners-natural-white建于2018年11月,2857天;untuckit有一件4107天;thirdlove 4001天;brooklinen 4025天。都是主力款的基础色,不是清仓尾货。
这批商品的性质直接决定后面所有结论的解释方向:它们是店里最经典的那几件,不是忘了删的垃圾。僵尸SKU那套救活逻辑对它们不适用,它们卖了七八年,不缺买家。
从建档到上架,created_at与published_at差多少天?
既然created_at和published_at是两个字段,那它们的差值本身就是一条信息:一件货从录进系统到对外可见,中间等了多久。
建档与上架的差值中位44天
43912件里,两个日期不在同一天的有37874件,占86.2%。差值中位44天,P75是170天,P90是429天,最大4074天,有一件货在库里躺了11年才上架。
44天这个中位数符合直觉:拍照、写文案、定价、等库存到仓,一个多月不算慢。更需要关注的是P90那个429天,意味着每十件里就有一件在系统里等了一年多。做上新节奏复盘时,这个差值比后台报表更接近真实进度。
109件负差值的成因
有109件商品的published_at早于created_at,最极端的一件早了1499天。按字面理解,这件货在被创建之前四年就已经上架了。
这109件分布在12个站,其中一个站独占69件,指向的是数据迁移:换平台、换主题、批量重建商品记录的时候,新记录拿到了新的created_at,但published_at从旧系统原样带了过来。占比只有0.2%,成不了普遍结论,但可以当排查线索:如果你的站上突然冒出一批负数,多半是有人动过底层数据。
老商品的sitemap收录率是否低于新商品?
接下来是这轮实测真正要回答的问题:商品在架时间长了,会不会被系统漏掉。
按货龄分桶的总量口径看不出规律
把所有商品按货龄分桶,逐桶算在sitemap里的比例:不到1年85.4%,1到2年84.3%,2到3年92.2%,3到5年90.4%,5年以上82.3%。
五个数字上上下下,没有单调趋势。这种口径下最容易发生的,是从里面挑一个符合预期的数字讲故事。问题在于这个百分比被大站主导:taylorstitch一家就贡献了3000件商品,它的口径歪一点,整个桶就跟着歪。
同站配对之后的收录率对照
正确的做法是把每个站当成自己的对照组:在同一个站里,比较三年以上的老货和两年以内的新货,各自进sitemap的比例。两组都至少有20件的站才进统计,一共33个。
| 配对结果 | 站数 |
|---|---|
| 老货明显更差(低于新货1个百分点以上) | 1 |
| 基本一样(相差1个百分点以内) | 19 |
| 老货反而更好(高于新货1个百分点以上) | 13 |
差值的中位数是0.0个百分点。19个站里老货和新货的收录比例分毫不差,多数是双双100%。
13个老货更好的站里,差距大到很难忽略:dreametech的老货88.5%在sitemap里,新货只有36.4%;dollarshaveclub老货100%、新货66.3%;magicspoon老货64.6%、新货40.2%。这几个站真正漏掉的,是最近两年上架的那批。
成因不难推。sitemap按某种规则批量生成,老货早就在里面了,新货要等下一次生成、等某个开关、等某个应用同步。这跟电商sitemap的进出场机制是同一回事:进场那一步,多数站根本没有验收。全站逐条查一遍代价太大,按页面模板抽样更现实,但抽样的前提是先知道该按什么维度分层,“上架年份”正好是一个现成的分层轴。
唯一符合直觉的那个反例
33个站里只有taylorstitch符合“老货更容易被漏掉”的直觉:老货68.3%在sitemap里,新货97.0%,差28.7个百分点。这个站的货龄中位1510天,三年以上占65.7%,是全样本里最老的一家。只有当老货多到成为主体的时候,漏掉老货才会变成一个规模问题。
老商品会不会掉出首页两跳可达范围?
收录是爬虫那一侧的事,用户这一侧还有另一道关:从首页出发,经过首页上点得到的分类,两跳之内能不能走到这件货。这个口径上一篇已经完整跑过一遍,这次直接把货龄这一维叠上去。
两跳可达这一层,老货确实吃亏
同样做同站配对,28个站够条件:老货明显更差的10个站,基本一样的10个站,老货反而更好的8个站,差值中位仍然是0.0个百分点。
更差的那10个站,差得非常明显:ice-watch老货可达率46.2%、新货95.9%,差49.8个百分点;tentree差43.5个;marinelayer差38.4个;decathlon差21.1个。
三分之一的站会把老货挤出导航
10比10比8这个分布,比“老货会被埋起来”这句话精确得多:三分之一的站会把老货从导航里挤出去,三分之一无差别,还有三分之一的老货反而站得更稳,因为老货往往是主力品类,主力品类的分类入口一直挂在首页上。
货架本身也得算进来。这些站一共开了19405个分类,首页真正点得到的只有一成七,其中一成的分类里一件货都没有。老货走不到,有时候并不是被挤下去了,而是装它的那个货架从来就没挂上去过。
会挤的那批站有个共同点:分类切得很细、上新很勤,新品会自动进“新品”“本周上新”这类入口,老货则要靠人手动维护分类归属。站点架构那笔账在这里体现得最直接:架构每上一次新就退化一点,搭一次并不能一直有效,跟内链结构会自己烂掉是同一个道理。
各站最老的商品,前台还正常在售吗?
清单里写着,不等于前台还在。这一步不能省:上一次做分类清单比对的时候,正是这道闸当场废掉了一条本来会被当成主要结论的判断。
56个站的最老商品状态码全部是200
做法是每个站取最老的一件和最新的一件,用真实浏览器打开,看状态码、看有没有加购按钮、看结构化数据里的库存状态。为什么用浏览器而不是脚本,后面那一节会讲。
56个站的最老商品,56个200,一个404都没有。里面46件有加购按钮,按谷歌的商品结构化数据规范标着有货的41件。这批平均已经上架三到十年的商品,前台状态跟新品没有实质差别。
缺货比例的同站配对结果
53个站两件都正常打开,把“页面上出现缺货字样或者结构化数据标着无货”当成缺货,做同站配对:
| 老货缺货 | 新货缺货 | 站数 |
|---|---|---|
| 是 | 否 | 7 |
| 否 | 是 | 5 |
| 都缺货 | — | 8 |
| 都有货 | — | 33 |
7比5,基本对称。“老货多半已经断货,留着占位置”这个说法,在这个样本上不成立。页面正文长度也是同样的结论:老货中位4220字符,新货3944字符,老货甚至还长一点。
3个404逐个核对后只剩1个
唯一出现404的是新货那一组,3件。最新上架的商品前台打不开,这个读数看着可以直接写成结论,但逐个核对之后,三件里有两件不能算数。
ugreen那件的域名会按访问来源做地区路由,上一批已经因为同样的原因把整站扣掉;functionofbeauty连老货那一页的h1都渲染成了购物车,说明它的商品页在无头浏览器里根本没正常出来,整站数据都不能用。真正干净的只有peakdesign一件:出口里明明白白写着这个handle,前台回404,而且是自定义的404页。
所以能确认的只有一句:每站抽一件的量级下,新货出现过前台失效,老货一件都没有。要把它变成一个可外推的比例,还得再抓一轮。
这轮实测的读数在哪三处出过问题?
这一节是整轮实测里最贵的部分。三处读数出过问题,其中两处是靠浏览器才看出来的,脚本层面完全无感。
接口返回顺序与分类页展示顺序对不上
本来还想量一件事:老货在分类页里排第几位。分类的商品清单接口带顺序,直接数位次就行,这个做法在脚本层面挑不出毛病。
于是挑了12个站,用浏览器打开对应的分类页,只数正文区里可见的商品链接,按DOM顺序去重,跟接口返回的前12个对照。结果:5个站前12位完全对上,5个站一个都对不上,1个站的/collections/all在前台压根是个系列列表页,正文区一个商品链接都没有,还有1个站的前台显示“这里什么都没有”,而接口说这个分类里有294件商品。
接口的顺序是集合的存储序,前台的顺序是主题模板套上默认排序规则之后的展示序,两者只在没人改过排序的站上重合。位次这条腿因此整条砍掉,留着就是一条有一半概率出错的结论。商品列表页那97条准则里有相当一部分也卡在这个坑上:准则本身没问题,量它的尺子在页面上取不到值。用错请求方法查响应头犯的是同一个毛病,工具没坏,问的方式不对。
脚本通道被限流时浏览器通道畅通
复抓跑到第36个站的时候开始连续返回429,而且是跨域名的:36个不同品牌、不同域名的站同时开始拒绝,说明限流不在各家自己的服务器上,在平台的边缘层。响应里没有Retry-After,恢复用了大约35分钟。
同一时刻还发生了另一件事:浏览器那一路的56个站、112个页面,一个429都没有,全部200。同一台机器、同一个出口地址、同一分钟。
公平起见补一句:后来又跑了一轮浏览器采集,114个页面里出现了3次429。浏览器通道并非完全免疫,只是阈值明显高得多:脚本那边是连续25个站全军覆没,浏览器这边是零星3个。
被限的是客户端类型,不是这个IP。用脚本去量一个站,量到的可能是这个站给脚本准备的那一份待遇。这跟决定收录哪一版页面的其实是十分钟前路过的那个用户是同一类问题的两个面:一个是内容因人而异,一个是通道因人而异。做审计的时候,两个通道都得留一条。
地区路由把采集识别成了亚太访客
112次浏览器访问里,25次最终落到了不同的地址上:aloyoga和glossier跳进了/en-sg/,dollarshaveclub跳到了us.子域,casper和getquip收敛到了带变体参数的地址。前两类是按访问来源做的地区路由,这意味着这次看到的商品页并不都是这些站的主版本。
这不影响“老货还在不在”这个判断,404就是404,跟地区无关。但要做内容层面的对比,就必须先把地区这一维锁死,否则量的是两个站。
这套货龄审计怎么在自己站上复现?
不必等到有人来做审计,自己站上跑一遍,半小时就够。
三步复现流程,跑完之前先别删商品
第一步,导出全部在售商品的建档时间,按年份分桶,看看三年以上的占多少。这一步只需要一次数据库查询或者一次接口翻页。第二步,把这批老货的地址跟当前sitemap比对,看有多少不在里面;反过来也要比,看sitemap里有多少地址在商品表里已经不存在。第三步,抽10到20件老货,用浏览器逐个打开,确认它们不是软404、不是跳转到了首页。
顺序不能颠倒:很多人拿到第一步的分桶结果就开始动手清理三年以上的那批,而保哥这次的实测说明,那批多半是最不该动的。等第二步和第三步跑完,名单会完全换一批。
三个判据指向的是同一个问题
这三步问的其实是同一件事:这件东西还在不在你的管理范围里。在库里能查到、在sitemap里写着、在前台打得开,三者缺一样都算失联。
这三个判据不能只用在老货上。这次实测最反直觉的一点是,漏掉的更可能是新货,新货还没来得及被任何一套自动流程收进去。所以每次上新之后,最该做的一次检查是“这批刚上的货进sitemap了吗”,而不是“老货该不该清理了”。
哪些站可以不做这套检查
如果你的商品总数在三位数以内、上新频率低于每月一次,那么这套检查的价值有限,肉眼过一遍分类页就够了。它真正值钱的场景是SKU上千、有第三方应用在写商品数据、并且换过一次主题或者平台,这三个条件凑齐两个,出问题的概率就相当高。
还有一种情况要单独说:如果你正在做内容审计的留改并删决策,别把商品页和内容页套同一套标准。文章会衰减,老内容的流量确实会悄悄掉,但一把卖了八年的厨刀不会因为上架久了就变差。判断商品该不该下架的依据是销量、库存和毛利,不是年龄。
常见问题解答
商品的最后更新时间为什么完全不能用?
它记录的是这条记录最后一次被写入的时刻,而不是内容最后一次被人修改的时刻。库存扣减、价格同步、第三方应用回写、批量任务扫过,任何一样都会刷新它。实测里43912件商品的这个字段全部落在24小时以内,49个站复抓的变动率是100.00%。一个每天都返回“刚刚”的字段,用来判断新旧没有任何意义。
那要判断一个页面有没有真的改过,该看什么?
看内容本身。取两次快照做正文差分,比看任何时间戳都可靠。只能用时间戳的时候,优先用建档时间加上一份自己维护的变更记录;变更记录是你自己写的,它才对应真实的动作。sitemap里那个修改时间同样不能直接信,很多站的那一列就是生成文件的当下时刻。至于内容该不该更新,那是新鲜度与QDF机制要回答的问题,跟“它上次到底变没变”是两个层面。
老商品到底该不该下架?
先分清是“不卖了”还是“卖得久”。真正停售的商品,处置方式取决于有没有替代品和有没有外链,301、410和软404怎么选是另一套决策。卖得久的商品不需要处置,这次实测里56个站最老的那件商品全部正常在售,其中相当一部分是主力款。
新品迟迟不被收录,最该先查哪一步?
先查它在不在sitemap里。这次配对实测发现,13个站的新货进sitemap的比例低于老货,最极端的一个站新货只有36.4%在里面。多数人会先去改标题、补结构化数据,但如果地址根本没进清单、站内又没有链接指过去,改什么都白搭,这跟孤岛页面检测要解决的是同一类问题。
建档时间和上架时间差很多,说明有问题吗?
不一定。整体中位是44天,一个多月完成拍照、文案、定价、备货是正常节奏。需要警惕的是两头:差值超过一年的那10%,多半是排期一直往后拖或者干脆忘了;差值是负数的,说明这批记录被迁移或者重建过,底层数据动过手脚。
我的站不是Shopify,这套方法还能用吗?
能,字段名要换。WooCommerce看post_date和post_modified,Magento看created_at和updated_at,自建站看你自己的表。判据不变:任何一个会被库存同步刷新的字段,都不能拿来判断新旧。
为什么强调要用浏览器核对,脚本不够吗?
这次三处读数出问题,两处是浏览器发现的:分类页的商品顺序跟接口对不上,以及脚本被平台限流的同时浏览器畅通无阻。脚本快、便宜、能跑全量,但它看到的是接口愿意给它的那一份。全量用脚本、抽样用浏览器,是目前最省力的组合。
这些数字多久会过时?
货龄分布本身在持续变化,半年后重跑必然不同。但两条结论稳定性很高:一是更新时间字段被系统刷新这件事属于平台机制,不会因为站点不同而不同;二是“老货被遗忘”这个直觉在同站配对下站不住,它的成因是运营流程,不是时间流逝本身。真要复现,重点复现方法,不是数字。
权威参考资料
本文标题:《商品上架时间实测:43912件里老货没掉队,漏的是新货》
本文链接:https://zhangwenbao.com/product-age-created-at-audit.html
版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0