Webスクレイピング Advent Calendar 2017 22日目の記事です。
(内容的にWebスクレイピングからちょっとずれてしまいましたが、気にしたら負けだと思いました)
何故Puppeteerを使うと良いのか?
17日目の記事の方も書かれているように、最近、Headless ChromeのDevTools Protocolを使ってWebスクレイピングが出来るPuppeteer(綴りが難しい)というライブラリが人気のようです。
以前からあるWebスクレイピングのツールとしてはPhantomJSがあり、CSSのテストツールとしてもこれを使ったPhantomCSSというものがあります。しかしPhantomCSSは
- 依存しているライブラリであるPhantomJSのメンテナンスが終了
- それに伴い、PhantomCSSのメンテナンスも終了
-
PhantomJSでは(おそらく?)DOMレンダリング後のwidth, heightといった値が取れない1
という理由から、今後使い続けていくのが難しくなりつつあります。
そこで、新しく登場したPuppeteerで、実際にレンダリングされた後のwidthやheightを使ってCSSのテスト(CSSに書いた値が実際の見た目と合っているかどうか)をしようというのがこの記事です。
Puppetterでスクレイピングしてきてwidthやheightの情報を抽出するのはこちらの記事が大変参考になります。
ref: PuppeteerでWebページからメインコンテンツっぽいところを抽出してみる
簡単なサンプル
コード全文はこちら
(本当に簡単な例だけなのでアレですが)例えば以下のように
<!-- html -->
<div id="main">
メイン
</div>
/* CSS */
#main {
display: inline;
width: 100px;
height: 100px;
}
inline要素に間違ってwidthやheightを指定してしまった場合でも、puppeteerを使って
/* javascript */
const puppeteer = require('puppeteer');
(async() => {
const url = "http://127.0.0.1:8080/"
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url, {waitUntil: 'networkidle2'}); // ページがレンダリングされるまで待つ
const selector = '#main'
await page.waitForSelector(selector); // DOMが表示されるまで待つ
const rect = await page.evaluate(selector => {
const element = document.querySelector(selector);
const {x, y, width, height} = element.getBoundingClientRect();
return {x: x, y: y, width: width, height: height}
}, selector);
console.log(rect) // デバッグ用にとりあえずログに出す
await page.screenshot({path: 'ss.png', clip: rect}) // 一応目視でも確認するためのスクリーンショット
await browser.close();
})();
のようなコードを書いて実行すると、CSSで指定した値そのものではなく、実際にレンダリングされた後の値が返ってきて、間違いであることを検証出来ます。
実行例
$ node script.js
{ x: 8, y: 12, width: 48, height: 17 }
念のため比較用に、CSSをdisplay: block
にしてから再度実行すると
$ node script.js
{ x: 8, y: 8, width: 100, height: 100 }
のように、ちゃんと意図通りにレンダリングされた結果の値が返ってきます。
余談
PhantomJSで出来ないことをやりたかったけど、PhantomJS試してみたら色々出来てしまったので微妙な感じになってしまった、うーん...
参考文献
- PhantomCSS
- Puppetter
-
試してみたら取れた ↩