Pythonを使用したWebブラウザの自動操作において、目的のボタンをクリックしたり、入力フォームにテキストを入力したりするためには、操作対象となるHTML要素を正確に特定する必要があります。
この「要素の特定」において中核的な役割を担うのが、SeleniumのByクラスです。
かつてのSeleniumではメソッドごとに検索手法が分かれていましたが、現在のバージョン(Selenium 4以降)では、このByクラスを用いた指定方法が標準となっています。
効率的で壊れにくい自動化スクリプトを作成するためには、Byクラスが提供するさまざまなロケータ(検索戦略)を理解し、状況に応じて最適なものを選択するスキルが欠かせません。
本記事では、Byクラスの基本的な使い方から、実務で役立つ応用的なテクニックまで詳しく解説します。
SeleniumにおけるByクラスの役割と基本概念
SeleniumにおけるByクラスとは、HTMLドキュメント内から要素を検索するための「戦略」を定義するためのクラスです。
WebページはHTML、CSS、JavaScriptで構成されており、無数のタグが階層構造を成しています。
その中から「どの属性を使って要素を探すか」をブラウザに伝えるのがByクラスの役割です。
なぜByクラスが必要なのか
以前のSelenium(バージョン3以前)では、find_element_by_idやfind_element_by_nameといった、検索手法ごとに個別のメソッドが用意されていました。
しかし、これらのメソッドは現在非推奨(Deprecated)となっており、最新のSeleniumではfind_element()という共通のメソッドにByクラスの引数を渡す形式に統一されています。
この変更により、コードの可読性が向上し、検索手法を動的に変更するようなプログラムが書きやすくなりました。
また、IDE(統合開発環境)の補完機能も活用しやすくなり、開発効率の向上にも寄与しています。
Byクラスを利用するための事前準備
Byクラスを使用するには、まずSeleniumライブラリから適切にインポートを行う必要があります。
また、ブラウザを操作するためのWebDriverも準備しておきましょう。
ライブラリのインポート
Pythonスクリプトの冒頭で、以下のモジュールをインポートします。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import Byという記述が、Byクラスを使用するために最も重要な部分です。
これを行わないと、検索時にエラーが発生します。
基本的な実行環境の構築
2026年現在のモダンな記述方法では、webdriver-managerを利用してドライバを自動管理するのが一般的です。
# WebDriverのセットアップ
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
# ターゲットサイトへ移動
driver.get("https://example.com")
要素の検索に使用する主なメソッド
Byクラスは、WebDriverオブジェクトの2つの主要な検索メソッドと一緒に使用されます。
それぞれの違いを正しく理解しておくことが重要です。
find_elementメソッド
find_element()は、条件に一致する要素を1つだけ返します。
# By.IDを使用して要素を取得
element = driver.find_element(By.ID, "submit-button")
element.click()
もし条件に一致する要素がページ内に複数存在する場合、HTMLの上から順に探して最初に見つかった要素が返されます。
要素が見つからない場合は、NoSuchElementExceptionというエラーが発生し、プログラムの実行が停止します。
find_elementsメソッド
find_elements()は、条件に一致するすべての要素をリスト形式で返します。
# By.CLASS_NAMEを使用して複数の要素を取得
items = driver.find_elements(By.CLASS_NAME, "product-item")
for item in items:
print(item.text)
このメソッドの特徴は、要素が見つからなくてもエラーにならない点です。
条件に合う要素がない場合は空のリスト [] を返します。
特定の要素が存在するかどうかのチェック(存在確認)を行いたい場合にも非常に有用です。
Byクラスで指定できる8つの検索ロケータ
Byクラスには、要素を特定するための8つの戦略が用意されています。
それぞれの特徴と使い分けを見ていきましょう。
| ロケータ名 | 説明 | 推奨されるケース |
|---|---|---|
By.ID | id属性で検索 | 最優先で使用すべき(高速・一意) |
By.NAME | name属性で検索 | フォーム入力項目など |
By.CLASS_NAME | class属性で検索 | デザイン共通の要素グループ |
By.TAG_NAME | HTMLタグ名で検索 | リンク一覧や表の行の取得など |
By.LINK_TEXT | aタグのテキストで検索 | 固定の文言を持つリンク |
By.PARTIAL_LINK_TEXT | aタグのテキスト部分一致 | 長いリンクテキストの一部指定 |
By.CSS_SELECTOR | CSSセレクタで検索 | IDがない場合や複雑な構造の指定 |
By.XPATH | XPath式で検索 | 構造が複雑な場合や親要素への遡り |
By.ID: 要素固有の識別子で検索
HTMLのid属性は、ページ内で重複しないことがルールとなっています。
そのため、最も確実かつ高速に要素を特定できる手法です。
# id="login_email" という要素を検索
email_field = driver.find_element(By.ID, "login_email")
By.NAME: name属性で検索
主に<input>や<form>タグなどのフォーム関連要素で使用されます。
サーバーにデータを送信する際の識別子として利用されるため、比較的安定したロケータです。
# name="query" という検索ボックスを取得
search_box = driver.find_element(By.NAME, "query")
By.CLASS_NAME: CSSクラス名で検索
デザインを適用するためのclass属性を使って検索します。
複数の要素に同じクラスが割り当てられていることが多いため、find_elementsと組み合わせてリストを取得する際によく使われます。
# class="nav-link" を持つ要素をすべて取得
nav_links = driver.find_elements(By.CLASS_NAME, "nav-link")
By.TAG_NAME: HTMLタグ名で検索
h1, div, table などのタグ名そのもので検索します。
単独で特定の要素を狙い撃ちにするのは難しいですが、特定の親要素の中にある子要素をリストアップする際に便利です。
# ページ内のすべてのリンク(aタグ)を取得
all_links = driver.find_elements(By.TAG_NAME, "a")
By.LINK_TEXT: リンクの完全一致テキストで検索
アンカータグ(aタグ)のテキスト部分を指定して検索します。
ユーザーが見ている画面上の文字で指定できるため、直感的です。
# 「お問い合わせはこちら」というテキストのリンクをクリック
contact_link = driver.find_element(By.LINK_TEXT, "お問い合わせはこちら")
By.PARTIAL_LINK_TEXT: リンクの一部テキストで検索
リンクテキストの一部が含まれていればマッチします。
動的に日付が含まれるリンクや、非常に長いテキストのリンクを扱う場合に重宝します。
# 「2026年度 報告書」などの一部を指定
report_link = driver.find_element(By.PARTIAL_LINK_TEXT, "報告書")
By.CSS_SELECTOR: CSSセレクタで柔軟に検索
CSSセレクタは、フロントエンド開発者がスタイルを適用する際に使用する記法です。
非常に柔軟で、IDやクラス、属性、階層構造を組み合わせて指定できます。
# divタグ配下のclass="active"な要素を取得
active_item = driver.find_element(By.CSS_SELECTOR, "div.container > ul > li.active")
By.XPATH: 強力なパス式で検索
XPathはXMLドキュメント内を検索するための言語です。
HTMLの構造をツリーとして捉え、複雑な条件(「特定のテキストを持つ要素の隣のボタン」など)を指定できます。
# テキストに「削除」を含むボタンの親要素を辿って特定のdivを探す
delete_div = driver.find_element(By.XPATH, "//button[contains(text(), '削除')]/parent::div")
2026年のモダンな開発におけるロケータの選び方
どのロケータを使うべきか迷った際は、以下の優先順位に従うことをお勧めします。
これは自動テストの「保守性」と「実行速度」を両立させるためのベストプラクティスです。
優先順位の考え方
- By.ID : あれば必ず使う。最も高速で重複の恐れがない。
- By.CSS_SELECTOR : IDがない場合、または複数の属性を組み合わせたい場合に最適。
- By.NAME : フォーム操作であれば有効。
- By.XPATH : 上記で対応できない複雑な構造や、テキスト内容を基準に要素を探したい場合のみ使用。
注意点:
絶対パスによるXPath(例: /html/body/div[1]/div[2]/ul/li[5]/a)は避けるべきです。
Webページの構造が少し変わるだけで動作しなくなるため、壊れやすいスクリプトの原因になります。
テストの保守性を高めるために
Webアプリケーションのアップデートにより、HTMLの構造やクラス名は頻繁に変更されます。
これに対処するため、近年ではテスト用の専用属性(例: data-testid="login-btn")を開発段階で埋め込み、それをBy.CSS_SELECTORで指定する手法が推奨されています。
# 開発者が付与したテスト専用IDで検索
login_button = driver.find_element(By.CSS_SELECTOR, "[data-testid='login-btn']")
Byクラスと待機処理(Explicit Wait)の組み合わせ
ブラウザの自動操作において、要素が表示される前に検索を試みて失敗するケースは非常に多いです。
Byクラスは、Explicit Wait(明示的な待機)と組み合わせることで真価を発揮します。
WebDriverWaitの利用例
単にfind_elementを呼び出すのではなく、要素が「クリック可能になるまで」や「画面に現れるまで」待機するように記述します。
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 最大10秒間、要素が現れるのを待つ
wait = WebDriverWait(driver, 10)
element = wait.until(EC.presence_of_element_located((By.ID, "dynamic-content")))
print("要素が見つかりました:", element.text)
ここで注目すべきは、EC.presence_of_element_located((By.ID, "dynamic-content"))の部分です。
Byクラスの情報をタプル形式 (By.XXX, "値") で渡すのがルールとなっています。
これにより、ネットワーク遅延や非同期処理(Ajaxなど)に強い堅牢なコードを作成できます。
よくあるエラーと対処法
Byクラスを使用して要素を検索する際、初心者が直面しやすい問題がいくつかあります。
1. NoSuchElementException
指定したロケータで見つからない場合に発生します。
- 原因: タイポ(打ち間違い)、要素がまだ読み込まれていない、またはiframeの中にある。
- 対策: 明示的な待機を使うか、
driver.switch_to.frame()でフレームを切り替えます。
2. InvalidSelectorException
XPathやCSSセレクタの構文が間違っている場合に発生します。
- 原因: カッコの閉じ忘れや、不正な文字の使用。
- 対策: ブラウザのデベロッパーツール(F12キー)の「Console」や「Elements」タブで、そのセレクタが正しく動作するか事前に検証してください。
3. ElementNotInteractableException
要素は見つかっているが、非表示だったり、他の要素に隠れていたりして操作できない場合に発生します。
- 原因: スクロールしないと見えない位置にある、またはオーバーレイ広告などが被っている。
- 対策:
element.location_once_scrolled_into_viewでスクロールさせるか、JavaScript経由でクリックを実行します。
まとめ
Python SeleniumにおけるByクラスは、Webオートメーションの精度と保守性を決定づける非常に重要な要素です。
本記事で紹介した8つのロケータを適切に使い分けることで、どのようなWebサイトに対しても柔軟にアプローチできるようになります。
特に、IDを優先しつつ、複雑な構造にはCSSセレクタやXPathを駆使するという戦略は、実務において不可欠なスキルです。
また、単に要素を探すだけでなく、WebDriverWaitと組み合わせて待機処理を適切に行うことが、安定したスクリプトを作成するための第一歩となります。
今回学んだByクラスの使い方を基礎として、より高度なスクレイピングやテスト自動化に挑戦してみてください。
自動化の鍵は、「正確な要素特定」にあります。
Byクラスをマスターして、効率的でストレスのない開発を実現しましょう。
