Google AdSense を試験導入

当サイトは収益確保を目的としたものではないため、長らく Web 広告なしでやってきました。開設当初の1年間ほど(2001年2月〜2002年3月)は無料のレンタルサーバーを使っていたので、ページ上部に広告が自動挿入されていましたけども。

現在はVPSと独自ドメインを契約しているため支出が発生していますが、一部のページに Amazon アフィリエイトリンクを貼っており、それで実コスト分は回収できています。

一方、技術的興味から Web 広告を試してみたいという欲求は以前からあり、この度Google AdSense(www.google.com) を導入してみました。実際にやった作業はこんなところです。

  • Google に対して AdSense の申請
  • サーバーのルート直下に ads.txt を配置
  • HTML 内にコードを挿入
  • アクセシビリティ面の調査
  • サーバーのセキュリティ設定を変更
  • プライバシーポリシーを整備

このうち、 Google への申請方法や AdSense 管理ページ内の設定、 ads.txt については既に多くの解説記事が出回っているため、ここではアクセシビリティ、セキュリティ面に焦点を絞り、気付いたことを記しておきます。

  1. HTML コードとアクセシビリティ(3重の <ins> に仰天)
  2. サーバーのセキュリティ設定
  3. プライバシーポリシーを整備

HTML コードとアクセシビリティ(3重の <ins> に仰天)

§

外部サービスを導入する際は HTML 内にコードを挿入する必要がありますが、 Google AdSense はこんなコードになっています。

  • 以下は4種類存在する広告ユニットのうち「記事内広告」の例ですが、他のユニットも一部の属性が異なるのみで大差はありません。
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-{サイト運営者ID}"
     data-ad-slot="{広告ごとのID}"></ins>
<script>
   (adsbygoogle = window.adsbygoogle || []).push({});
</script>

このコードをはじめて見た時、思わず腰を抜かしてしまいました。なぜ <ins> 要素!?

<ins> 要素(WHATWG) とは、ドキュメントの変更に伴い追加された箇所をマークアップするのに使う要素です。例えばECサイトにおいて商品価格が値下げされた場合、次のように使います。

<del datetime="2020-07-17">500</del> <ins datetime="2020-07-17" cite="https://ec.example.com/sale">300</ins>

そのため、広告の挿入に <ins> を使うのは不適切だと思うのですが……。

さらに、実際には adsbygoogle.js によって <ins> 内に広告が挿入されるのですが、その DOM 構造はこんな感じになります。

<ins class="adsbygoogle" style="display: block; text-align: center; height: {算出された高さ};" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-{サイト運営者ID}" data-ad-slot="{広告ごとのID}" data-adsbygoogle-status="done">
  <ins id="aswift_0_expand" style="{省略}">
    <ins id="aswift_0_anchor" style="{省略}">
      <iframe id="aswift_0" name="aswift_0" style="{省略}" src="https://googleads.g.doubleclick.net/pagead/ads?{たくさんのパラメーター}" {たくさんの属性}></iframe>
    </ins>
  </ins>
</ins>

なぜか <ins> 要素が3重になります。Google さん、どんだけ <ins> 好きなんですか!! などと呑気にツッコんでいる場合ではありません。支援技術によっては大変なことになります。

試しに Windows 10 + Firefox 78 + NVDA 2020.1jp で読み上げると、「挿入マークあり、挿入マークあり、挿入マークあり、フレーム 広告」となります。ここで「広告」と読まれるのは、 <iframe> 内の <body> の冒頭に <span>広告</span> があるためです。続けて、広告内において Tab キーや ↓ キーで移動するたびに「挿入マークあり、挿入マークあり、挿入マークあり」と読まれて鬱陶しいことこの上ありません。さらに、「もっと見る」ボタンの後は長々としたURLパラメーターが延々と読み上げられる事態になってしまいます。

Google AdSense 広告のスクリーンリーダー読み上げの様子(YouTube)

このようにマークアップが変というだけでなく、閲覧環境によっては実害も出ている状況です。とはいえ、挿入コードは勝手に変更できないのでどうしようもありません。せめて最も外側の <ins> だけでも <aside><div> に変更できないかと思ったのですが、 adsbygoogle.js において document.getElementsByTagName("INS") なんてことをやっていますから、 <ins> のままでないと広告が正常に表示されないのです……。

また、本来なら <iframe>title 属性が欲しいところです。フレームを title 属性でラベル付けすることにより、ショートカットキー等で複数フレームの間を移動する際の利便性が高まるからですが[1]、前述のとおり <ifrmae> 内の <body> 冒頭にある <span>広告</span> が読み上げられるため、 title 属性がなくても実害は少ないかもしれません。

このように、 Google AdSense の広告はスクリーンリーダーでの読み上げやキーボード操作による移動はあまり考慮されていない状況です。当サイトでは収益確保ではなく「広告を導入する」ことが主目的ということもあり、広告を目立たないフッターの最下部に配置しているので(すなわち広告の後方には何のコンテンツも存在しない)、多少アレな状況でも大きな影響はないと思うのですが、ページの先頭やコンテンツの途中に広告を配置する場合はアクセシビリティの面からも慎重に検討する必要がありそうです。

サーバーのセキュリティ設定

§

当サイトでは CSP で Trusted Types(w3c.github.io) を設定しており、前記のコードを HTML 内に挿入しただけでは JavaScript エラーが出てしまいました。

Chrome のデベロッパーツールでコンソールを見ると、こんなエラーです。

❌ Refused to create a TrustedTypePolicy named 'goog#html' because it violates the following Content Security Policy directive: "trusted-types default 'allow-duplicates'".

❌ Failed to execute 'createPolicy' on 'TrustedTypePolicyFactory': Policy "goog#html" disallowed.

ブラウザのコンソールに赤文字でエラーメッセージが表示されている様子

これの対処は簡単で、 trusted-types ディレクティブのポリシー名に goog#html を追加するだけです。当サイトは Apache で動いており、 CSP はHeader ディレクティブ(httpd.apache.org) で設定しているのですが、その記述をこうしました。

Header set Content-Security-Policy: "trusted-types goog#html default 'allow-duplicates'; require-trusted-types-for 'script'; (以下省略)"

2020年10月31日追記10月29日に google#safe が追加されました。

プライバシーポリシーを整備

§

Google AdSense オンライン利用規約(www.google.com) にはこんな記述があります。

10. プライバシー

(中略)

お客様は、本サービスを利用するに際しては、常に、明確に表示され、簡単にアクセス可能なプライバシー ポリシーを広告媒体に必ず付すものとし、当該プライバシー ポリシーにより、Cookie、デバイス特有の情報、ロケーション 情報、および本サービスに関連してエンド ユーザーのデバイスに保存され、当該デバイスにおいてアクセスされ、当該デバイスから収集されるその他の情報(場合により、Cookie 管理に関するエンド ユーザーのオプションに関する情報を含みます)についての明確かつ包括的な情報をエンド ユーザーに提供するものとします。Cookie、デバイス特有の情報、ロケーション情報または本サービスに関連したエンド ユーザーのデバイスに関するその他の情報の保存およびアクセスに対してエンド ユーザーの承諾が法律により要求される場合は、エンド ユーザーから当該承諾が得られるように、お客様は商業的に合理的な努力をするものとします。

Google AdSense オンライン利用規約(www.google.com)

また、より具体的なことがヘルプセンターに記載されています。

プライバシー ポリシーには次の情報を記載する必要があります。

・Google などの第三者配信事業者が Cookie を使用して、ユーザーがそのウェブサイトや他のウェブサイトに過去にアクセスした際の情報に基づいて広告を配信すること。

・Google が広告 Cookie を使用することにより、ユーザーがそのサイトや他のサイトにアクセスした際の情報に基づいて、Google やそのパートナーが適切な広告をユーザーに表示できること。

・ユーザーは、広告設定でパーソナライズ広告を無効にできること(または、www.aboutads.info にアクセスすれば、パーソナライズ広告に使われる第三者配信事業者の Cookie を無効にできること)。

プログラムポリシー > プライバシーとセキュリティ > 必須コンテンツ(support.google.com)

これらを鑑みたうえで、とくに以下の情報が伝わるようなプライバシーポリシーを作成しました。

  • 広告を掲載する目的(Web 広告の技術的興味および調査)
  • ファーストパーティ Cookie 、およびサードパーティー Cookie を使っていること
  • サードパーティー Cookie のドメイン名
  • Cookie をブロックしていても広告は表示されること
  • アドブロック等で広告を表示しない状態にしていてもページの閲覧には支障ないこと

以前から「Google アナリティクス」や「Twitter」に関する記述はしていましたが、そこに Google AdSense の記述を追加してこんな感じになりました。

巷のプライバシーポリシーは難解な長文で読む気も起こらないというのが常ですが、これくらいの長さなら全文読むのもそこまでツラくないかと思っています。なお、このサイトの対象読者は決して Web エンジニアだけではないので、「ファーストパーティ Cookie」などの用語を知らない人も多いと思うのですが、興味ある人はググるなりして自分で適切なリソースを見つけるでしょうし、興味ない(気にしない)人にとってはどうでもいい情報でしょうから、そういった用語解説をプライバシーポリシーに書く必要はないと考えています。

脚注