Search Consoleの構造化データのエラーを減らすべくmicrodataの書き方を試行錯誤中です (hAtom編)

Googleのウェブマスターツール改めSearch Consoleの構造化データでのエラーを気にしているブロガーの方も多いでしょう。

私も勉強がてら対策をしてみました。


Search Consoleの構造化データに大量のエラーがあることが気になっている方も多いでしょう。"Updated"やら"Author"やら。何かエラーを出しています。

検索すると多くの対策ページを見る事ができます。ですが、なかなかエラーを消すことができません。そもそも何を書き換えるとどうなるのかが判りませんでした。
我流ながら一通りの対策を行いましたので忘れないように書き留めておきます。

結論を先に書いておきますがBloggerでこのエラーを完全になくすことはできないようです。

Microdataっていうんだ

そもそも構造化データって何でしょうか?
詳しい事はより専門的な説明をしているサイト様にお任せです。検索してください。放り投げ。

簡単には、
GoogleやBingなどのインターネットの情報を自動で収集するbotに対して専用の情報を伝える仕組みです。ブログやホームページの情報は人が読んで理解できる文章でかかれています。これをプログラムで正確に解釈するのはGoogleのエンジニアでも困難なのです。

例えば会社のホームページで住所を書いておいたとします。人が見れば本社の住所だな、営業所の住所だなと判るでしょう。あるいは文字をカッコよくデザインしたいのでテキストではなく画像で会社名のロゴを置いているだけで文字で書いていなかったりしていませんか?住所が複数書いてあるとどどれが何の住所か判断できないので拾ってくれなかったり、botは画像の意味を理解できないので会社名を拾わなかったりしてしまいます。

検索サイトのbotが正しく自分のページを解釈してくれないと読んでほしい人に自分のページの存在を伝える事ができません。検索結果に表示されないことに直結します。

そこでbot専用の書式を決めてbotへ何が書かれているサイトか正確に伝える取り決めが作られました。構造化したデータの取り決めに従って自分のブログやホームページにデータを埋め込んでおくと検索botがより正しい情報を拾ってくれるようになります。

構造化データを埋め込む方法は何種類かあるようです。簡単なのはhtmlの要素へ決められた書式でbot用情報を追加する方法です。すでにあるブログやホームページのテンプレートに書式を追加することでどこに何が書いてあるかbotに教えることができます。その他に情報を一塊として置いておく方法もあるようです。

ここで前者のhtmlの要素で情報を追加する方法を総じて"Microdata"というそうです。既存のhtmlに要素を追加するだけでデータを埋め込めるのでお手軽です。しかし、htmlに無理やりデータを追加するためコードが汚くなるという欠点があります。せっかくhtmlとcssが分離されたのにhtmlがまた着膨れします。
当然分離しようというので後者の方法が出てきました。JSON-LD(JSON for Linking Data)というやつです。

埋め込む方法に関係なく、埋め込むデータの構造が別に決められています。こちらも何種類かあります。この記事を見に来たという事はSearch ConsoleのStructured Data Testing Tool を見ていることでしょう。そこに"hatom"とか"BlogPosting"とか書いてあるでしょう。それがデータ構造の名前ですね。

BloggerではテンプレートにMicrodataが最初から入っています。しかし、テンプレートは古い規格のままで最近の規格に合っていないためエラーが表示されてしまうようです。
hAtom に詳細が書いてあります。Bloggerのテンプレートをいじるとclassに"hentry"とか書いてあり、何の意味だろう?と思っていましたがこれだったんですね。

hAtomとは別に'BlogPosting'(Schema.org)も混じっていたりするのでしょうか?テンプレートをいじりすぎて最初から入っていたのか気づかず追加してしまったのかわからなくなっています。

'BlogPosting'という名前の通りこれはブログ向けの構造化データを使うと(自分で)宣言しています。他に会社の情報を入れる構造やイベントの日時や場所を入れるフォーマットなど伝えたい情報にあったフォーマットを自分で宣言してデータを埋め込みます。Schema.orgを一通り眺めるとどんなデータを想定しているかが判ると思います。

どうやってデータを埋め込むのか?

microdataが何をするものかわかってきたところでエラーを直していきたいです。Search Consoleの構造化データのエラーがなぜ起きているのか理解しないとエラーを直せません。
そもそも、何もしなくてもデフォルトのテンプレートには一部のデータが入っています。どこに入っていて、足りないものはどうすれば追加できるのでしょうか?

ついでにJSON-LDに対応したいところです。ですがBloggerの構造上JSON-LDにするのは難しそうです。表示するページ全体の情報を一か所で読み出す方法がBloggerには無いからです。投稿記事の情報などを読み出したくともwidget毎に読み出せる情報が限られているのです。JSON-LDを分割して置いておけばどうにかなるでしょうか。

それならjavascriptなどで書き出せばいいじゃないか、と思いますよね。後でもう一度書きますが、javascriptなど動的にJSON-LDを生成してもbotはそれを読んでくれません。botは基本的にscriptを実行しないからです。

Serch Consoleの構造化データのエラーはhAtomに関するものだけ表示しているのかな?

エラーを無くしたいというだけならhAtomに関する情報だけ対処すれば良いようです。Search Consoleの構造化データでは"エラーが発生したアイテム"が表示されるのはhAtomだけのようです。BlogPostingには"-"が表示されています。詳細を見るとAuthorやUpdatedがありませんと出ている場合が多いでしょう。

しかし、Structured Data Testing Tool ではhAtomのエラーが表示されず"問題ありません"と表示されます。そしてBlogPostingにエラーがあると表示されます。
今のところ構造化データのエラーを無くしたいという目的ならhAtomにだけ対応すればよいようです。

しかし、構造化データの目的からすればそんな一時的な対応は意味が無いと判るでしょう。今後を考えてできる限りまじめにデータを埋め込むことを考えなくてはなりません。
Search Consoleもそのうちエラー表示の基準を変えてくるでしょう。

私はまだ正確に理解できていませんが、今後を考えるとhAtomを除去してBlogPostingだけ埋め込む方がよさそうな気がします。

まずは勉強がてら構造化データがどこに書かれているかを理解するためエラーに対処してみます。

hAtomのmicrodataを追加する

hAtomの構造化データはBloggerのテンプレートであらかじめ埋め込まれています。Bloggerもメンテナンスがあまり頻繁に行われていないようなのでこのテンプレートも少し古くなっているようです。hAtomの仕様変更に対応できなくなっているようです。hAtomはmicroformatsという規格で定義される一つのフォーマットです。今ではmicroformats2というフォーマットがありそちらの方が今どきの構造化データを扱えます。

それは置いておいて、hAtomのエラーに対処していきます。
エラーへの対処の具体的方法は他のサイト様がたくさんありますので、そちらにお任せです。
ここでは、構造化データの構造がhtmlのどこにあるのかを中心に書いてみます。

class属性の階層構造をそのまま構造化データとして使う

hAtomの構造化データはhtmlの要素のClass属性のDOMを使って表現しています。

まずはBloggerのテンプレートをhtml編集で開きます。
次の行を探します。
<div class='blog-posts hfeed'>

投稿記事を表示する部分です。
hfeedというクラス名がhAtomの一番上位の構造です。

<b:includable id='post' var='post'>

個々の記事を表示する部分です。この行の直後に次のような文があります。

<div class='post hentry' itemprop='blogPost' itemscope='itemscope' itemtype='https://schema.org/BlogPosting'>

今回はclass属性だけ見てください。他の属性はBlogPostingのものですから別途説明します。
class属性に"post"があるのは意味が分かりますね。普通にDOM構造の宣言でここから投稿記事があるという事です。microdataとは関係がありません。
このDOM構造をそのままmicrodataとして間借りするのがhAtomのようです。
class属性に"hfeed"あるいは"hentry"があります。これがhAtomの構造の宣言みたいなものです。以後、このDOM構造の階層に従ってhAtomのデータを埋め込んでいきます。

DOMなので入れ子構造になります。という事は"hfeed"クラスが使われているdiv要素の範囲内にhAtomのデータが入っていないとなりません。
今回のBloggerの例では投稿記事を表示するdiv要素に書かれているため、サイドバーやナビゲーションバーなどにhAtomの属性を書いても入れ後構造の外なので解釈されることは無いのです。

また、class属性にhAtom用のクラス名を追加するだけなので、div要素にだけデータを埋め込めるというわけではありません。class属性を書けばspanだろうがmetaだろうがimgだろうが好きな要素に追加できます。

クラス名で構造化データの場所を指定しているので、hAtomのクラス名を偶然別に使っていたとしたらクラス名を整理してhAtomのクラス名と被らないようにしましょう。

hAtomのAuthorを追加する

hAtomの構造化データをどうやって書けば良いかイメージできてきたでしょうか?
まずはAuthorを例にしてデータを埋め込んでみましょう。

Authorは著者情報を表します。あなたのブログ記事の投稿者を指定できれば良いのです。
クラス名は"Author"を使います。つまり、hentryクラスの範囲内にAuthorクラスを使って著者名をくくっておけば良いのです。
構造としては次のようになれば良いのです。

<div class='hfeed'>
 <div class='hentry'>
  <div ....  >
   ...
   <span class='author'> Blog's Author Name here </span>
   ...
  </div>
 </div>
</div>


Bloggerの場合は次の文が書かれている場所があるはずです。複数箇所あるはずですが、hentryクラス内にあるものだけ探しましょう。

<data:post.author/>

著者名を埋め込むコードです。ブログが表示される時にこの文は著者名に展開されます。この文をauthorクラス内に入れればいいのです。次のようにです。

<span class='author'><data:post.author/></span>

ここで注意する事があります。authorクラスで囲む範囲は著者名だけが書かれている部分を囲む必要があります。botはauthorクラスで囲われた範囲すべてを著者名だと解釈するでしょう。余計な文をauthorクラス内に入れないようにしましょう。

hAtomのpublishedを追加する

次にpublishedを例にしてみます。これは記事の発行日時を表します。
authorと同様にhtmlの編集画面で次の文がある場所を探してみましょう

<data:post.timestamp/>

これは記事が公開された日時に展開されます。これを"published"クラスで囲ってやれば良いのです。

ただし、Bloggerの場合はこの指定が意味をなさないと思います。data:post.timestampは投稿日時を返す関数ですが、その書式に問題があります。人が読める書式なのですがbotは理解できないのです。どうしてでしょうか?

Bloggerで投稿日時を表示するとき次のようにブラウザで表示されているでしょう。

"2016年4月1日金曜日" とか "10:03" と時刻だけかもしれません。
botはどちらも日時として認識しません。publishedが指定されて何か書かれている事は判ってくれますが日時を解釈しません。

botが理解してくれる日付の形式は決められています。ISO 8601(wiki)を見てみましょう。
インターネットは世界中で使われているのです。という事は時差があります。日時が書いてあってもどこに時刻だろう? となってしまいます。正確に表すには協定世界時 UTC(wiki)を使わななくてはなりません。

BloggerにはISO8601の投稿日時を返してくれる関数があります。

<data:post.timestampISO8601/>

とすればbotが理解してくれる時刻に展開してくれます。

しかし、今度は人が見て理解できなくなります。

2016-04-01T00:01:03+09:00

え! 何時?

BlogPostingでは人が読む文とbotが解釈するデータを分離できます。hAtomでもできるのかな?
少しちゃんと仕様を読んでいきます。あっ、何かできそうですね。Value Class Patternに書いてありそう。

img,area要素は alt属性、
data要素は value属性、
abbr要素は title属性、
del,ins,time要素は datetime属性
に書いておけば良いようです。その他の要素はインナーテキストと書いてあるので人が読むテキスト部分と同じになります。

html5的にはtime要素を使うのがよさそうです。
という事でpublishedのデータを埋め込むには次のように書いておけば良いようです。

<time class='published' expr:datetime='data:post.timestampISO8601'/>

hAtomのupdatedを追加する

結論からいうと追加しませんでした。

ちまたで紹介されているのはpublishedと同じ場所にupdatedクラスを追加する方法です。
Bloggerには更新日時を得る方法がありません。そのため、更新日時を投稿日時と同じにして更新日時が存在するとbotに思わせるのです。これでSearch Consoleのエラー表示は消えます。ですがmicrodataとしては意味を成しません。エラーを消すという目的なら達成できますが意味のある修正とは言えません。

Bloggerはテンプレートから簡単に更新日時を取得することはできませんが、Blogger内の投稿データ自体には更新日時を保持しています。それはfeedから得る事ができます。つまり、javascriptを使えば更新日時を表示する事ができます。

まずは更新日時を表示できるようにしてみましょう。
方法はp--q様のコードを使わせていただきました。

"アイテムページでは右詰めで公開日時、更新日時、投稿者名がでるようにしました。"
p--q
こちらのjQueryで更新日時を取得する事が出来ました。これを使ってhAtomのupdatedに更新日時を設定できないでしょうか?

jQueryなので簡単に属性値を再設定できます。time要素を追加してdatetime属性に日時を追加するコードをちょろっと追加しますが・・・

残念ながらbotは更新日時を解釈してくれません。IEやchromeでF12キーを押してDOM構造を確認すると正しくtime要素に更新日時の設定ができています。
しかしながら、Structured Data Testing Tool で見ると更新日時を認識していません。

これは、botはjavascriptを実行しないというのが原因でしょう。

"Changing microdata values was no sense, since as dwtm.ts said, bots don't execute javascript and parse only source code downloaded directly when they get the pages. You should use "fetch as googlebot" test tool from GWT to check how search bots "read" your page."
StackOverflow
という事でupdatedのデータは追加できていません。
Bloggerが更新日時を提供するデータタグを追加してくれるのを祈るしかないでしょうか。

まとめ

hAtomの構造化データの追加は比較的簡単にできます。データの要素も多くありません。
しかし、もう古い形式なので完全に消してしまうのが良いかもしれません。
構造化データは必須の要件になるでしょうからhAtomの代わりを使う方が良いでしょう。

次はその代替候補の一つBlogPostingについて書いてみようかと思っています。

本当はBloggerのテンプレートが最近の構造化データに対応してくれるとよいのですが、Picasaの扱いを含め、いつまでBloggerが存在しているか心配しだしてしまいます。
引っ越し準備をした方がよいのでしょうか。

コメント

最近のコメント

Threaded Recent Comments will be here.