schema.orgに準拠してクローラと会話しよう - QiitaのSEO事情（後編）

[前編](http://qiita.com/yuku_t/items/726a67d8ae74eea2540a)ではHTML5のアウトラインを綺麗にする、というお話でした。アウトラインを綺麗にすれば、検索エンジンにコンテンツの階層構造がどうなっているのか、正しく教えることができます。

けどそれだけでは1つ1つのまとまりが一体何を表しているのかが不明です。

schema.orgに準拠することで、そこに何が書かれているのか、を検索エンジンに教えることができます。

# schema.orgとは

[schema.org](http://schema.org) はGoogle, Microsoft, Yahoo!などの検索エンジンベンダーが集まってマークアップ方式を標準化している組織とその標準化された仕様を文書化しているサイトです。

例えば「ここは著者のことを書いています」「これは著者の名前です」「この記事が公開されたのはこの日時です」などなど、HTMLの機能だけでは伝えきれない詳細な情報をクローラに伝えるための手段が色々定義されています。

ちなみにschema.orgで定義されている語彙は全てmicrodataという方式が使われています。microdataという書き方に、Googleなどがルールを与えたものがschema.orgなわけです。

## なぜQiitaはschema.orgに準拠したか

やるからには効果が無きゃ困る訳ですが、Googleが提供しているツールを観察してみる限り、少なくともGoogleはschema.orgに準拠したマークアップを理解していることが分かります。

前回の[QiitaのSEO事情 - HTMLのアウトライン意識してますか？](http://qiita.com/yuku_t/items/726a67d8ae74eea2540a)でも言及したように、正しく検索エンジンに解釈されることがまわりまわって検索順位の向上に寄与すると考えているため、schema.orgに準拠することにしました。

また、検索順位というのは相対評価で決まるものです。他のサイトがやっていないことをすることに価値があるんじゃないか、と考えたというのもあります。

# マークアップする

では実際にschema.orgに準拠したマークアップを行なってましょう。

## itemscopeとitemtype

例えばQiitaの記事には著者情報を表した箇所があります。ここには著者名と自己紹介が書かれています。

```html
<section>
  <h1>著者情報</h1>
  <span>yuku_t</span>
  <p>自己紹介</p>
</section>
```

ここが著者に関することを書いていると明示するために、まず `itemscope` 属性をその情報を囲っている要素に加えます。

```html
<section itemscope>
  <h1>著者情報</h1>
  <span>yuku_t</span>
  <p>自己紹介</p>
</section>
```

`itemscope` を加えることで `<section>…</section>` が何かしらの項目についてのものであることが表明されます。

これでは何に関する情報化が分かりません。これが何について表しているのか `itemtype` 属性を `itemscope` 属性の直後に置くことで表明できます。

```html
<section itemscope itemtype="http://schema.org/Person">
  <h1>著者情報</h1>
  <span>yuku_t</span>
  <p>自己紹介</p>
</section>
```

これでこれがschema.orgで定義されている `Person` について記述している箇所だということが表現できました。タイプはURLを使って指定します。今回の場合だと `http://schema.org/Person` です。

## itemprop

`Person` には名前や詳細などのプロパティを持ちます。これを指定するには `itemprop="name"` を名前をマークアップしている要素に加えます。（指定できるプロパティは `itemtype` で指定したURLで知ることができます。今回の場合なら http://schema.org/Person です。）

```html
<section itemscope itemtype="http://schema.org/Person">
  <h1>著者情報</h1>
  <span itemprop="name">yuku_t</span>
  <p itemprop="description">自己紹介</p>
</section>
```

## 入れ子にする

プロパティの中にはそれ自体が一つの項目になれるものがあります。

QiitaではユーザはOrganizationに所属することができます。ある要素が他の項目を表すことを表明するには `itemscope` を `itemprop` の直後に置きます。

```html
<section itemscope itemtype="http://schema.org/Person">
  <h1>著者情報</h1>
  <span itemprop="name">yuku_t</span>
  <p itemprop="description">自己紹介</p>
  <div itemprop="memberOf" itemscope itemtype="http://schema.org/Organization">
    <span itemprop="name">Increments.inc</span>
  </div>
</section>
```

ここでは `Person` の `memberOf` プロパティに `Organization` が指定されています。これでyuku_tという `name` の `Person` がIncrements.incという `name` の `Organization` の `memberOf` である、という情報を表すとができました。

`memberOf` に `Organization` を指定できることは http://schema.org/Person の `memberOf` のExpected Typeで知ることができます。

# itemtypeの種類

- [Full Hierarchy - schema.org](http://schema.org/docs/full.html)

`itemtype` に指定できるタイプはクラス継承のように、階層構造になっています。一番上が `Thing` です。

先ほど `memberOf` には `Organization` を指定できると言いましたが、 `Organization` を継承したタイプ、例えば `Corporation` や `Hospital` など、も指定することが可能です。

実に様々なタイプが定義されているので、必要に応じて選択しましょう。

# プロパティが画面に現れない場合

デザインの関係上、必ずしもプロパティが画面に現れるとは限りません。例えばユーザアイコンは表示するけど、名前は表示しないような場合です。こういう場合は `meta` か `link` 要素を使います。値がURLなら `link` 単なる文字列なら `meta` になります。

```html+erb
<link itemprop="url" href="/yuku_t" />
<meta itemprop="name" content="yuku_t" />
```

# マークアップ時に意識すること

schema.orgの「[Get started with schema.org](http://schema.org/docs/gs.html)」というドキュメントに、[schema.orgに準拠してマークアップするときに注意すること](http://schema.org/docs/gs.html#schemaorg_expected)が書かれているので、軽く紹介します。

## hiddenな文書をマークアップしない

一般的に適切にマークアップしているなら、多いければ多いほどよいと言えますが、それは見える要素のみです。言明はされていませんが、schema.orgはhiddenな文書にマークアップするとペナルティが課されると暗にほのめかしています。

## Expected Typeの代わりにテキストでも問題ない

`memberOf` のExpected Typeは `Organization` ですが、これは別に必須というわけではありません。 `itemscope` にせず、単なるテキストやURLでも問題ありません。

## urlプロパティを使う

他のページへのリンクがあって、そのリンク先が1つの項目を表しているなら、そのリンクには `itemprop="url"` をつけましょう。勿論そのリンク自体が `itemscope` に包含されていなければなりません。

# マークアップを確認してみる

schema.orgに対応したマークアップをしてみたら、Googleが専用のツールを提供してくれているので、それが正しく書けているのか確かめましょう。

- [Google Structured Data Testing Tool](http://www.google.com/webmasters/tools/richsnippets)

確認したいページのURLを指定するか、HTMLを貼り付けてるか、の２通りの検査方法があります。

- サンプル：[このページの解析結果](http://www.google.com/webmasters/tools/richsnippets?q=http%3A%2F%2Fqiita.com%2Fyuku_t%2Fitems%2F3740cc9a5f8503693bd2)

上記のリンク先をみると、検索スニペットのサンプルに続いて、Personがどうたらこうたら、Articleがどうたらこうたらと出てくると思います。このような記述が意図した通りに出現していればOKです。

ちなみに、開発時はHTMLを貼り付けて確認することになると思いますが、なぜかHTML貼り付けだと後述するパンくずが検索スニペットのサンプルで適切に反映されないです。訝しみつつそのままデプロイしてみたらパンくずとして認識するようになったので、パンくずを設定するときは注意してください。（単なる勘違いの可能性もあります）

# おまけ：存在しないパンくずを認識させる

Qiitaの投稿ページがGoogle検索にひっかかるとこんな感じになってますよね。

![Screen_Shot_2013-07-17_at_12.28.24_AM.png](https://qiita-image-store.s3.amazonaws.com/0/153/f24662f3-0f6a-731c-139a-b97444fcec8d.png)

SEOに効果があるのか分かりませんが、検索結果にパンくずを表示させることができます。パンくずとは何か、というのは適当にググってください。あと、これを表示する方法は公式ドキュメント（[リッチ スニペット - パンくずリスト - ウェブマスター ツール ヘルプ](https://support.google.com/webmasters/answer/185417?hl=ja)）を参照してください。

QiitaはURL構造が階層構造になっているので、ページにはパンくずが表示されていませんが、検索結果にはそれを反映させるようにしています。同様にデザインにはパンくずがないけど検索結果には表示させたい、という場合は、前述の「プロパティが画面に現れない場合」と組み合わせて次のように書きます。

```html:
<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
  <link itemprop="url" href="/yuku_t" />
  <meta itemprop="title" content="yuku_t" />
</span>
<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
  <link itemprop="url" href="/yuku_t/items" />
  <meta itemprop="title" content="items" />
</span>
```

ここで使っているのがschema.orgではなくdata-vocabulary.orgであることに注意が必要です。

data-vocabulary.orgはschema.orgの前身となった（？）サイトで、現在ではそのほとんどがschema.orgに引き継がれていますが、少なくともこの `Breadcrumb` typeに関しては、Googleの公式ドキュメントでもそうしているように、data-vocabulary.orgで定義されているものを使わなければなりません。

# まとめ

- 結構面倒なので、検索流入が重要なページだけやれば十分だし、余裕が無いならやらなくてもいい。
- でもやったら何かいいことがありそうな予感する。とりあえず無駄にはならないはず。

# QiitaのSEO事情

1. [HTMLのアウトライン意識してますか？](http://qiita.com/yuku_t/items/726a67d8ae74eea2540a)
2. schema.orgに準拠してクローラと会話しよう