Pythonを用いたブラウザ自動化において、要素の取得は最も基本的かつ重要なステップです。
特にウェブサイトの構造を定義するclass名やタグ名を利用した要素指定は、特定の情報を効率的に抽出するために欠かせません。
しかし、近年の動的なウェブサイトでは、単純に指定するだけでは要素が見つからない、あるいは意図しない要素を取得してしまうといったトラブルも少なくありません。
本記事では、Selenium 4以降の標準的な記述方法に基づき、class名とタグ名を使って要素を確実に取得・操作するための具体的な手順を解説します。
初心者の方が陥りやすい「複合クラス」の扱い方や、複数の要素をまとめて取得する際のポイントについても触れていきます。
Seleniumにおける要素取得の基本構造
Seleniumで要素を取得する際、以前のバージョン(Selenium 3以前)では find_element_by_class_name といったメソッドが使われていましたが、現在の最新バージョンでは Byクラスを用いた指定方法 が標準となっています。
これにより、コードの可読性が向上し、メンテナンスが容易になっています。
まず、要素を取得するための基本的なライブラリのインポートとセットアップを確認しましょう。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
# WebDriverの初期化
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
# 対象のURLを開く
driver.get("https://example.com")
要素を指定する際には、常に from selenium.webdriver.common.by import By を記述し、By.CLASS_NAME や By.TAG_NAME を引数として渡す形をとります。
この統一された記述法をマスターすることが、エラーの少ない自動化プログラムへの第一歩です。
class名による要素の取得 (By.CLASS_NAME)
class名は、HTML要素にスタイルを適用するために最も頻繁に使われる属性の一つです。
特定のボタンや入力フォーム、テキストエリアなどを特定する際に非常に便利です。
基本的な記述方法
単一の要素を取得する場合は、find_element メソッドを使用します。
# class名が "submit-button" の要素を取得
element = driver.find_element(By.CLASS_NAME, "submit-button")
# 要素に対してクリック操作を行う
element.click()
このコードを実行すると、指定したクラスを持つ最初の要素が返されます。
もしページ内に同じクラス名を持つ要素が複数ある場合、最初に見つかった1つだけが対象となる点に注意してください。
複合クラス (Compound Classes) の注意点
多くの開発者が直面する問題に「複合クラス」があります。
HTML上で class="btn btn-primary active" のようにスペースで区切られた複数のクラスが設定されている場合、そのまま文字列として渡すとエラーが発生します。
# NG例:スペースを含めるとエラー(InvalidSelectorException)になる
# element = driver.find_element(By.CLASS_NAME, "btn btn-primary")
# OK例:一つのクラス名だけを指定する
element = driver.find_element(By.CLASS_NAME, "btn-primary")
SeleniumのBy.CLASS_NAMEでは、スペースを含む複数のクラスを一度に指定することはできません。
確実にその要素を特定したい場合は、後述するCSSセレクターを利用するか、その要素を象徴する単一のクラス名を選択する必要があります。
タグ名による要素の取得 (By.TAG_NAME)
タグ名は、h1、p、a、table といったHTMLのタグそのものを指します。
特定のクラス名が割り振られていない場合や、ページ内のすべてのリンク、すべての表データを抽出したい場合に有効です。
特定のタグから情報を抽出する
例えば、ページ内のすべてのハイパーリンク (aタグ) のURLを取得したい場合は、次のように記述します。
# すべてのaタグを取得
links = driver.find_elements(By.TAG_NAME, "a")
for link in links:
# href属性を取得して表示
url = link.get_attribute("href")
print(url)
| メソッド名 | 戻り値 | 見つからない場合 |
|---|---|---|
| find_element | 単一の WebElement | NoSuchElementException |
| find_elements | WebElementのリスト | 空のリスト [] |
このように、複数を対象とする場合は find_elements (末尾にsがつく) を使用することが重要です。
タグ名指定は範囲が広すぎる傾向があるため、次に解説する「絞り込み」と組み合わせて使うのが一般的です。
効率的な要素操作のための絞り込みテクニック
クラス名やタグ名だけでは、目的の要素をピンポイントで特定できないことが多々あります。
その場合、親要素を取得してからその内部を検索するという二段階のステップを踏むことで、精度を劇的に向上させることができます。
範囲を限定して検索する
例えば、特定のニュースリスト (class=”news-list”) の中にあるリンクだけを取得したい場合を考えます。
# まず親要素(リスト全体)を特定
news_container = driver.find_element(By.CLASS_NAME, "news-list")
# その親要素の中からaタグを探す
news_links = news_container.find_elements(By.TAG_NAME, "a")
for news in news_links:
print(news.text)
この手法を使えば、ページ下部にある不要なナビゲーションリンクなどを排除し、必要なデータだけを正確に取得できます。
これはスクレイピングにおいて非常に 堅牢なコード を書くための重要なテクニックです。
動的な要素取得と待機処理の重要性
現代のウェブサイトはJavaScriptを使用して非同期にコンテンツを読み込むため、プログラムが実行された瞬間に目的の要素がまだ画面上に存在しないことがあります。
このとき、単に find_element を実行すると、要素が見つからずエラーでプログラムが停止してしまいます。
そこで重要になるのが 「明示的な待機 (Explicit Wait)」 です。
WebDriverWaitを利用した安定化
特定のクラス名が表示されるまで最大10秒間待機するコード例は以下の通りです。
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 要素が表示されるまで待機
wait = WebDriverWait(driver, 10)
element = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "dynamic-content")))
print("要素が正常に読み込まれました:", element.text)
単に time.sleep() で固定時間を待つのではなく、要素が出現した瞬間に次の処理へ進むため、実行速度と安定性を両立させることができます。
実務レベルのスクリプトでは、この待機処理を入れることが推奨されます。
class名・タグ名取得時のよくあるトラブルと解決策
要素が取得できない原因はいくつか考えられます。
以下のチェックリストを確認して、デバッグに役立ててください。
1. 属性値が動的に変化している
一部のフレームワーク (ReactやVueなど) では、ビルドのたびにクラス名にランダムな文字列が付与されることがあります (例: Button__sc-1abc123)。
このような場合は、クラス名の一部だけを前方一致で検索するか、タグ名と他の属性を組み合わせる必要があります。
2. iframeの中に要素がある
広告や特定のウィジェットは iframe タグで囲まれていることがあります。
この場合、メインのHTMLからは class名を指定しても見つけることができません。
一度 driver.switch_to.frame() を使ってフレーム内に切り替える必要があります。
3. 要素が非表示になっている
画面上には存在するが、スクロールしないと表示されない、あるいはCSSで display: none になっている要素は、通常の操作ができないことがあります。
この場合は、JavaScriptを実行してスクロールするか、要素の表示状態を確認してください。
クラス名・タグ名を活用した実践的なデータ収集例
最後に、クラス名とタグ名を組み合わせて、表 (table) からデータを抽出する具体的なコード例を紹介します。
# テーブル要素をクラス名で取得
table = driver.find_element(By.CLASS_NAME, "data-table")
# テーブル内のすべての行 (tr) を取得
rows = table.find_elements(By.TAG_NAME, "tr")
for row in rows:
# 各行の中にあるセル (td) を取得
cols = row.find_elements(By.TAG_NAME, "td")
if cols:
# 1列目と2列目のテキストを表示
print(f"項目: {cols[0].text} | 値: {cols[1].text}")
項目: ユーザー数 | 値: 1,200名
項目: 更新日時 | 値: 2026/05/20
項目: ステータス | 値: 正常
このように、「大きな枠組みをクラス名で捉え、内部の構造をタグ名で走査する」 という使い分けが、最も効率的でエラーの少ない実装方法となります。
まとめ
PythonとSeleniumを組み合わせたブラウザ操作において、class名とタグ名による要素取得は基本中の基本でありながら、非常に奥が深い技術です。
本記事で解説した以下のポイントを意識することで、より安定したスクリプトを作成できるようになります。
- By.CLASS_NAME ではスペースを含む複合クラスを直接指定しない。
- By.TAG_NAME はリストやテーブルなどの構造解析に活用する。
- 目的の要素が取得できない場合は、親要素からの絞り込みや明示的な待機を検討する。
- 複数の要素を扱うときは
find_elementsを使用し、リストとして処理する。
適切なセレクター選びは、自動化プログラムの「壊れにくさ」に直結します。
対象サイトのHTML構造を丁寧に観察し、今回紹介した手法を組み合わせて、最適な要素取得を目指してください。
まずはシンプルなサイトでクラス名指定の練習から始め、徐々に複雑な構造の解析に挑戦してみることをお勧めします。
