本文约 6,089 字,预计阅读 16 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:视频,bought发了半年,Google 一条都没索引
做产品测评、软件教程、设备拆机的站点,视频是转化率最高的内容资产,但也是最容易被 Google 无视的资产。典型症状是:页面已经被正常收录,视频播放量也不错,可 Google 视频搜索里一条都搜不到,Search Console 的”视频”报表也始终为空。原因通常不在视频本身,而在两件 Google 明确要求但站长常忽略的事:一是视频所在页面必须以视频为主要内容(Google 称之为 video page,会做 prominence 判断,正文只有两三段的”陪衬页”不会被认定为视频页);二是需要用 VideoObject 结构化数据或视频 sitemap 明确告诉 Google”这里有个视频、封面在哪、什么时候上传、多长”。只做了自动播放的 embed iframe,等于什么都没说。
原理分析:两条告知通道,各解决一半问题
Google 给了两条通道。第一条是页面内的 VideoObject JSON-LD:爬虫抓到页面时就知道这里有视频,字段包括 name、description、thumbnailUrl、uploadDate(带时区的 ISO 8601),推荐补 duration、contentUrl、embedUrl、interactionStatistic、expires。其中 thumbnailUrl 必须是 Googlebot 可直接抓取的图片地址,uploadDate 必须包含时区偏移,这两项是最常见的报错来源。
第二条是视频站点地图(Video sitemap)或其替代形式 mRSS 订阅:在 sitemap XML 里用 <video:video> 扩展声明 <video:thumbnail_loc>、<video:title>、<video:description>、<video:content_loc>、<video:player_loc>。它的价值在于主动 pushing 告诉我们”这些 URL 里有视频”,能显著加快发现速度,尤其是新站或深层级页面。
| 字段 | 是否必填 | 典型错误 |
|---|---|---|
| name | 必填 | 直接用页面标题,与视频内容不符 |
| description | 必填 | 空或与name 重复 |
| thumbnailUrl | 必填 | 被防盗链/CDN 拦截,Googlebot 抓不到 |
| uploadDate | 必填 | 缺时区,如写成 2025-03-01 |
| duration | 推荐 | 单位写成秒而非 ISO 8601(PT3M25S) |
| contentUrl / embedUrl | 推荐其一 | 给了需要登录才能播放的地址 |
值得注意的是:contentUrl 或 embedUrl 至少要有一个指向真正可播放的视频资源,embedUrl 指向播放器 URL,两者都不应该需要登录、付费或 App 才能观看。
保姆级实操
第一步:判断页面是否够格做视频页
把一个视频放在页面顶部显眼位置,正文围绕视频展开(可配转写文字、时间轴、补充说明),而不是把视频塞在 800 字文章的第 6 屏。加入视频转写文字既利于无障碍,也让页面图文信息足够,被判定为视频页的概率大幅提升。
第二步:写 VideoObject JSON-LD
注意 uploadDate 的时区和 duration 的 ISO 8601 时长格式:
{
"@context": "https://schema.org",
"@type": "VideoObject",
"name": "Redis 对象缓存启用全流程演示",
"description": "演示在 WordPress 服务器上安装 Redis、启用对象缓存插件并验证命中的完整过程。",
"thumbnailUrl": [
"https://mimangfei.com/wp-content/uploads/redis-thumb-1280x720.jpg"
],
"uploadDate": "2025-03-18T09:20:00+08:00",
"duration": "PT3M25S",
"contentUrl": "https://cdn.mimangfei.com/videos/redis-object-cache.mp4",
"embedUrl": "https://mimangfei.com/video/redis-object-cache/#player",
"interactionStatistic": [
{
"@type": "InteractionCounter",
"interactionType": { "@type": "WatchAction" },
"userInteractionCount": 12840
}
]
}
第三步:在 WordPress 里用文章自带的视频字段生成
用自定义字段保存视频地址、封面、时长,避免每篇手工编辑 JSON。
add_action( 'wp_head', function () {
if ( ! is_singular( 'video' ) ) {
return;
}
$id = get_the_ID();
$file = get_post_meta( $id, '_video_file', true );
$poster = get_post_meta( $id, '_video_poster', true );
if ( ! $file || ! $poster ) {
return;
}
$iso_date = get_the_date( 'c', $id );
$sec = (int) get_post_meta( $id, '_video_seconds', true );
$hours = intdiv( $sec, 3600 );
$minutes = intdiv( $sec % 3600, 60 );
$seconds = $sec % 60;
$duration = sprintf( 'PT%dH%dM%dS', $hours, $minutes, $seconds );
$node = [
'@context' => 'https://schema.org',
'@type' => 'VideoObject',
'name' => get_the_title( $id ),
'description' => wp_strip_all_tags( get_the_excerpt( $id ) ),
'thumbnailUrl' => [ $poster ],
'uploadDate' => $iso_date,
'duration' => $duration,
'contentUrl' => $file,
];
echo '<script type="application/ld+json">' . wp_json_encode( $node, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) . '</script>';
}, 20 );
第四步:补一份视频 sitemap
用 WordPress 自己的 sitemap 无法输出 video 命名空间,需要单独生成。可以用 wp_sitemaps 相关过滤器扩展,也可以由 Cron 生成静态文件。下面是一份可照抄的 XML 结构:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<url>
<loc>https://mimangfei.com/video/redis-object-cache/</loc>
<video:video>
<video:thumbnail_loc>https://mimangfei.com/wp-content/uploads/redis-thumb-1280x720.jpg</video:thumbnail_loc>
<video:title>Redis 对象缓存启用全流程演示</video:title>
<video:description>演示安装 Redis、启用对象缓存插件并验证命中。</video:description>
<video:content_loc>https://cdn.mimangfei.com/videos/redis-object-cache.mp4</video:content_loc>
<video:player_loc>https://mimangfei.com/video/redis-object-cache/#player</video:player_loc>
<video:duration>205</video:duration>
<video:publication_date>2025-03-18T09:20:00+08:00</video:publication_date>
</video:video>
</url>
</urlset>
第五步:把 sitemap 提交到 Search Console
在后台的”站点地图”区域提交该文件路径,而不是只靠 robots.txt 声明。随后在”视频”报表中查看 indexed videos(已编入索引的视频)数量变化。
第六步:确认封面图可被 Googlebot 抓取
curl -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
-o /dev/null -s -w "http=%{http_code} type=%{content_type} size=%{size_download}\n" \
"https://mimangfei.com/wp-content/uploads/redis-thumb-1280x720.jpg"
返回非 200 或非 image/* 就说明防盗链或 CDN 策略拦住了 Googlebot。
常见踩坑
uploadDate没带时区:写成2025-03-18会被判字段无效,必须形如2025-03-18T09:20:00+08:00。duration写成 205 秒:ISO 8601 时长是PT3M25S,纯数字会被忽略。- 封面图用 WebP 而 CDN 按 UA 拒绝:用上面的 curl 命令验证一次最保险。
- 视频在懒加载容器里但内容不在 DOM:视频地址只存在于 JS 变量中,爬虫看不见。
contentUrl指向需要登录的后台:必须是公开可直接下载的地址。- 案例:某设备测评站把视频托管在某国内视频平台的外链播放器里,页面只嵌入 iframe,
VideoObject的contentUrl填了该平台的播放页。半年后 GSC 视频报表仍然为零,排查时发现该平台对 Googlebot 返回了地区限制页。整改方案是把视频源文件自己托管到对象存储 CDN,并在页面上用原生<video>渲染 + 提供转写文字,提交视频 sitemap 后 3 周内全部视频被编入索引。托管位置是视频收录的地基。 - 同一份 VideoObject 同时给了语焉不详的 duration 与 expires:矛盾字段会让解析器直接放弃整块节点。
总结
判断标准:一个合格的视频页,视频必须在页面最显眼处当主角,VideoObject 四件套(name、description、thumbnailUrl、uploadDate)必须齐全准确,且资源地址对 Googlebot 开放。行动清单:把视频提到首屏并配转写 → 用文章字段自动生成 VideoObject → 时长转 ISO 8601、时间带时区 → 生成带 video 命名空间的 sitemap 并在 GSC 提交 → 用 Googlebot UA 验证封面可抓 → 在视频报表里观察 2–4 周。视频播放本身会带来大量渲染开销,落地页体验可参照Core Web Vitals 三指标(LCP/INP/CLS)详解一并优化。
