selenium(Python)でstyleが"display: none;"となっている要素を取得する

 他の人も既に同様の記事を書いているのですが、メモ代わりにブログに残します。

使える場面

 例えば以下のような<li>タグがあった場合、

<li style="display: none;">
  <a href="...">
    <div class="title">fuga</div>
  </a>
  <div class="description">xxxxxxxxxxx</div>
</li>
<li style="display: none;">
  <a href="...">
    <div class="title">hoge</div>
  </a>
  <div class="description">xxxxxxxxxxx</div>
</li>

...

こういうの、ページネーションとセットでよく出てくる気がします。 次ページの番号をクリックすると、別リンクに飛ばすよくある仕様でなく。 指定した番号に対応する<li>noneからblockなどに切り替えると同時に、それ以外の<li>タグをnoneに切り替え非表示とすることで、ユーザーに他ページに飛んだように見せることがよくある気がします。

こういうサイト。例えばBeautifulSoupでスクレイピングしようとしてもうまくいかないので、seleniumを使ってjsをいじりながらやっていくのが早いかと思います。

コード

 seleniumでjsのコードを動かす場合、execute_scriptメソッドが非常によく使われるかと思います。例えば要素をクリックしたり、スクショしたり、、、etc.

そんなexecute_scriptですが、styleの書き換えも簡単に行うことが可能です。

driver.execute_script("arguments[0].style.display='block';",{要素})

結果の確認

 確認のため状況HTMLをローカルに保存してseleniumスクレイピングしてみます。まず以下のコードでローカルに保存したHTMLファイルを開いてみます。

url = 'file://{htmlファイルの絶対パス}'
chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=chrome_options)
driver.get(url)

結果

f:id:spider-man-dance:20211019142559p:plain
selenium1

非表示であることが確認できます。 次に以下の行を追記してコードを再実行してみます。

url = 'file://{htmlファイルの絶対パス}'
chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=chrome_options)
driver.get(url)

elems = elems.find_elements_by_tag_name('li')
for elem in elems:
    driver.execute_script("arguments[0].style.display='block';", elem)

結果

f:id:spider-man-dance:20211019143021p:plain
selenium2

CSSが書き換えられ<li>タグの中身が表示されているのが分かります。これで.textでテキストを取得したりすることも可能になります。

追記

プロ野球のデータ可視化サイトを作りました!ぜひ遊びにきてください!