搜索全站
Google SEO 16 分钟阅读

VideoObject 结构化数据提交:让 Google 收录你的视频页

视频上传半年 Google 一条都没收录?本文讲清 VideoObject 的必填推荐字段、视频 sitemap(含 video 命名空间)的实际写法、缩略图与 duration 的常见坑,以及 GSC 视频报表的定位方式。

U
UFO_PF 2020-03-04 · 阅读 16 分钟
Vi GOOGLE SEO
阅读提示
本文约 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。

常见踩坑

  1. uploadDate 没带时区:写成 2025-03-18 会被判字段无效,必须形如 2025-03-18T09:20:00+08:00。
  2. duration 写成 205 秒:ISO 8601 时长是 PT3M25S,纯数字会被忽略。
  3. 封面图用 WebP 而 CDN 按 UA 拒绝:用上面的 curl 命令验证一次最保险。
  4. 视频在懒加载容器里但内容不在 DOM:视频地址只存在于 JS 变量中,爬虫看不见。
  5. contentUrl 指向需要登录的后台:必须是公开可直接下载的地址。
  6. 案例:某设备测评站把视频托管在某国内视频平台的外链播放器里,页面只嵌入 iframe,VideoObject 的 contentUrl 填了该平台的播放页。半年后 GSC 视频报表仍然为零,排查时发现该平台对 Googlebot 返回了地区限制页。整改方案是把视频源文件自己托管到对象存储 CDN,并在页面上用原生 <video> 渲染 + 提供转写文字,提交视频 sitemap 后 3 周内全部视频被编入索引。托管位置是视频收录的地基。
  7. 同一份 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)详解一并优化。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。