Django Girls and Boys 備忘録

Python、Selenium、Django、java、iPhoneアプリ、Excelマクロなどで気付いたこと、覚えておきたいことなどを載せていきます。

【Python Selenium】解決! NoSuchElementExceptionの原因と対処法まとめ

Seleniumを使っていると、必ずと言っていいほど遭遇するのがこのエラーです。

 
NoSuchElementException

または、

 
element not interactable

この記事では、

  • Seleniumで要素が取得できない原因

  • find_elementの違い

  • 明示的待機(WebDriverWait)の使い方

  • 動的ページの対処法

を、実例コード付きでわかりやすく解説します。


1️⃣ NoSuchElementExceptionとは?

このエラーは、

「指定した要素が見つからない」

ときに発生します。

例えば:

 
driver.find_element(By.ID, "login-button")

 

などを実行した時に、指定したIDが存在しない、またはまだ読み込まれていない場合に発生します。


2️⃣ よくある原因5つ

① ページの読み込みが終わっていない

SeleniumはHTMLが完全に描画される前に処理を実行することがあります。

② IDやクラス名が間違っている

開発者ツールで再確認しましょう。

③ iframe内の要素

iframe内の要素は、そのままでは取得できません。

④ JavaScriptで後から生成される要素

動的ページではよくあります。

⑤ 表示されていない(非表示)

これが element not interactable の原因になります。


3️⃣ find_elementの違い

Selenium 4以降は書き方が変わっています。

❌ 古い書き方(非推奨)

 
driver.find_element_by_id("login")

 

✅ 新しい書き方

 
from selenium.webdriver.common.by import By

driver.find_element(By.ID, "login")
driver.find_element(By.CLASS_NAME, "btn")
driver.find_element(By.XPATH, "//button[text()='ログイン']")

 


4️⃣ 解決策①:明示的待機(WebDriverWait)

最も重要な対策です。

 
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

wait = WebDriverWait(driver, 10)

element = wait.until(
    EC.presence_of_element_located((By.ID, "login"))
)

 

これで、

「最大10秒待って、要素が表示されたら取得」

という動きになります。


よく使う待機条件

条件 説明
presence_of_element_located DOMに存在する
visibility_of_element_located 表示されている
element_to_be_clickable クリック可能

クリックエラーが出る場合はこれ:

 
wait.until(EC.element_to_be_clickable((By.ID, "login")))

 


5️⃣ 解決策②:iframeの切り替え

iframe内の場合は必ずこれが必要です。

 
driver.switch_to.frame("frame_name")

 

処理後に戻す:

 
driver.switch_to.default_content()

 


6️⃣ 解決策③:動的ページ対策(JavaScript生成)

AjaxやReactサイトでは、要素が後から生成されます。

その場合:

 
wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, ".result-item")) )

 

無限スクロール型サイトでは:

 
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

 

をループさせます。


7️⃣ element not interactable の原因

このエラーは、

✔ 要素が非表示
✔ 画面外にある
✔ 別要素が重なっている

ときに起きます。

対策:

 
element = wait.until( EC.element_to_be_clickable((By.ID, "submit")) ) element.click()

 

またはスクロール:

 
driver.execute_script("arguments[0].scrollIntoView();", element)

 


8️⃣ それでも解決しないときのチェックリスト

✔ IDは正しいか?
✔ iframeではないか?
✔ ページ遷移後にすぐ実行していないか?
✔ headlessモードで表示崩れしていないか?
✔ JavaScript生成ではないか?


まとめ

Seleniumで要素が取得できない原因の多くは、

「待機不足」または「iframe」

です。

まずは WebDriverWaitを必ず使う ことが重要です。