🙊

javascript で #shadow-root (shadowRoot) の中身をスクレイピングする

2022/02/20に公開

動機

y○utube の #shadow-root の中身が欲しかった
(javascript で tampermonkey の user script を書きたかったわけです)

結論

y○utube は Polymer を使用して Shadow DOM を作成しています。
Polymer なら以下で #shadow-root の innerHTML は取得できる。他のライブラリとかは知らないです。

document.getElementById('id_where_you_wanna_get').__shady.ba.host.innerHTML

あとはお好きに。

もうちょい詳しく

y○utubeが Polymer を使用してDOMを作っており、特定の #shadow-root 下にある情報だけを選択的に抜き出すことができなかった。

試行錯誤

  1. Python selenium Chrome では以下のコードで取得できるらしい
shadow_root = driver.execute_script(
        'return arguments[0].shadowRoot', element)

でも今回は tampermonkey でやりたかったのでナシ

  1. shadow DOM にはopenモード, colosedモードがあるらしいので弄ってみる
    やり方はこちら。mode が closed だったから参照できなかったのか?
    https://blog.revillweb.com/open-vs-closed-shadow-dom-9f3d7427d1af
    試してみたんだけどイマイチうまくいかない
element.attachShadow({mode: "open"};

prototype.attachShadow を乗っ取って全部openにしちまおうぜ!っていうのもあったけど試す前にDOMにアクセスする方法を見つけた。沼を掘った。

Element.prototype._attachShadow = Element.prototype.attachShadow; 
Element.prototype.attachShadow = function  (){ 
    return this._attachShadow({mode: "open"}; 
};

沼の中

最終的に冒頭のこのコードでやってみることにした。でも上記2の後者は使えそうなので気が向いたら試してみたい。

document.getElementById('id_where_you_wanna_get').__shady.ba.host.innerHTML

これでyoutubeのコンテンツをダウンロードでき、、ええ。ヒャッハー

余談で蛇足なんですけど、 映画とかドラマで、ヒャハハハハ みたいに笑う悪役がでてくるとまあまあ萎えちゃうほうです。だってそんな笑い方する人、今まで一度も実生活で見たことないもの。

Discussion