0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SeleniumでJS-renderedページ取得のベストプラクティス|AI実務ノート 編集部

Last updated at Posted at 2026-01-03

1. 結論(この記事で得られること)

この記事を読むと、Seleniumで動的レンダリングされるページから確実にデータを取得できる実装が書けるようになります。

具体的には:

  • 待機戦略の正しい設計(暗黙的待機は使わない理由)
  • 要素の可視性判定(「presence_of_element_located」 vs 「visibility_of_element_located」 の使い分け)
  • AI(Claude/GPT)を使った障害切り分けの最速フロー
  • 実務で通用するリトライ設計とログ戦略

私自身、5年前に「なぜか本番環境だけ取得できない」というスクレイピング障害で2日溶かした経験があります。原因は「要素の存在 ≠ 描画完了」を理解していなかったこと。この記事では、そういう現場の地雷を全部踏まえた設計を紹介します。

2. 前提(環境・読者層)

想定読者

  • Python / Selenium でスクレイピング・E2Eテストを書く人
  • 「たまに取れない」「CIで失敗する」という不安定さに悩んでいる人
  • AIを実務フローに組み込む方法を模索しているエンジニア
selenium==4.15.0
python==3.11
Chrome==120.x + ChromeDriver(webdriver-manager で自動管理推奨)

用語の定義

  • JS-rendered:JavaScript実行後に初めてDOMが生成される仕組み(React/Vue/SPAなど)
  • 待機(Wait):要素が出現するまでポーリングで確認する処理

3. Before:よくあるつまずきポイント

典型的な失敗コード

from selenium import webdriver
 
driver = webdriver.Chrome()
driver.get("https://example.com/spa")
 
# ❌ ダメな例1:即座に取得しようとする
title = driver.find_element(By.CLASS_NAME, "dynamic-title").text
print(title)  # NoSuchElementException が飛ぶ
 
# ❌ ダメな例2:固定sleep
import time
time.sleep(5)  # 環境依存で壊れる
title = driver.find_element(By.CLASS_NAME, "dynamic-title").text

なぜダメか?

① 「driver.get()」 は HTML 取得完了で返るが、JS実行完了は待たない

② 固定sleepは遅い環境で足りず、速い環境で無駄

③ 要素が DOM に存在しても 「display:none」 なら操作不可

私が昔ハマったのは「ローカルでは成功、AWS Lambdaでは失敗」というパターン。原因はCPUスペック差による描画タイミングのズレでした。

4. After:基本的な解決パターン

正しい待機の基本形

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
 
driver = webdriver.Chrome()
driver.get("https://example.com/spa")
 
# ✅ 明示的待機:要素が「見える」まで待つ
wait = WebDriverWait(driver, timeout=10)
title_element = wait.until(
    EC.visibility_of_element_located((By.CLASS_NAME, "dynamic-title"))
)
print(title_element.text)

待機条件の使い分け

「presence_of_element_located」
 用途: DOM上に存在すればOK
 注意点: 「display:none」 でも通る

「visibility_of_element_located」
 用途: 画面に表示されている
 注意点: 推奨(クリック可能判定に近い)

「element_to_be_clickable」
 用途: クリック可能
 注意点: ボタン操作の直前

レビューで必ず指摘するポイント

# ❌ 暗黙的待機は絶対NG
driver.implicitly_wait(10)  # 全要素に影響、デバッグ困難
 
# ✅ 明示的待機のみ使う
wait = WebDriverWait(driver, 10)

理由:暗黙的待機は「要素が見つからない場合に毎回待つ」ため、エラー時に10秒×要素数待たされる。デバッグ時に地獄を見ます。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?