Chrome に関する投稿を表示しています

(翻訳)Chrome の広告ブロックが何をしているか

元記事はこちら。
Chromium Blog: Under the hood: How Chrome's ad filtering works

自分の理解のため読んだ記録に。
※翻訳者は中の人でもなければ、ガバガバ翻訳なの※


web 上の多くの広告はユーザエクスペリエンスを尊重している。が、ここのところ邪魔なんだけど!と聞いていて、昨年 6 月に発表した( Chromium Blog: Improving advertising on the web )けど Chrome で Better Ads Standards ( The Initial Better Ads Standards - Coalition for Better Ads )に従ってない広告を消すようにしたよ。

Chrome が守っている詳細は前に説明した( Building a better web for everyone )けど、このアプローチがリリースされる 2 月 15 日が近くなってきているので、今日はどうやって動いているかを説明するよ。

Better Ads Standards って何?

オンライン広告のユーザーエクスペリエンスを向上させるための、業界団体が定めるもの。4 万人以上の北米・ヨーロッパのユーザにアンケートを取って、様々な広告について評価をしたよ。
一番迷惑だと評価されたのは全画面広告( Ad Experience: Prestitial Ads [Mobile] - Coalition for Better Ads )とフラッシュアニメーション広告( Ad Experience: Flashing Animated Ads [Mobile] - Coalition for Better Ads )だったよ。

詳しくはこっち( The Research - Coalition for Better Ads )をみてね。

そんな Better Ads Standards に違反する広告のいくつかは、そもそも広告自体に問題があるけれど、ほとんどはサイトの所有者が制御しているよ。思うに、広告が密集していたり、カウントダウンするような広告だったり。

この Better Ads Standards の結果を受けて、多くの迷惑な広告からユーザを守るアプローチを Chrome でやるよ。Better Ads Standards に準拠しているか評価して、発生した問題をサイトに報告、問題に対処する機会を提供し、それでも継続していたら広告の削除を行なうよ。

違反サイトの評価

サイト上のページのサンプルを調査して評価するよ。見つかった Better Ads Standards の問題に応じて、サイトが合格、警告、失敗のステータスに評価するよ。

サイトの評価ステータスは Ad Experience Report API ( Introduction | Ad Experience Report API | Google Developers )を通してアクセスできるよ。

サイト所有者は詳細な結果を見るために、 Google Search Console の Ad Experience Report ( Web Tools - Web Tools )の中で確認できるよ。ここで、再審査をしたりもできるね。

ネットワークレベルでのサイトのフィルタリング

Chrome ユーザがページに移動すると、 Chrome の広告フィルタが、ページが Better Ads Standards に違反してないかを確認するよ。このとき、ネットワークリクエスト(JavaScript や 画像たち)は広告関連 URL と一致しているかチェックするんだ。マッチした場合、 Chrome はそのリクエストをブロックして、広告を表示されないようにするよ。

この広告関連 URL は EasyList フィルタルール( EasyList - Overview )に基づいていて、 Google プラットフォームの AdSense や DoubleClick も含まれるんだ。

Chrome でこれがどのように見えるのか?

ここまで紹介したアプローチで Chrome は広告を自動的にブロックするんだ。少なくとも 1 つの広告がブロックされると、 Chrome はユーザにブロックした旨を伝えるよ。広告を許可するオプションもあるよ。

デスクトップユーザなら Chrome のアドレスバーにでるポップアップブロッカーと似たような通知を出すよ。Android ユーザの場合は画面下の小さなインフォバーで表示されるね。

初期の結果ではユーザのために良い進歩

この操作の結果で Chrome ユーザは Better Ads Standards に準拠していない広告は見えないことになるが、私達のゴールは全ての広告を見せないことではなく web ユーザのエクスペリエンスを向上させることだよ。( The browser for a web worth protecting

2 月 12 日時点では Better Ads Standards に違反していたサイトのうち 42% は既に合格しているよ。これは私達の望んていることで、迷惑な広告体験を修正し、全ての web ユーザに恩恵をもたらすんだ。

違反に関する通知を受けてから 30 日たってもサイトが修正されなければ Chrome は広告をブロックするよ。

私達は迷惑な広告体験から以降する早期な結果を持って、業界と継続的にやり取りし、 Chrome の広告フィルタ機能が不要になる未来を目指しているんだ!

エンジニアリングマネージャーの Chris Bentzel さんが書きました。

Node.js から Headless Chrome を操作できる puppeteer を試す

この記事は公開されてから1年以上経過しており、情報が古い可能性があります。

いい感じに Javascript がゴリゴリ書かれていて、認証が必要なサイトを定期的にキャプチャを取る、という謎タスクが生まれ、ちょうど最近話題の Headless Chrome でも試してみるかな~~と思ったら puppeteer なるものがあるそうなので、これを使ってみる。

GoogleChrome/puppeteer: Headless Chrome Node API

GoogleChrome 配下にいるので Chrome 公式のパッケージだ。

何も気にせず動かしてみる

// puppeteer 導入
$ npm init
$ npm install puppeteer

ドキュメントにもあるサンプルソースを入れてみる。

// index.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();

https://example.com へとアクセスし、そのページをキャプチャして ./example.png に保存するソースだ。 await で簡単わかりやすい書き方になるのが素晴らしい。これを動かしてみる。

$ node index.js
(node:30285) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Failed to launch chrome!
/var/www/html/crawl/bitbucket_billing/node_modules/puppeteer/.local-chromium/linux-497674/chrome-linux/chrome: error while loading shared libraries: libXss.so.1: cannot open shared object file: No such file or directory


TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

(node:30285) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

かなしみ…。どうにも libXss.so.1 が開けずにエラーっぽい。パッケージを探してインストールし、再度動かしてみる。

$ yum provides */libXss.so.1
...

libXScrnSaver-1.2.2-6.1.el7.i686 : X.Org X11 libXss runtime library
Repo        : base
Matched from:
Filename    : /usr/lib/libXss.so.1

libXScrnSaver-1.2.2-6.1.el7.x86_64 : X.Org X11 libXss runtime library
Repo        : base
Matched from:
Filename    : /usr/lib64/libXss.so.1


$ sudo yum install libXScrnSaver
...

$ node index.js
(node:1345) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Failed to launch chrome!
/var/www/html/crawl/bitbucket_billing/node_modules/puppeteer/.local-chromium/linux-497674/chrome-linux/chrome: error while loading shared libraries: libgtk-3.so.0: cannot open shared object file: No such file or directory


TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

(node:1345) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

GTK+3 が要求される。都合によって CentOS6 なのだが GTK+3 は入れるのがめっちゃ困難だった記憶。とりあえず GTK+3 というか Chrome を入れる方法を調べたら必要なライブラリも揃うだろう、と判断して調べる。

Google Chrome 60 Released - Install on RHEL/CentOS 7/6 and Fedora 26-20

Yes, they’ve discontinued support for RHEL 6.X version as of Google Chrome and on other side, latest Firefox and Opera browsers run successfully on the same platforms.

CentOS6 では Chrome は動かない、ダメ。Richard Lloyd 氏がスクリプトを作っているそうだが、そのサイトでも、いつまでも古いものを使うな、って書いてあった。

Site has been shut down

You have two choices really (ignoring Chromium, which no-one seems to be keeping up-to-date for RHEL/CentOS 6):

1. Use Mozilla Firefox ESR via "yum install firefox" that is shipped with RHEL/CentOS 6. Unfortunately, this can be up to a year out of date w.r.t. features compared to the more "normal" Mozilla Firefox that you can download from Mozilla (but that "normal" Mozilla Firefox is now also using GTK+3 and doesn't work on RHEL/CentOS 6 either).

2. Move to RHEL/CentOS 7, perhaps first in a VM before upgrading on bare metal once the VM is to your satisfaction. The latest Google Chrome installs and runs out-of-the-box on RHEL/CentOS 7 (see below).

気を新たにdockerで動かす

まあ、一旦使ってみるなら docker でもいいか。

$ docker run -it -d -v $(pwd):/var/www/puppeteer_test centos:latest
Unable to find image 'centos:latest' locally
latest: Pulling from centos
6c5159923047: Pull complete
acec82331181: Pull complete
1c1b67b33c28: Pull complete
Digest: sha256:57c91a43765de2147fa666a128477bc6101d6fda660feaaa5fbb1a8b110c934f
Status: Downloaded newer image for centos:latest
2be8ec65e6e4db3d852d563b82cc4c90ca90f62b4aaa6304d6e00f06d6a4a9e7

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
2be8ec65e6e4        centos:latest       "/bin/bash"         16 seconds ago      Up 16 seconds                           romantic_sinoussi

$ docker exec -it 2be /bin/bash

# cd /var/www/puppeteer_test/
# ls
index.js  node_modules  package-lock.json  package.json

# node -v
bash: node: command not found

// nodeがいないので入れる
# curl -sL https://rpm.nodesource.com/setup_8.x | bash -
# yum install nodejs

# node index.js
(node:114) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Failed to launch chrome!
/var/www/puppeteer_test/node_modules/puppeteer/.local-chromium/linux-497674/chrome-linux/chrome: error while loading shared libraries: libpangocairo-1.0.so.0: cannot open shared object file: No such file or directory


TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

(node:114) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

// とりあえず yum provides で探しながら一個ずつ入れていく
// をまとめたものがこちら
# yum groupinstall "Development Tools"
# yum install pango libXScrnSaver libXcomposite libXcursor libXi libXtst cups-libs libXrandr GConf GConf2 alsa-lib atk gtk3

// 起動してみる
# node index.js
(node:11985) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Failed to launch chrome!
[0920/101508.987383:ERROR:zygote_host_impl_linux.cc(88)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.


TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

(node:11985) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

root で --no-sandbox なしは認められないらしいのでソースを変える。

// index.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({args: ['--no-sandbox']});
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();

再び実行。

# node index.js

# ls
example.png  index.js  node_modules  package-lock.json  package.json

キャプチャ取れたので、画像を確認。

勝ち。

というわけで puppeteer 動いた。CentOS6 で CentOS7 が動いてて~ってちょっとアレなので、バージョン上げてまた試……、じゃない、本来の目的だった認証通してキャプチャできるかをやらなくちゃ。続く。

Chrome の console.log で CSS プロパティが指定できるよ

この記事は公開されてから1年以上経過しており、情報が古い可能性があります。

以前からごみばこいんでは、コンソールにようこそメッセージを出していました。

Chrome Devtools のドキュメントを見ると console.log の詳細が書かれています。

診断とコンソールへのログ出力  |  Web  |  Google Developers

ドキュメントには CSS プロパティが利用できるとあるのですが、なぜかこれまでは色とサイズが変えられる程度だと思っていました。試すと text-shadow が出来たり border が出来たりと、様々なプロパティが効くようです。

var properties1 = [
    'font-size: 8em;',
    'color: white;',
    'padding: 5px;',
    'background: linear-gradient(red, orange, yellow, green, aqua, blue, violet);',
    'text-shadow: white 0 0 15px;'
];

var properties2 = [
    'font-size: 8em;',
    'color: #222;',
    'text-shadow: white 0 0 3px;',
    'margin-left: calc(-15em - 6px);',
];
console.log(
    '%cうぇるかむとぅーごみばこいん!%cうぇるかむとぅーごみばこいん!',
    properties1.join(''),
    properties2.join('')
);

いくつかプロパティを試してみたのですが display だったり float だったり position 、 top や left あたりは無効化されているようです。。

で。実は Inspector を使うと、ここも HTML/JS/CSS で構成されていることがわかります。
Inspector は URL バーに chrome://inspect/ と入力するとアクセス出来ます。その中でも Other の項目を見ると Developer Tools について Inspect することができます。

DevTools の DevTools ができるなんてちょっと不思議な光景ですねw

こうやって console.log した結果を眺めてみると %c で指定したものは span タグの style 属性に入っています。
これでは :beforeなどのセレクタが使えなかったり、階層構造が持てないのでアニメーションしたりなどなども出来ないです。先にあった使えないプロパティのところもあるので、凝ったことをするのはできなさそうですねー。残念。