はじめに
こんにちは ラスクです。
本記事では、スクレイピング(Selenium)時に画面から値を取得する際の躓きポイントを豆知識としてご紹介していきます。
早速本題ですが、Webスクレイピングをする際に、ページロード時には表示されていない項目から値を取りたい。なんてことはないでしょうか?
Seleniumでは非表示項目の要素を特定することはできても、値を取得することはできません。要素が特定できるから値も取れるだろうと思っていたことで躓いたことがあるので同じ方のお役に立てればと思い、まとめていきます。
動作検証環境
今回の動作検証環境は以下の通りです。
作業エディタ:VSCode
OS:MacOS 12.0.1
Pythonバージョン:Python3.9.5
回避方法
いくつか回避方法がありますので、ご紹介します。
- 要素を表示させるアクションを実行する(例:Click())
- CSSを変更して要素を表示させる
- 要素を表示させる方法を別視点から考える
要素を表示させるアクションを実行する
1つ目は、要素を表示させるボタンやアクションがあれば、アクション処理を通してから値を取得するように修正してみましょう。
# 要素クリック
elem_btn = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "XXXX")))
driver.execute_script('arguments[0].click();', elem_btn)
# 要素クリック後に表示される項目を取得する
elem = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "XXXX")))
CSSを変更して要素を表示させる
2つ目は、非表示項目のCSSで表示させて表示項目として取得する方法です。
要素がそもそもなかったらNGですが、要素が隠されているだけならば、表示させて取得しちゃおうというものですね。(クリック時に表示されるのであれば、1つ目の方法で取得可能かもです。)
例えば、マウスフォーカスしたら表示される項目やスクロースしたら表示される項目などが該当すると思います。
以下、参考コードになりますので、ご参考までに!
# display:none; → display:block;
elem_div = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "XXXXX")))
driver.execute_script("arguments[0].setAttribute('style','display: block;')", elem_div)
要素を表示させる方法を別視点から考える
3つ目は、最後の手段で、できればの話ですが、画面を触って出さなければいけないという固定概念に囚われずに考えてみましょう。ということです。
- 別ページからの取得はできないか
- パラメータ指定での表示切り替えはできないか
実際に行き詰まった時に一度立ち止まって考え直してみたところ、別の方法で取得できることがあったので、固定概念に囚われず、柔軟に考えてみると良い方法が思いつくかもしれません。
参考サイト
まとめ:少しの工夫で非表示項目を取得しよう
実際に躓いたことをまとめてみました。
結論は、諦めず取得できそうな方法を模索して作業を効率化しましょう。ということです。
非表示項目でも表示されるロジックはあるはずなので、手順を踏んで取得できる方法を模索してみましょう。
また豆知識っぽい事例あれば記事化していこうと思います〜!