seleniumでの要素出現を待った（wait）取得の方法

SeleniumのWebDriverWaitとexpected_conditions（EC）は、「要素が現れるまで待つ」「特定の状態になるまで待つ」ための非常に重要な機能です。

## 1. WebDriverWaitとは？
ページの読み込みや要素の出現など、「何かの状態になるまで」明示的に待機するためのクラスです。
例：
「id='target'の要素が現れるまで最大10秒待つ」
```python
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
  EC.presence_of_element_located((By.ID, "target"))
)
```

## 2. expected_conditions（EC）とは？
`selenium.webdriver.support.expected_conditions` の略で、「どんな状態を待つか」を指定するための関数群です。
例：
- 要素が存在するまで待つ
- 要素がクリック可能になるまで待つ
- 要素が表示されるまで待つ
- アラートが出るまで待つ
- タイトルが変わるまで待つ
など

## 3. よく使うECのバリエーション
| メソッド名 | 意味・用途 | 例 |
|---|---|---|
| presence_of_element_located | 要素がDOM上に現れるまで待つ（表示/非表示は問わない） | EC.presence_of_element_located((By.ID, "target")) |
| visibility_of_element_located | 要素が「表示」されるまで待つ | EC.visibility_of_element_located((By.ID, "target")) |
| element_to_be_clickable | 要素が「表示」かつ「有効」になり、クリック可能になるまで待つ | EC.element_to_be_clickable((By.ID, "target")) |
| text_to_be_present_in_element | 要素内に特定のテキストが現れるまで待つ | EC.text_to_be_present_in_element((By.ID, "target"), \"ログイン\") |
| invisibility_of_element_located | 要素が「非表示」または「DOMから消える」まで待つ | EC.invisibility_of_element_located((By.ID, "target")) |
| presence_of_all_elements_located | 複数の要素がDOM上に現れるまで待つ | EC.presence_of_all_elements_located((By.CLASS_NAME, "item")) |
| alert_is_present | アラートダイアログが出るまで待つ | EC.alert_is_present() |
| title_is | ページタイトルが完全一致するまで待つ | EC.title_is(\"Google\") |
| title_contains | ページタイトルに部分一致するまで待つ | EC.title_contains(\"Google\") |
| frame_to_be_available_and_switch_to_it | 指定したiframeが利用可能になるまで待ち、自動で切り替える | EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME, \"iframe\")) |

## 4. 使い方の例
```python
# 1. 要素が表示されるまで待つ
element = WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.ID, "target"))
)

# 2. 要素がクリック可能になるまで待つ
element = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//button[text()='送信']"))
)

# 3. テキストが現れるまで待つ
WebDriverWait(driver, 10).until(
    EC.text_to_be_present_in_element((By.ID, "message"), "完了")
)

# 4. アラートが出るまで待つ
WebDriverWait(driver, 10).until(EC.alert_is_present())
```

## 5. 公式ドキュメント・全バリエーション
公式ドキュメント（英語）
https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html

## 6. カスタム条件も作れる！
自分で関数を作って、WebDriverWaitで使うこともできます。
Apply to edge_login_l...
```python
def my_condition(driver):
    return driver.find_element(By.ID, "target").text == "OK"

WebDriverWait(driver, 10).until(my_condition)
```


## 7. document.readyStateによる待機との違い・使い分け
**`document.readyState` での待機**
```python
def my_condition(driver):
    return driver.find_element(By.ID, "target").text == "OK"

WebDriverWait(driver, 10).until(my_condition)
```

ページ全体の「初期読み込み」完了を待つ方法です。HTMLのパースや静的リソース（画像・CSS・JSなど）のロードが終わった状態を保証します。ただし、JavaScriptで後から動的に追加される要素はこの時点でまだ現れていないことが多いです。

**ECによる要素待機**
```python
WebDriverWait(driver, 20).until(
    lambda d: d.execute_script('return document.readyState') == 'complete'
)
```
特定の要素がDOM上に現れるまで待つ方法です。動的に生成される要素や、Ajaxで後から追加される要素にも対応できます。ページの「見た目」はできていても、肝心の要素がまだ出ていない場合にも有効です。

**使い分けのポイント**
- ページ遷移直後の「最低限の読み込み完了」を保証したい場合
→ document.readyStateでの待機が有効

- 本当に必要な要素が出てきたことを保証したい場合
→ EC系の要素待機（presence_of_element_locatedなど）が圧倒的におすすめ
- 実践的には両方組み合わせることも多い
    - document.readyStateで初期ロードを待つ
    - その後、ECで必要な要素を待つ

例：両方組み合わせる
```python
# 1. ページの初期ロードを待つ
WebDriverWait(driver, 20).until(
    lambda d: d.execute_script('return document.readyState') == 'complete'
)

# 2. 必要な要素が現れるまで待つ
element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "target"))
)
```

## まとめ
- WebDriverWaitは「状態になるまで待つ」ためのもの
- EC（expected_conditions）は「どんな状態を待つか」を指定するもの
- クリック可能、表示、非表示、テキスト出現、アラート、タイトル、iframeなど多彩なバリエーション
- カスタム条件もOK
- document.readyStateは「ページ全体の初期読み込み完了」を待つのに有効
- EC系の要素待機は「本当に必要な要素が出てきた」ことを保証したいときに最適
- 両方を組み合わせることで、より堅牢な自動化が可能