
Seleniumは、Webブラウザを自動操作するためのツールで、主にブラウザの自動テストに使用されます。指定したスクリプトに従って、クリックやテキスト入力などの操作を自動化することで、テスト作業を効率化できます。これにより、コストを抑えつつテストの実行頻度を増やし、バグの早期発見に役立ちます。特に、チーム開発において各メンバーが統一されたテストを実施することで、不具合の原因の切り分けを容易にし、安定した開発プロセスを確立できます。また、単調なテスト作業を自動化することで、モチベーションの低下を防ぐ効果もあります。
さらに、SeleniumはWebスクレイピングにも活用されています。近年のウェブサイトではJavascriptを用いた動的なコンテンツ生成が増えており、通常のHTML取得では必要な情報を取得できないことがあります。Seleniumを使うことで、実際にブラウザを操作し、ページが完全に表示された状態のHTMLを取得することができ、必要な情報を収集できる可能性が高まります。
本記事では、Pythonでブラウザを自動するためのSeleniumの基本的な使用方法について、ご紹介いたします。
本記事で使用した環境は以下になります。
・ Windows 11
・ Python 3.13.0
・ selenium 4.29.0
・ webdriver-manager 4.0.2
目次
- Seleniumの概要
- Seleniumの環境構築
- テスト用のHTMLファイル
- ブラウザを開く方法
- 要素を探索する方法
- 要素を操作する方法
- 待機処理
- ページ遷移
- HTMLの取得
- インラインフレームとShadow DOMの操作
- まとめ
Seleniumの概要
Seleniumは、Webアプリケーションの画面操作を自動化するためのツールです。クリックやキー入力などブラウザに対するさまざまな操作を行うことができます。SeleniumはApachi License 2.0で提供されており、だれでも無料で使用することができます。また、さまざまなOSやブラウザに対応しています。対応しているOSやブラウザの主なものを以下に示します。
項目 | 対応状況 |
---|---|
対応しているブラウザ | Google Chrome Mozilla Firefox Microsoft Edge Safari(macOS専用) Opera |
動作するOS | Windows MacOS X Linux iOS Android |
対応しているプログラミング言語 | Java JavaScript Python Ruby C# |
Selenium単体ではブラウザを操作することはできず、各ブラウザごとに専用のWebDriverが必要になります。WebdriverはSeleniumのスクリプトとブラウザの間で仲介の役割をはたします。Seleniumのコードをブラウザの操作に変換し、ブラウザを開く、操作する、閉じるなどの指示を実行します。
Seleniumの環境構築
本記事では、PythonによりSeleniumを使用します。そのために、次のパッケージをインストールします。
pip install selenium
pip install webdriver-manager
ここで、webdriver-mangaer
は、SeleniumでWebDriverを自動でインストール・管理するためのPythonのパッケージです。
通常、Seleniumを使うには手動でWebDriverをダウンロードしてパスを設定する必要がありますが、webdriver-managerを使えば、バージョン管理を自動化できるので手間が省けます。
項目 | 通常のWebDriver | webdriver-mangaer |
---|---|---|
WebDriverのダウンロード | 手動 | 自動 |
バージョン管理 | 手動で確認 | 自動で最新バージョンを取得 |
OS対応 | 自分で対応版を取得 | OSに応じて適切なバージョンを取得 |
コードの簡潔さ | 設定が面倒 | 1行でセットアップ可能 |
テスト用のHTMLファイル
Seleniumの機能をテストするために次のHTMLファイルを使用します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Selenium テストページ</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.container { width: 600px; margin: 0 auto; }
.hidden { display: none; }
.fade-in { opacity: 0; transition: opacity 1s; }
.fade-in.visible { opacity: 1; }
iframe { width: 100%; height: 120px; border: 1px solid black; }
.shadow-container { margin-top: 20px; }
.long-page { height: 1200px; background: linear-gradient(to bottom, white, lightgray); }
.drop-zone { width: 100%; height: 50px; border: 2px dashed gray; display: flex; align-items: center; justify-content: center; margin-top: 10px; }
</style>
</head>
<body>
<div class="container">
<h1>Seleniumテストページ</h1>
<!-- 基本フォーム -->
<h2>ユーザーリスト</h2>
<label>名前: <input type="text" id="name" value="Anonymous"></label></br>
</br>
<!-- チェックボックス -->
<label><input type="checkbox" id="agree"> 規約に同意する</label>
<!-- ラジオボタン -->
<label>性別:</label>
<label><input type="radio" name="gender" value="male"> 男性</label>
<label><input type="radio" name="gender" value="female"> 女性</label>
<!-- ドロップダウン -->
<label for="country">国を選択:</label>
<select id="country">
<option value="jp">日本</option>
<option value="us">アメリカ</option>
<option value="uk">イギリス</option>
</select>
<!-- JavaScriptで新規要素追加 -->
<br><br>
<button id="add_user">新しいユーザーを追加</button>
<br><br>
<!-- テーブル -->
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>名前</th>
<th>性別</th>
<th>国籍</th>
<th>アクション</th>
</tr>
</thead>
<tbody id="user_table">
<tr>
<td>1</td>
<td>田中太郎</td>
<td>男性</td>
<td>日本</td>
<td></td>
</tr>
<tr>
<td>2</td>
<td>山田花子</td>
<td>女性</td>
<td>日本</td>
<td></td>
</tr>
</tbody>
</table>
<!-- 動的なリスト(掲示板シミュレーション) -->
<h2>掲示板(動的要素)</h2>
<ul id="post_list"></ul>
<button id="add_post">新しい投稿を追加</button>
<!-- アラートダイアログ -->
<button id="alert_button">アラートを表示</button>
<!-- 10秒後に表示されるボタン -->
<button id="delayed_button" class="hidden">遅延ボタン</button>
<!-- AJAXデータ取得(JSON風) -->
<button id="ajax_button">AJAXデータを取得</button>
<pre id="ajax_result" class="hidden"></pre>
<!-- iFrame 内のフォーム -->
<h2>iFrame 内のフォーム</h2>
<iframe id="test_frame" srcdoc="
<form id='iframe_form'>
<label id='iframe_label'>メッセージ: <input type='text' id='iframe_message'></label>
<button type='submit' id='iframe_submit'>送信</button>
</form>
<script>
document.getElementById('iframe_form').addEventListener('submit', function(event) {
event.preventDefault();
let message = document.getElementById('iframe_message').value.trim();
let parentDocument = window.parent.document;
let outputElement = parentDocument.getElementById('iframe_output');
if (message) {
outputElement.textContent = `送信されたメッセージ: ${message}`;
} else {
outputElement.textContent = '⚠️ メッセージを入力してください!';
}
});
</script>
"></iframe>
<p id="iframe_output" style="margin-top: 10px; font-weight: bold;"></p>
<!-- Shadow DOM -->
<h2>Shadow DOM</h2>
<div class="shadow-container"></div>
<p id="shadow_output" style="margin-top: 10px; font-weight: bold;"></p>
<!-- ページスクロール -->
<h2 class="long-page">スクロールして一番下へ</h2>
<button id="scroll_button">ここをクリック</button>
<!-- 新しいタブを開く -->
<button id="new_tab">新しいタブを開く</button>
<!-- ファイルアップロード -->
<h2>ファイルアップロード</h2>
<input type="file" id="file_upload">
<!-- ドラッグ&ドロップ -->
<h2>ドラッグ&ドロップ</h2>
<div class="drop-zone" id="drop_zone">ここにドラッグ&ドロップ</div>
<!-- aを使用した要素-->
<br><br>
<a href="https://www.google.com">Googleに移動</a>
<br><br>
<input id="test_input" type="text" placeholder="テスト入力">
<button id="test_button" disabled>無効なボタン</button>
</div>
<script>
// ✅ 新しいユーザーを追加
let userIdCounter = 3;
document.getElementById("add_user").addEventListener("click", function() {
let name = document.getElementById("name").value.trim();
let gender = document.querySelector('input[name="gender"]:checked');
let country = document.getElementById("country").value;
let agree = document.getElementById("agree").checked;
if (!agree) {
alert("⚠️ 規約に同意する必要があります!");
return;
}
if (!name || !gender) {
alert("⚠️ 名前と性別を入力してください!");
return;
}
let table = document.getElementById("user_table");
let newRow = table.insertRow();
newRow.insertCell(0).textContent = userIdCounter++;
newRow.insertCell(1).textContent = name;
newRow.insertCell(2).textContent = gender.value === "male" ? "男性" : "女性";
newRow.insertCell(3).textContent = country === "jp" ? "日本" : country === "us" ? "アメリカ" : "イギリス";
let deleteCell = newRow.insertCell(4);
let deleteBtn = document.createElement("button");
deleteBtn.textContent = "削除";
deleteBtn.classList.add("delete_btn");
deleteBtn.addEventListener("click", function() {
table.deleteRow(newRow.rowIndex - 1);
});
deleteCell.appendChild(deleteBtn);
});
// ✅ アラートボタン
document.getElementById("alert_button").addEventListener("click", function() {
alert("これはアラートメッセージです!");
});
// ✅ AJAXデータ取得(JSON風)
document.getElementById("ajax_button").addEventListener("click", function() {
setTimeout(() => {
document.getElementById("ajax_result").classList.remove("hidden");
// ✅ 現在の日時を取得
let now = new Date();
let formattedDate = `${now.getFullYear()}年${now.getMonth() + 1}月${now.getDate()}日 ${now.getHours()}時${now.getMinutes()}分${now.getSeconds()}秒`;
// ✅ 表示内容を更新
document.getElementById("ajax_result").textContent = JSON.stringify(
{ message: "データ取得成功", timestamp: formattedDate },
null, 2
);
}, 2000);
});
// ✅ 掲示板の投稿を動的に追加
document.getElementById("add_post").addEventListener("click", function() {
let postList = document.getElementById("post_list");
let newPost = document.createElement("li");
newPost.textContent = "新しい投稿 " + (postList.children.length + 1);
postList.appendChild(newPost);
});
// ✅ Shadow DOMの追加
let shadowContainer = document.querySelector(".shadow-container");
let shadowRoot = shadowContainer.attachShadow({mode: 'open'});
let shadowButton = document.createElement("button");
shadowButton.textContent = "Shadow DOMのボタン";
shadowButton.id = "shadow_button";
shadowRoot.appendChild(shadowButton);
// Shadow DOM 内のボタンのクリックイベント
shadowButton.addEventListener("click", function() {
let outputElement = document.getElementById("shadow_output");
outputElement.textContent = "✅ Shadow DOM のボタンが押されました!";
});
// ✅ 10秒後に遅延ボタンを表示
setTimeout(() => {
document.getElementById("delayed_button").classList.remove("hidden");
}, 10000);
// ✅ 遅延ボタン
document.getElementById("delayed_button").addEventListener("click", function() {
alert("✅ 遅延ボタンが押されました!");
});
// ✅ 一番下までスクロールする
document.getElementById("scroll_button").addEventListener("click", function() {
window.scrollTo({
top: document.body.scrollHeight, // ページの最下部に移動
behavior: "smooth" // スムーズスクロール
});
});
// ✅ 新しいタブを開く
document.getElementById("new_tab").addEventListener("click", function() {
window.open("https://www.google.com", "_blank");
});
// ✅ ドロップ&ドラッグ
document.addEventListener("DOMContentLoaded", function() {
let dropZone = document.getElementById("drop_zone");
// ドラッグしている間、スタイルを変更
dropZone.addEventListener("dragover", function(event) {
event.preventDefault(); // デフォルトの動作を防ぐ
dropZone.style.backgroundColor = "#e0e0e0"; // 背景色を変更
});
// ドラッグがエリア外に出たら元のスタイルに戻す
dropZone.addEventListener("dragleave", function() {
dropZone.style.backgroundColor = "";
});
// ファイルがドロップされたときの処理
dropZone.addEventListener("drop", function(event) {
event.preventDefault(); // デフォルトの動作を防ぐ
dropZone.style.backgroundColor = ""; // 背景色を元に戻す
// ドロップされたファイルのリストを取得
let files = event.dataTransfer.files;
if (files.length > 0) {
dropZone.textContent = `✅ ${files[0].name} がドロップされました!`;
} else {
dropZone.textContent = "⚠️ ファイルをドロップしてください!";
}
});
});
</script>
</body>
</html>
メモ帳などのエディタに上記の内容をコピーします。そして、名前を付けて保存で拡張子をhtmlにして保存します(たとえば、sample.html
など)。そのファイルをクリックしてブラウザで開くと、次のようなページが表示されます。いろいろな機能を試せるように、基本的な要素(テキスト、チェックボックスなど)の他に、Javascriptを使用してボタンやアラート、AJAX、iFrame、Shadow DOM、スクロールなどの要素を入れています。
ブラウザを開く方法
Seleniumでは、対応するWebDriverを使ってブラウザを開きます。ここでは、各ブラウザを開いて数秒待機した後に、ブラウザを閉じるコードを示します。ブラウザを開くにはget
メソッドを使用します。
状況 | get メソッドの引数 |
---|---|
ローカルファイルを開く | file://HTMLファイルの絶対パス (絶対パスは os.path.abspath を使用するとOSによらず同じコードを使用できる) |
インターネット上のホームページを開く | ホームページのアドレス (例えば、googleの場合はhttps://google.comを設定) |
ブラウザを開く方法には、GUIを立ち上げる通常モードとGUIを立ち上げずにバックグラウンドで起動するヘッドレスモードがあります。
通常モード
Chrome(ChromeDriverManager)の場合は以下になります。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import os, time
# Chromeのドライバを起動
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
# テスト用HTMLファイルを開く
driver.get("file://" + os.path.abspath("sample.html"))
# 10秒間待つ
time.sleep(10)
# ブラウザを閉じる
driver.quit()
Firefox(GeckoDriver)の場合は以下になります。
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from webdriver_manager.firefox import GeckoDriverManager
import os, time
# Firefoxのドライバを起動
driver = webdriver.Firefox(service=Service(GeckoDriverManager().install()))
# テスト用HTMLファイルを開く
driver.get("file://" + os.path.abspath("sample.html"))
# 10秒間待つ
time.sleep(10)
# ブラウザを閉じる
driver.quit()
Edge(EdgeChromiumDriverManager)の場合は以下になります。
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from webdriver_manager.microsoft import EdgeChromiumDriverManager
import os, time
# Edgeのドライバを起動
driver = webdriver.Edge(service=Service(EdgeChromiumDriverManager().install()))
# テスト用HTMLファイルを開く
driver.get("file://" + os.path.abspath("sample.html"))
# 10秒間待つ
time.sleep(10)
# ブラウザを閉じる
driver.quit()
SafariをSeleniumで使う場合には、事前にWebDriverを有効化する必要があります。シェル上で次のコマンドを実行します。
safaridriver --enable
Pythonコードは以下となります。
from selenium import webdriver
import os, time
# Safariのドライバを起動
driver = webdriver.Safari()
# テスト用HTMLファイルを開く
driver.get("file://" + os.path.abspath("sample.html"))
# 10秒間待つ
time.sleep(10)
# ブラウザを閉じる
driver.quit()
これらのコードを実行すると、ブラウザが実際に開いて処理が行われます。
なお、ドライバは一度インストールするとキャッシュされるため、二回目以降はservice
オプションを削除しても動作します。インストール回数が多い場合はインストール回数の制限にかかる場合があるので、そのときは削除しましょう。
ヘッドレスモードで起動
ブラウザを開かずにバックグラウンドで操作する場合はヘッドレスモードを使います。ヘッドレスモードはSafariには公式では非対応です。
Chromeの場合を示します。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options # 追加
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import os
# Chromeオプションを設定
options = Options()
options.add_argument("--headless") # ヘッドレスモードを有効化
options.add_argument(
"--disable-gpu"
) # 必要に応じてGPU無効化(Windows対策、Chromeのみ)
# Chromeのドライバを起動
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()), options=options
)
# テスト用HTMLファイルを開く
driver.get("file://" + os.path.abspath("sample.html"))
# ページのタイトルを取得
print(driver.title)
# ブラウザを閉じる
driver.quit()
Firefoxの場合を示します。
from selenium import webdriver
from selenium.webdriver.firefox.options import Options # 追加
from selenium.webdriver.firefox.service import Service
from webdriver_manager.firefox import GeckoDriverManager
import os
# Firefoxオプションを設定
options = Options()
options.add_argument("--headless")
# Firefoxのドライバを起動
driver = webdriver.Firefox(
service=Service(GeckoDriverManager().install()), options=options
)
# テスト用HTMLファイルを開く
driver.get("file://" + os.path.abspath("sample.html"))
# ページのタイトルを取得
print(driver.title)
# ブラウザを閉じる
driver.quit()
Edgeの場合を示します。
from selenium import webdriver
from selenium.webdriver.edge.options import Options # 追加
from selenium.webdriver.edge.service import Service
from webdriver_manager.microsoft import EdgeChromiumDriverManager
import os
# Edgeオプションの設定
options = Options()
options.add_argument("--headless")
# Edgeのドライバを起動
driver = webdriver.Edge(
service=Service(EdgeChromiumDriverManager().install()), options=options
)
# テスト用HTMLファイルを開く
driver.get("file://" + os.path.abspath("sample.html"))
# ページのタイトルを取得
print(driver.title)
# ブラウザを閉じる
driver.quit()
Safariのヘッドレスモードは公式には非対応になっています。
なお、ドライバは一度インストールするとキャッシュされるため、二回目以降はservice
オプションを削除しても動作します。インストール回数が多い場合はインストール回数の制限にかかる場合がありますので、そのときは削除しましょう。
ヘッドレスモードでは画面が見えないので、スクリーンショットを撮って確認します。これを活用すると、ヘッドレスモードで動作中のページの状態を確認できます。
driver.save_screenshot("screenshot.png")
オプションの設定
add_argument
で設定するオプションには次のものがあります。必要に応じて設定しましょう。
オプション | 説明 | プラウザ |
---|---|---|
--headless | ヘッドレスモードを有効化(GUIなし) | Chrome/Firefox/Edge |
--window-size=1920,1080 | ウィンドウサイズを指定 | Chrome/Edge/Safari |
--width=1920 --height=1080 | ウィンドウサイズを指定 | Firefox |
--incognito / -private / --inprivate | シークレットモード(プライベートブラウジング) | --incognito(Chrome) -private (Firefox/Safari) --inprivate (Edge) |
--disable-extensions | 拡張機能を無効化 | Chrome/Firefox/Edge |
--ignore-certificate-errors | SSL証明書エラーを無視 | Chrome/Firefox/Edge/Safari |
--disable-gpu | Windowsの描画エラーを防ぐ | Chrome/Edge |
--start-maximized | ブラウザを起動時に最大化 | Chrome/Edge |
--user-agent="…" | カスタムUser-Agentを設定 | Chrome/Firefox/Edge/Safari |
--disable-dev-shm-usage | ディスクのメモリスペースを使う。Linuxで/dev/shm の制限を回避するために、代わりに/tmp を使う。 | Chrome |
--mute-audio | オーディオをミュート | Chrome/Edge |
--no-sandbox | Chromeの保護機能を無効(Linuxでのクラッシュ回避) | Chrome |
要素を探索する方法
ブラウザを開いた後は、操作を行う要素を決めます。Seleniumで要素を探索して取得する方法として、find_element
とfind_elements
があります。
メソッド | 戻り値 | 取得対象 | 要素が見つからない場合 |
---|---|---|---|
find_element(By,XXX, "値") | 単一の要素(WebElement ) | 最初に見つかった1つの要素のみ | エラー(NoSuchElementException )を発生 |
find_elements(By.XXX, "値") | リスト(list[WebElement] ) | 該当するすべての要素を取得 | 空のリスト([] )を返す |
By.XXX
はWebページの要素を検索するためのロケータ(検索方法)を指定するものです。ロケータを使用するために、次のクラスをインポートします。
from selenium.webdriver.common.by import By
要素を指定する際には、要素の種類や属性の有無に応じてロケータを選択することになりますが、画面構成が変更されたときに修正ができるだけ発生しないロケータを選ぶようにします。SeleniumのBy
クラスには、以下のような検索方法が用意されています。
ロケータ | 説明 | 使用例 |
---|---|---|
By.ID | id属性の値による指定 | find_element(By.ID, "search-box") |
By.NAME | name属性の値による指定 | find_element(By.NAME, "username") |
By.CLASS_NAME | クラス名による指定 | find_element(By.CLASS_NAME, "btn-primary") |
By.TAG_NAME | HTMLタグ名による指定 | find_element(By.TAG_NAME, "h1") |
By.LINK_TEXT | a要素のテキストによる指定 | find_element(By.LINK_TEXT, "ログイン") |
By.PARTIAL_LINK_TEXT | a要素のテキストの部分一致による指定 | find_element(By.PARTIAL_LINK_TEXT, "登録") |
By.CSS_SELECTOR | CSSセレクタ記法を使った指定 | find_element(By.CSS_SELECTOR, "div.container > p") |
By.XPATH | XPath記法を使った指定 | find_element(By.XPATH, "//input[@type='text']") |
By.ID
は一意の要素が取れるので最も安全な方法になります。また、複雑な検索やページ構造を考慮した検索を行う場合には、By.CSS_SELECTOR
やBy.XPATH
が役立ちます。find_element
で取得したWebElement
に対し、さらにfind_element
やfind_elements
メソッドを呼び出すと、最初に取得した要素の子孫要素から検索できます。
取得した要素の属性は、get_attiribute
で確認できます。
引数には"id
"や"class
"、"href
"、"value
"などの属性名を指定します。HTMLファイルの探索された要素の中に記述された、指定した属性が返されます。
get_attribute("属性名")
get_attribute()
で取得できる主な属性には以下のようなものがあります。
属性 | 取得できる値 | 例 |
---|---|---|
id | ID属性の値 | "search-box" |
class | クラス名 | "btn-primary large-button" |
name | name属性の値 | "username" |
value | <input> や <textarea> に入力された値 | "Selenium Python" |
href | <a> のリンク先 | "https://www.google.com" |
src | 画像のURL | "https://example.com/image.png" |
checked | チェックボックスが選択されているか | "true" または None |
selected | セレクトボックスが選択されているか | "true" または None |
disabled | ボタンなどが無効かどうか | "true" または None |
placeholder | 入力欄のプレースホルダー | "検索ワードを入力" |
type | 入力タイプ | "text" "password" "checkbox" |
要素の探索とその結果得られた要素の属性を取得するサンプルコードを示します(Chromeの場合)。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import os
# Chromeを起動し、ローカルのHTMLファイルを開く
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("file://" + os.path.abspath("sample.html")) # 実際のHTMLファイルのパスを指定
try:
print("=== By.XXX を使って要素を検索 ===")
# ✅ IDで要素を取得(名前入力欄)
print("ID:", driver.find_element(By.ID, "name").get_attribute("id"))
# ✅ NAMEで要素を取得(性別選択のラジオボタン)
print("NAME:", driver.find_element(By.NAME, "gender").get_attribute("name"))
# ✅ CLASS_NAMEで要素を取得(ページ全体のコンテナ)
print(
"CLASS_NAME:",
driver.find_element(By.CLASS_NAME, "container").get_attribute("class"),
)
# ✅ TAG_NAMEで要素を取得(ページの見出し)
print(
"TAG_NAME:", driver.find_element(By.TAG_NAME, "h1").text
) # 見出しのテキストを取得
# ✅ LINK_TEXTで要素を取得(Googleへのリンク)
print(
"LINK_TEXT:",
driver.find_element(By.LINK_TEXT, "Googleに移動").get_attribute("href"),
)
# ✅ PARTIAL_LINK_TEXTで部分一致検索(Googleを含むリンク)
print(
"PARTIAL_LINK_TEXT:",
driver.find_element(By.PARTIAL_LINK_TEXT, "Google").get_attribute("href"),
)
# ✅ CSS_SELECTORで要素を取得(名前入力欄)
print(
"CSS_SELECTOR:",
driver.find_element(By.CSS_SELECTOR, "input#name").get_attribute("id"),
)
# ✅ XPATHで要素を取得(名前入力欄)
print(
"XPATH:",
driver.find_element(By.XPATH, "//input[@id='name']").get_attribute("id"),
)
print("\n=== get_attribute() を使って要素の属性を取得 ===")
# ✅ 入力フォームの値を取得
input_element = driver.find_element(By.ID, "name")
print("value:", input_element.get_attribute("value")) # 初期値 "Anonymous"
print("type:", input_element.get_attribute("type")) # "text"(入力タイプ)
# ✅ チェックボックスの状態を取得(チェックされているか)
checkbox = driver.find_element(By.ID, "agree")
print(
"checked:", checkbox.get_attribute("checked")
) # チェックされていれば "true"、されていなければ None
# ✅ リンクの `href` を取得(リンク先URL)
link = driver.find_element(By.LINK_TEXT, "Googleに移動")
print("href:", link.get_attribute("href")) # "https://www.google.com"
print("\n=== ドロップダウンの選択状態を確認 ===")
# ✅ ドロップダウンメニューを取得(国選択)
dropdown = Select(driver.find_element(By.ID, "country"))
# ✅ 現在選択されている `option` を取得
selected_option = dropdown.first_selected_option
print("selected:", selected_option.text) # 初期状態では "日本"
# ✅ すべての選択肢の `selected` 状態を確認
options = driver.find_elements(By.XPATH, "//select[@id='country']/option")
for option in options:
print(
f"{option.text}: {option.get_attribute('selected')}"
) # 選択されているなら "true"
print("\n=== その他の属性を確認 ===")
# ✅ 無効化されたボタンの `disabled` を取得(ボタンが使えないか確認)
print(
"disabled:", driver.find_element(By.ID, "test_button").get_attribute("disabled")
) # "true"
# ✅ 入力フォームの `placeholder` を取得(ヒントテキスト)
print(
"placeholder:",
driver.find_element(By.ID, "test_input").get_attribute("placeholder"),
) # "テスト入力"
finally:
# **ブラウザを閉じる**
driver.quit()
実行すると、次の結果が得られます。
=== By.XXX を使って要素を検索 ===
ID: name
NAME: gender
CLASS_NAME: container
TAG_NAME: Seleniumテストページ
LINK_TEXT: https://www.google.com/
PARTIAL_LINK_TEXT: https://www.google.com/
CSS_SELECTOR: name
XPATH: name
=== get_attribute() を使って要素の属性を取得 ===
value: Anonymous
type: text
checked: None
href: https://www.google.com/
=== ドロップダウンの選択状態を確認 ===
selected: 日本
日本: true
アメリカ: None
イギリス: None
=== その他の属性を確認 ===
disabled: true
placeholder: テスト入力
要素を操作する方法
要素を探索した後は、その要素に対して操作を行います。
操作内容 | メソッド | 説明 |
---|---|---|
クリックする | WebElement.click() | ボタンやリンクをクリック |
テキストを入力する | WebElement.send_keys("入力内容") | 入力フィールドにテキストを入力 |
テキストをクリアする | WebElement.clear() | 入力フィールドのテキストを削除 |
フォームを送信する | WebElement.submit() | フォームを送信(<form> 内の要素で有効) |
ドロップダウンを選択する(値で選択) | Select(WebElement).select_by_value("値") | <select> の<option> のvalue の値から選択する |
ドロップダウンを選択する(表示テキストで選択) | Select(WebElement).select_by_visible_text("表示テキスト") | <select> の<option> の表示テキストで選択する |
ドロップダウンを選択する(インデックスで選択) | Select(WebElement).select_by_index(1) | <select> の<option> の順番で選択(0から開始) |
キーボード操作 | WebElement.send_keys(Key.XXXX) | キーボード操作をシミュレーション |
クリック操作
クリックできる要素としてボタン、チェックボックス、ラジオボタン、リンクなどがあります。click
の使用例を示します。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import os, time
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("file://" + os.path.abspath("sample.html")) # ローカルHTMLのパスを指定
# ボタンのクリック
driver.find_element(By.ID, "alert_button").click() # アラートボタンをクリック
time.sleep(3)
driver.switch_to.alert.accept() # アラートを閉じる
# チェックボックスのクリック
checkbox = driver.find_element(By.ID, "agree")
checkbox.click() # チェックを入れる
print("チェック状態:", checkbox.get_attribute("checked")) # "true" or None
time.sleep(3)
# ラジオボタンのクリック(男性を選択)
driver.find_element(By.XPATH, "//input[@name='gender'][@value='male']").click()
time.sleep(3)
# リンクをクリック
driver.find_element(By.LINK_TEXT, "Googleに移動").click()
time.sleep(3)
driver.quit()
テキストの入力とクリア
次に、テキストボックスとファイルアップロード(実際にインターネット上にアップロードするわけではありません)を例として、send_keys()
とclear()
の使用例を示します。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import os, time
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("file://" + os.path.abspath("sample.html")) # ローカルHTMLのパスを指定
# テキストボックスに入力
text_box = driver.find_element(By.ID, "name")
text_box.clear()
text_box.send_keys("テストユーザー")
print("入力された値:", text_box.get_attribute("value")) # "テストユーザー"
time.sleep(3)
# ファイルアップロード
file_input = driver.find_element(By.ID, "file_upload")
file_input.send_keys(os.path.abspath("sample.html")) # ファイルをアップロード
# 一番したまでスクロール(ファイルアップロードの確認)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(3)
driver.quit()
リストの選択
ドロップダウンリストの選択を行う方法として、select_by_value
, select_by_visible_text()
, select_by_index()
の使用例を示します。
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.support.ui import Select
import os, time
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("file://" + os.path.abspath("sample.html")) # ローカルHTMLのパスを指定
dropdown = Select(driver.find_element(By.ID, "country"))
# `select_by_value()`
dropdown.select_by_value("us") # "アメリカ" を選択
print("選択された国:", dropdown.first_selected_option.text) # "アメリカ"
# `select_by_visible_text()`
dropdown.select_by_visible_text("イギリス") # "イギリス" を選択
print("選択された国:", dropdown.first_selected_option.text) # "イギリス"
# `select_by_index()`
dropdown.select_by_index(0) # インデックス0(日本)を選択
print("選択された国:", dropdown.first_selected_option.text) # "日本"
driver.quit()
キーボード操作
Seleniumでは、キーボード操作もシミュレーションできます。テキストを入力する場合と同様にsend_keys()
を使用します。
引数で指定できるキーの一覧を以下に示します。
操作内容 | Keys | 備考 |
---|---|---|
Enterキーを押す | Keys.ENTER | 検索ボックスやフォームの送信など |
テキストの選択 | Keys.CONTROL, "a" | 全選択のショートカットキー(CTRL+a ) |
コピー | Keys.CONTROL, "c" | コピーのショートカットキー(CTRL+c ) |
ペースト | Keys.CONTROL, "v" | 貼り付けのショートカットキー(CTRL+v ) |
カット | Keys.CONTROL, "x" | 切り取りのショートカットキー(CTRL+x ) |
バックスペース(1文字削除) | Keys.BACKSPACE | カーソルの直前の文字を削除 |
デリート(1文字削除) | Keys.DELETE | カーソルの直後の文字を削除 |
矢印キー(移動) | Keys.ARROW_LEFT Keys.ARROW_RIGHT | 左・右にカーソルを移動 |
Shift + 矢印キー(範囲選択) | Keys.SHIFT, Keys.ARROW_LEFT | カーソル移動しながら選択 |
タブで次の要素へ移動 | Keys.TAB | TABジャンプ |
Escキーを押す | Keys.ESCAPE | ダイアログを閉じる場合など |
使用例を以下に示します。テストページの名前入力欄をつかって、いろいろなキー操作を試しています。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from webdriver_manager.chrome import ChromeDriverManager
import os, time
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("file://" + os.path.abspath("sample.html")) # ローカルHTMLのパスを指定
# テキスト入力欄を取得
input_box = driver.find_element(By.ID, "name")
input_box.clear()
# `send_keys(Keys.XXXX)` を実行
input_box.send_keys("Selenium Test") # 文字を入力
time.sleep(1)
input_box.send_keys(Keys.BACKSPACE) # "t" を削除
time.sleep(1)
input_box.send_keys(Keys.CONTROL, "a") # Ctrl + A(全選択)
time.sleep(1)
input_box.send_keys(Keys.CONTROL, "c") # Ctrl + C(コピー)
input_box.clear()
time.sleep(1)
input_box.send_keys(Keys.CONTROL, "v") # Ctrl + V(貼り付け)
time.sleep(1)
input_box.send_keys(Keys.ARROW_LEFT * 5) # ←キーを5回押す(カーソルを左に移動)
time.sleep(1)
input_box.send_keys(Keys.SHIFT, Keys.ARROW_LEFT * 3) # Shift + ←キー3回(範囲選択)
time.sleep(1)
input_box.send_keys(Keys.DELETE) # Deleteキー(選択した部分を削除)
time.sleep(1)
input_box.send_keys(Keys.ENTER) # Enterキーを押す(送信をシミュレーション)
time.sleep(1)
driver.quit()
待機処理
Seleniumでのテストや自動化では、ウェブページの要素がすぐ利用できるとは限らないため、適切な待機処理が必要となります。待機処理を入れずに要素を操作しようとすると、以下のようなエラーや不安定な動作が発生する可能性があります。
エラーの種類 | 発生する状況 |
---|---|
NoSuchElementException | ページの読み込みが遅く、要素がまだ生成されていない |
ElementNotVisibleException | 要素がページにあるが、まだ表示されていない |
StaleElementReferenceException | 要素が動的に更新され、参照が切れてしまった |
TimeoutException | 指定した時間内に要素が見つからない |
待機処理にはtime.sleep()
がありますが、SeleniumにはWebDriverWait
というメソッドが用意されています。これらには次の違いがあります。
方法 | メリット | デメリット |
---|---|---|
time.sleep (固定時間待機) | 実装が簡単 | ページの速度に関係なく決まった時間待つため、不要な時間がかかる |
WebDriverWait (条件付き待機) | 必要な時間だけ待機 | コードが少し複雑になる。 |
使い方は、次のようになります。
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# ドライバーを最大time秒まで待機
wait = WebDriverWait(driver, time)
# By.XXXXで値を検索して得られる要素を、EC.XXXXで指定された条件を満たすまで待機させる
result = wait.until(EC.XXXX((By.XXXX, "値")))
待機させる要素の選択は、find_element
を使用する場合と同じです。待機を解消する条件の設定には、expected_conditions
(通称、EC
)のメソッドを使用します。
メソッド | 説明 |
---|---|
presence_of_element_located((By.XXX, "値")) | 要素がページ上に存在していれば、要素WebElement を取得する(非表示でも可) |
visibility_of_element_located((By.XXX, "値")) | 要素が表示されている(display: none; ではない)のであれば、要素WebElement を取得する |
text_to_be_present_in_element((By.XXX, "値"), "テキスト") | 要素のテキストが特定の値になるのを待ち、条件を満たしたらTrue を返す。 |
alert_is_present() | JavaScriptのアラート(alert() ,confirm() , prompt() )が表示されるのを待ち、条件を満たしたらAlert オプジェクトを返す。 |
frame_to_be_available_and_switch_to_it((By.XXX, "値")) | iframe がロードされるのを待ち、条件を満たしたらswitch_to.frame() を実行し、成功すればTrue を返す。 |
staleness_of(WebElement) | 要素が無効になるのを待ち、True を返す。(無効にならなければ False を返す) |
使用例を以下に示します。
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.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os, time
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("file://" + os.path.abspath("sample.html")) # ローカルHTMLのパスを指定
wait = WebDriverWait(driver, 10) # 最大で10秒待つ
### ✅ presence_of_element_located() ###
# 遅延ボタンが「DOM に存在する」ことを確認
element = wait.until(EC.presence_of_element_located((By.ID, "delayed_button")))
print("presence_of_element_located: 要素が存在する")
### ✅ visibility_of_element_located() ###
# 遅延ボタンが表示されるのを待つ(display: none; ではない)
element = wait.until(EC.visibility_of_element_located((By.ID, "delayed_button")))
print("visibility_of_element_located: 要素が表示された")
### ✅ text_to_be_present_in_element() ###
# AJAXボタンをクリック
driver.find_element(By.ID, "ajax_button").click()
# AJAXの結果が「データ取得成功」になるのを待つ
result = wait.until(
EC.text_to_be_present_in_element((By.ID, "ajax_result"), "データ取得成功")
)
print("text_to_be_present_in_element: AJAXのデータが表示された")
time.sleep(4) # 画面確認
### ✅ alert_is_present() ###
# アラートボタンをクリック
driver.find_element(By.ID, "alert_button").click()
# アラートが表示されるのを待つ
alert = wait.until(EC.alert_is_present())
print("alert_is_present: アラートが表示された")
time.sleep(4) # 画面確認
# アラートを閉じる
alert.accept()
### ✅ frame_to_be_available_and_switch_to_it() ###
# iframe が利用可能になるのを待つ
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, "test_frame")))
print("frame_to_be_available_and_switch_to_it: iframe に切り替え成功")
# iframe 内の入力フィールドに文字を入力
iframe_input = driver.find_element(By.ID, "iframe_message")
iframe_input.send_keys("iframe内のテスト")
# iframeの外に戻る
driver.switch_to.default_content()
time.sleep(4) # 画面確認
### ✅ staleness_of() ###
# ボタンを取得
button = driver.find_element(By.ID, "add_user")
# ページをリロード(以前の要素は `stale` になる)
driver.refresh()
# 利用規約にチェックをつけて、性別で女性を選択
driver.find_element(By.ID, "agree").click()
driver.find_element(By.XPATH, "//input[@type='radio' and @value='female']").click()
# 要素が無効化されるのを待つ
result = wait.until(EC.staleness_of(button))
print("staleness_of: 要素が無効化された")
if result:
button = wait.until(EC.presence_of_element_located((By.ID, "add_user")))
button.click()
time.sleep(4) # 画面確認
driver.quit()
ページ遷移
ページの遷移のメソッドとして代表的なものに以下があります。
メソッド | 説明 |
---|---|
back() | 戻る |
forward() | 進む |
switch_to.window() | タブの移動 |
refresh() | リロード |
使用例を示します。サンプルのHTMLファイルとgoogleの検索サイトを用いてページの遷移を行っています。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import os, time
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("file://" + os.path.abspath("sample.html")) # ローカルHTMLのパスを指定
### ✅ back()とforward() ###
# 「Googleに移動」のリンクをクリック(新しいページに遷移)
driver.find_element(By.LINK_TEXT, "Googleに移動").click()
time.sleep(2) # 少し待機
# 戻る
driver.back()
time.sleep(2) # 少し待機
print("戻る: 元のページに戻りました")
# 進む
driver.forward()
time.sleep(2) # 少し待機
print("進む: 次のページに進みました")
# 戻る
driver.back()
time.sleep(2) # 少し待機
print("戻る: 元のページに戻りました")
### ✅ switch_to.window() ###
# 「新しいタブを開く」ボタンをクリック
driver.find_element(By.ID, "new_tab").click()
time.sleep(2)
# すべてのタブを取得
tabs = driver.window_handles
print("現在開いているタブ:", tabs)
# 新しいタブに切り替え
driver.switch_to.window(tabs[1])
time.sleep(2) # 少し待機
print("新しいタブに切り替えました")
# 元のタブに戻る
driver.switch_to.window(tabs[0])
time.sleep(2) # 少し待機
print("元のタブに戻りました")
driver.quit()
HTMLの取得
現在のページのHTMLの取得にはdriver.page_source
を使用します。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import os, time
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("file://" + os.path.abspath("sample.html")) # ローカルHTMLのパスを指定
html_source = driver.page_source
print(html_source) # ページのHTMLが表示される
driver.quit()
インラインフレームとShadow DOMの操作
通常の要素操作とはことなり、インラインフレーム(iframe
)とShadow DOM
をSelenium
で操作するには特別な処理が必要になります。
項目 | 方法 |
---|---|
iframe (インラインフレーム) | ページが分割されているため、switch_to.frame() でiframe の内側に切り替えてから操作する。iframeの外側に戻る場合にはswitch_to.default_content() を用いる。 |
Shadow DOM (シャドウ DOM) | 通常はfind_element() ではアクセスできず、shadow_root を取得する必要がある。 |
使用例を示します。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import os, time
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("file://" + os.path.abspath("sample.html")) # ローカルHTMLのパスを指定
### ✅ iframe ###
# `iframe` に切り替え
driver.switch_to.frame("test_frame") # `id="test_frame"` の `iframe` に切り替え
print("iframe に切り替え成功!")
# `iframe` 内の要素を操作(例: input に文字を入力)
iframe_input = driver.find_element(By.ID, "iframe_message")
iframe_input.send_keys("iframe 内のテスト")
# `iframe` の外(元の HTML)に戻る
driver.switch_to.default_content()
print("元のページに戻りました!")
time.sleep(4)
### ✅ Shadow DOM ###
# Shadow DOM のルート要素を取得
shadow_host = driver.find_element(By.CSS_SELECTOR, ".shadow-container")
shadow_root = driver.execute_script("return arguments[0].shadowRoot", shadow_host)
# Shadow DOM 内のボタンを取得してクリック
shadow_button = shadow_root.find_element(By.ID, "shadow_button")
shadow_button.click()
print("Shadow DOM のボタンをクリックしました!")
time.sleep(4)
driver.quit()
まとめ
本記事では、Python の Selenium を使ったブラウザ自動操作の基本を解説しました。特に、以下のポイントについて詳しく説明しました。
- 基本操作(要素の検索、クリック、入力)
- ページ遷移(戻る・進む・タブ移動・リロード)
- 特殊な要素の操作(iframe・Shadow DOM)
- 待機処理(要素の表示を待つ)
Selenium を活用すれば、テストの自動化だけでなく、Web スクレイピングや業務効率化にも役立ちます。ぜひ、実際にコードを動かしながら、試してみてください!