LoginSignup
2
1

More than 3 years have passed since last update.

ブラウザのconsoleからは要素を取得できるのに、scriptから取得するとnullになるときは、iframeの要素かもしれないというお話

Posted at

はじめに

簡単なスクレイピングツールを書いていたら、不可解な現象に遭遇してハマってしまいました。
同じような現象に遭遇した人が無為な時間を過ごさないように共有します。

スクレイピングツールを書くときのお話

「この部分の内容を取得したい!」と思ったら、該当部分を右クリックして「要素の詳細を表示」(Safariの場合)からHTMLを眺めて、要素のattributeなどをチェックします。

そして、こうやれば取得できるかなというコマンドを、試しにconsoleに入力してみます。

document.querySelector('a[href^="/start_with"]) // => <a href="/start_with/12345">...</a>

無事に結果が返ってきました!

通常はこのような手順でうまくいったコマンドをスクリプトにまとめていくと思います。ところが……

スクリプトを実行するとnullが返ってくる

???

あれ?コピペしたのにおかしいな。このコマンドにたどり着くまでのページ遷移がおかしいのかな?いや、そもそも……という感じで1時間くらい哀しい時間を過ごしました。

iframeの中の要素だった

色々試すうちに気がつきました。あれ?取得しようとしている要素がiframeの中にあるぞ。
ページ上から要素の詳細を表示すると、対象の要素が見える状態まで展開されるのでなかなか気がつかなかったのです。

iframeの中の要素を取得する

というわけで結論です。
以下のように、iframe.contentDocumentから検索することでiframe内の要素を取得できます。

const iframe = document.querySelector('#iframe-selector')
// iframe.contentWindow.document === iframe.contentDocument
const targetElement = iframe.contentDocument.querySelector('a[href^="/start_with"]')

 // XPathで取得するときは、2つめの引数にiframe.contentDocumentを渡せばOK
const targetElementByXPath = document.evaluate(
  '//a[contains(@href, "/start_with")]',
  iframe.contentDocument,
  null,
  XPathResult.FIRST_ORDERED_NODE_TYPE,
  null
).singleNodeValue

どうやら、Webインスペクタやデベロッパーツールからiframe内の要素を手動で表示した時点で、iframe内の要素が、通常のdocument内に展開されるようです。そのため、ブラウザのconsoleからは取得できてしまっていたのでした……(かなしみ)

参考

javascriptでiframe内のDOM要素を取得したり操作する

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1