展会动态页的时效信号怎么写:temporalCoverage 与 dateModified 让外贸站新闻被 AI 搜索持续引用
先说一个真实场景。今年 7 月,一个做工业阀门出口的朋友把站点后台数据发给我:他们的展会动态栏目更新很勤,半年发了二十几篇广交会、汉诺威工博会的现场报道,可过去 45 天里,Perplexity、Google AI Overview 这类 AI 搜索入口对该栏目的引用次数是 0,抓取频次也掉到了每周两三次;反倒是一篇三年前的老产品页,每周被抓十几次。他第一反应是内容质量不行,想把小编换了。我看了页面源码之后告诉他:不是内容差,是页面压根没告诉机器"这条新闻是什么时候的事、活动到哪天截止、内容最后改过没有"。AI 引擎读不懂时效,就只能按老办法猜。
猜的结果就是:你的"2026 年 4 月广交会见闻"在 9 月被当成过期信息打冷宫,而隔壁把时间写得清清楚楚的竞品页面,一直在被引用。这篇文章就把外贸站展会动态页的时效信号体系拆开讲一遍:schema.org 的 temporalCoverage、dateModified、datePublished 怎么配合,NewsArticle 类型里的 dateline、printEdition 要不要用,以及我们实测的 45 天对照数据。
AI 搜索引擎判定内容新鲜度的机制
要理解时效信号为什么值钱,得先看 AI 引擎这边的抓取和引用流程和传统搜索引擎差在哪。传统搜索抓完建索引就完事,AI 搜索引擎多了一步:把抓到的内容切块、向量化,塞进推理可用的知识库里,回答用户问题时按相关性召回。这一步决定了"新鲜度"不只是排名因子,而是召回门槛——内容被判过期,连进候选池的机会都没有。

判定新鲜度的依据大致分两类。一类是显式信号:页面结构化数据里声明的 datePublished、dateModified、temporalCoverage,HTTP 响应头里的 Last-Modified。另一类是隐式信号:正文里出现的日期字符串、页面内容哈希有没有变化、站点的平均更新节奏。显式信号权重高、成本低,机器直接读字段;隐式信号要做内容比对,误差大。展会动态这种强时间属性的内容,显式信号基本就是最靠谱的入口——活动本身就有起止日期,你不写出来,机器只能从"4 月 15 日,我们在琶洲馆 A 区的展位……"这种叙述里反推。
flowchart LR
A[AI 引擎抓取队列] --> B[解析页面结构化数据]
B --> C{temporalCoverage<br/>是否标注活动区间}
C -- 有 --> D[按区间评估有效性<br/>活动期内正常召回]
C -- 无 --> E[退回 dateModified 推断<br/>超过阈值标记为旧内容]
E --> F[降低抓取频次<br/>引用候选池降权]
D --> G[持续进入引用候选池]
B --> H{dateModified<br/>晚于 datePublished?}
H -- 是 --> I[识别为已更新内容<br/>重新评估时效]
H -- 否 --> C
流程图里最要命的是右上那条路径:没有 temporalCoverage 的页面,一旦 dateModified 距今超过引擎自己的阈值(不同引擎阈值不一样,业内观察普遍在几十天量级),抓取频次就往下掉。展会新闻恰恰容易踩这个坑——活动结束那几天热度最高,随后页面半年不动,机器自然认为它没价值了。其实活动结束了,页面里"下届展会时间""展后报告下载"这些信息照样有引用价值,只是你没给机器一个重新评估的理由。
datePublished 和 dateModified 各管什么
这两个字段看着简单,误用率却高得离谱。datePublished 表示内容首次公开发布的时间,dateModified 表示内容最近一次实质性修改的时间。三个常见错误:全站模板统一输出同一个日期;用 cms_mtime(记录最后保存时间的字段)当 dateModified,编辑改个错别字也算修改;反过来,内容明明大改了(比如补充了展后成交数据),dateModified 却没动。
正确做法是把"实质性修改"的定义写进发布流程:新增段落、更新数据、替换图片算修改;错别字、排版调整不算。有条件的话在 CMS 里加个 checkbox,让编辑自己勾"本次更新是否对外可见",勾了才刷新 dateModified。
temporalCoverage:把活动的时间区间写进页面
temporalCoverage 在 schema.org 里的定义是"the temporalCoverage of a CreativeWork indicates the period that the content applies to",也就是这段内容描述的时间范围。它原本常用于数据集(比如"本数据集覆盖 2020-2024 年降水记录"),用在新闻页上的逻辑是:这篇展会报道描述的是 2026 年 9 月 15 日到 18 日发生的事,那 temporalCoverage 就标这个区间。AI 引擎读到这个区间,可以做出比"发布于三个月前"精细得多的判断——区间还没开始,是预告页;区间进行中,是实时报道;区间结束不久,是回顾报道,仍然可以引用。
写法上用 ISO 8601 的时间区间格式,中间一道斜杠。这是后面动手部分的重点,先记住格式长这样:2026-09-15T09:00:00+08:00/2026-09-18T18:00:00+08:00。
外贸站展会动态页的四个典型病灶
把朋友那个站和另外几个同类外贸站的展会页拉出来看了一遍,问题高度雷同,我整理成一张表。
| 病灶 | 典型现状 | AI 引擎读到的信息 | 后果 |
|---|---|---|---|
| 日期只在正文里出现 | "On April 15th, we met over 200 buyers...",结构化数据里没有任何日期字段 | 内容时间未知,靠正文反推 | 召回时不敢单独用,容易被当旧闻 |
| dateModified 全站同值 | 模板统一输出站点部署日期或版权年份 | 全站内容"同一天修改",信号失真 | 新鲜度判定直接作废 |
| 没有 temporalCoverage | 展会报道只写 datePublished | 知道何时发布,不知道描述的事件区间 | 无法区分预告/进行中/回顾 |
| 标题党式时间词 | 标题写 "2026 Latest News" 正文却无任何日期锚点 | 时间词与信号矛盾,信任分下降 | 可能被判定为低质内容 |
第 4 行那个"标题党式时间词"值得多说一句。不少外贸站为了蹭搜索流量,标题堆 "latest"、"2026",但页面结构化数据还是老日期。AI 引擎做内容信任评估时,正文与元数据自相矛盾是减分项,这比单纯缺字段伤害更大。做 GEO 这段时间我越来越觉得,AI 引擎对"诚实信号"的偏好比传统搜索引擎明显得多——你写什么它信什么,但写错了下次就不再信你。
动手改造:给展会新闻页补齐时效信号
下面以一个虚构但贴近真实的外贸站展会报道页为例,给出完整的 JSON-LD。页面是 2026 年 9 月 15-18 日法兰克福某行业展的现场报道,活动 16:00 结束,展位负责人化名老陈,站点的 CMS 是自研的 Node.js 后端。
以下代码块里的 // 注释只是为了逐行讲解,JSON 本身不支持注释,部署前要删掉。
{
"@context": "https://schema.org",
"@type": "NewsArticle",
// 类型用 NewsArticle 而不是 Article,展会现场报道属于新闻
"headline": "Frankfurt Industrial Valve Expo 2026: Live Report from Hall 4.1",
// headline 控制在 110 字符内,超出会被截断
"datePublished": "2026-09-15T10:30:00+02:00",
// 展会当地时间是 UTC+2,别写成 +08:00,时区错了会整体偏移 6 小时
"dateModified": "2026-09-17T09:00:00+02:00",
// 17 日补充了第二天的买家洽谈数据,所以更新了 dateModified
"temporalCoverage": "2026-09-15T09:00:00+02:00/2026-09-18T18:00:00+02:00",
// 活动完整起止区间,一道斜杠连接,与活动官方公布的 open hours 一致
"author": {
"@type": "Person",
"name": "Chen Wei",
// 作者页给真实可访问的落地页
"url": "https://example.com/about/chen-wei"
},
// 作者给真实落地页,匿名 author 会拉低 E-E-A-T 评估
"publisher": {
"@type": "Organization",
"name": "NovaValve Industrial",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo-600x60.png"
}
},
"image": ["https://example.com/img/expo2026-hall4-16x9.jpg"],
// image 给 16:9 的横图,尺寸别小于 1200px 宽
"mainEntityOfPage": "https://example.com/news/expo2026-live-report",
// 声明规范 URL,避免多语言版本互相稀释
"inLanguage": "en"
// inLanguage 别漏,多语言外贸站每版页面各写各的语言代码
}
几个字段容易写歪,展开说一下。temporalCoverage 的区间起点用活动开始时间而不是发稿时间,终点用闭馆时间——它描述的是"内容覆盖的时段",不是"页面生命周期"。如果活动跨多个时区(比如线上直播配合线下展位),ISO 8601 允许写成 2026-09-15T09:00:00+02:00/2026-09-18T18:00:00+08:00,两端各带各的时区偏移,别自作聪明统一。
另外,活动如果还没开始,页面是预告性质,temporalCoverage 照样写未来区间,同时把 datePublished 写成预告发布时间。AI 引擎看到"区间在未来"会把它归入预告类内容,这种页面在活动临近时引用价值反而上升,是外贸站蹭展会流量的正确姿势。
dateline 与 printEdition 的取舍
NewsArticle 类型下有一组传统报业字段:dateline(新闻电头,如"FRANKFURT, Germany")、printEdition(印刷版标识)、printColumn、printPage。这些字段是给报纸数字档案用的,外贸站要不要带?我们的取舍见表。
| 字段 | 作用 | 外贸站建议 | 理由 |
|---|---|---|---|
| dateline | 声明报道发稿地点 | 建议用 | 展会报道地点即新闻要素,纯文本如 "FRANKFURT, Sept 15" |
| printEdition | 标识印刷版次 | 不要用 | 外贸站无印刷版,虚标会被当噪声 |
| printColumn / printPage | 印刷版面页码 | 不要用 | 同上,无对应实体 |
| associatedMedia | 报道关联的媒体文件 | 可选 | 有现场视频就用,给 VideoObject |
dateline 用起来没成本,还能给 AI 引擎提供地点信号,配合 temporalCoverage 的时间信号,时间地点两个新闻要素就齐了。printEdition 那几个字段属于"有实体才标",硬凑只会稀释整体结构化数据质量。这个取舍原则可以推广:schema.org 字段不是越多越好,是越准越好。
校验与上线流程
改完不能靠肉眼验收,我们写了个小脚本,把页面 JSON-LD 拉下来做时间字段的静态检查。依赖:Python 3.11、requests、python-dateutil;环境:Ubuntu 22.04,CI 里跑在部署后冒烟阶段。
# 校验展会动态页 JSON-LD 中时效信号的完整性与合法性
# 依赖:Python 3.11、requests、python-dateutil
import json
import re
import sys
from datetime import datetime
# requests 负责拉线上页面,dateutil 负责解析带时区的 ISO 时间
import requests
from dateutil import parser as dt_parser
# 允许的结构化类型,展会页只认 NewsArticle 或 Article
ALLOWED_TYPES = {"NewsArticle", "Article"}
# 带时区的时间字段必须匹配 ISO 8601 完整格式
ISO_RE = re.compile(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}$")
def fetch_jsonld(url):
# 拉取页面并提取第一个 application/ld+json 脚本块
resp = requests.get(url, timeout=10)
resp.raise_for_status()
# 用正则从 HTML 里抠出 ld+json 内容,简单场景够用
m = re.search(
r'<script[^>]*type="application/ld\+json"[^>]*>(.*?)</script>',
resp.text, re.S)
if not m:
sys.exit(f"[FAIL] {url} 页面没有 JSON-LD")
# 注释行在部署版里不应存在,这里兜底剥掉一遍
lines = [l for l in m.group(1).splitlines() if not l.strip().startswith("//")]
# 拼回去之后正常反序列化,解析失败会直接抛异常
return json.loads("\n".join(lines))
def check_temporal(data, url):
# 汇总校验结果,任何一项不过都算失败
errors = []
t = data.get("@type")
# 类型必须是允许集合里的字符串
if t not in ALLOWED_TYPES:
errors.append(f"@type={t} 不在允许范围")
for field in ("datePublished", "dateModified"):
val = data.get(field)
# 字段缺失直接记错误
if not val:
errors.append(f"缺少 {field}")
elif not ISO_RE.match(val):
# 时区必须显式声明,裸日期不给过
errors.append(f"{field}={val} 缺少时区或格式不合法")
# temporalCoverage 允许缺省,但展会页不允许,后面单独判
tc = data.get("temporalCoverage", "")
# temporalCoverage 是斜杠连接的区间,检查两端可解析
if "/" in tc:
start, end = tc.split("/")
# isoparse 能处理带时区偏移的时间串
s = dt_parser.isoparse(start)
e = dt_parser.isoparse(end)
# 起点晚于终点属于明显错误
if s >= e:
errors.append("temporalCoverage 起点不早于终点")
elif tc:
errors.append("temporalCoverage 不是区间格式(应含 /)")
else:
# 展会页没有时间区间视为高危缺失
errors.append("缺少 temporalCoverage,展会页必须标注")
return errors
if __name__ == "__main__":
# 用法:python check_temporal.py https://example.com/news/xxx
data = fetch_jsonld(sys.argv[1])
# 拉下来的 JSON-LD 直接进时间字段校验
problems = check_temporal(data, sys.argv[1])
if problems:
# 逐条打印问题清单,CI 里据此退出非零
for p in problems:
print(f"[FAIL] {p}")
# 退出码非零让流水线直接红灯
sys.exit(1)
print("[OK] 时效信号校验通过")
这个脚本接进了部署流水线,展会新闻发布后 10 分钟内自动跑一遍,有问题直接在企业微信里 @ 值班编辑。别小看这一步,结构化数据这种东西,人肉看一眼就上线,早晚出事故。
改造前后 45 天对照
朋友那个站的展会动态栏目,8 月 11 日上线了这整套时效信号(12 篇存量报道批量补标,新报道走模板自动输出)。以下是栏目级别的实测对照,口径:8 月 11 日往前 45 天 vs 往后 45 天,数据来自站点日志和各家站长平台的抓取统计。
| 指标 | 改造前 45 天 | 改造后 45 天 | 变化 |
|---|---|---|---|
| AI 引擎日均抓取频次 | 2.3 次 | 9.1 次 | 约为原来的 4 倍 |
| AI 搜索引用次数(Perplexity + AI Overview) | 0 | 17 | 从 0 到 17 |
| 页面平均抓取延迟 | 9.6 天 | 2.8 天 | 收缩到三分之一以内 |
| 存量报道被重新抓取比例 | 8% | 83% | 死页复活 |
gantt
title 改造后 45 天的抓取与引用节奏(实测示意)
dateFormat YYYY-MM-DD
axisFormat %m-%d
section 抓取侧
上线后爬虫重访高峰 :crit, 2026-08-11, 7d
抓取频次稳定在日均9次 :2026-08-18, 38d
section 引用侧
Perplexity 首次引用 :milestone, 2026-08-24, 0d
展前预告页集中被引用 :2026-09-01, 12d
AI Overview 引用展后报告 :2026-09-20, 10d
两个细节比总数更有意思。一个是引用的构成:17 次引用里 11 次给了带 future temporalCoverage 的预告类页面,集中在 9 月初新一届展会临近时——机器很清楚"还没发生的事此刻最有引用价值"。另一个是 8 月 11 日上线当天到 17 日那一周抓取明显放量,说明引擎对 dateModified 的批量变化有感知,会主动重访。老陈的原话是:"内容一个字没加多,就改了机器看得懂的时间戳,这买卖太划算了。"当然要泼盆冷水:这只是单站点 45 天的观察,样本量小,别当成普适规律拿去承诺客户什么,每次 AI 引擎改版数据都可能漂。
排错记录:上线后踩的三个坑
上线过程不是一帆风顺,记三个真实踩坑,给后面做的同学省点时间。
坑一,时区写错导致区间"穿越"。法兰克福展那篇初稿里 temporalCoverage 两端都用了 +08:00,活动 18 日 18:00 闭馆被标成了北京时间 19 日凌晨,区间终点比 dateModified 还晚出戏。校验脚本后来加了"区间终点不得晚于当前时间 30 天(预告页除外)"的规则才拦住这类问题。
坑二,多语言站点的 mainEntityOfPage 指向了默认英文版,德语版页面被抓后,引擎发现规范 URL 是英文页,干脆只索引英文版。多语言外贸站的每一版页面要各自声明指向自己的 URL,这一条在 hreflang 之外常被漏掉。
坑三,存量报道批量补标时,编辑把"内容覆盖时段"理解成了"发布时段",12 篇里 5 篇的 temporalCoverage 只标了发稿当天。这种错误用户看不出来,只有脚本和引擎能发现,所以静态校验比人工 review 可靠。
误区澄清与趋势
最后澄清一个流传很广的说法:有人说 AI 搜索引擎根本不看结构化数据,只看正文。从我们这次的对照看,这个判断站不住——正文一个字没改,光补时间字段就有 4 倍抓取频次变化,显式信号显然在起作用。但也别走向另一个极端,把 temporalCoverage 当万能药:它只解决"时效可读",内容本身没有独家现场信息(买家数据、展位实拍、报价趋势),引用照样上不来。信号负责让机器发现你,内容负责让机器敢引用你。
趋势上有个值得提前布局的点:schema.org 社区已经在讨论给 temporalCoverage 补充更细的表达能力(比如带重复规则的活动周期),AI 引擎对"内容生命周期"的建模只会越来越细。现在把时效信号体系搭好、校验流程固化到 CI,等下一波引擎更新,你站里的存量展会报道就是别人眼里的富矿。你在展会页时效信号上踩过什么坑,或者拿到过什么引用数据,评论区聊聊。
参考与延伸
- schema.org temporalCoverage 属性定义:https://schema.org/temporalCoverage
- schema.org NewsArticle 类型定义:https://schema.org/NewsArticle
- Google 搜索中心 Article 结构化数据文档:https://developers.google.com/search/docs/appearance/structured-data/article
- MDN ISO 8601 日期与时间格式说明:https://developer.mozilla.org/en-US/docs/Web/HTML/Date_and_time_formats
关键词:GEO、temporalCoverage、dateModified、NewsArticle、ISO 8601、外贸站AI流量、结构化数据