Selenium(セレニウム)とは、PythonなどのコードからWebブラウザを自動操作するためのライブラリです。 要素の取得は driver.find_element(By.ID, "title") のように、By で「どの方法で探すか」を指定する書き方が Selenium 4 の基本です。

この記事では、Selenium 4.50.0(2026年10月時点で pip から入る最新版)と Chromium 141 を使い、ローカルのHTMLに対して実際にコードを動かした結果をそのまま載せています。By の全8種の対応表、検索上位で今も見かける旧記法 find_element_by_* がエラーになる再現と書き換え表、つまずきやすい NoSuchElementException・StaleElementReferenceException・iframe の再現と直し方まで、コピペで試せる形でまとめました。

Selenium Pythonの早見表

まずはこの表で「やりたいこと → 書き方」を引けます。 すべて from selenium.webdriver.common.by import By を前提にしています。

やりたいこと 書き方(Selenium 4) 補足
ブラウザを起動 driver = webdriver.Chrome() 4.6以降は Selenium Manager がドライバーを自動準備
ページを開く driver.get("https://example.com") 読み込み完了まで待つ
要素を1つ取得 driver.find_element(By.ID, "title") 無ければ NoSuchElementException
要素を全部取得 driver.find_elements(By.CLASS_NAME, "item") 無ければ空リスト []
文字を入力 el.send_keys("ノートPC") 消すのは el.clear()
クリック el.click()
セレクトボックス Select(el).select_by_value("pc") select_by_visible_text / select_by_index も可
テキスト取得 el.text 画面に見えている文字
属性取得 el.get_attribute("href") get_dom_attribute / get_property もある
表示されるまで待つ WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "x"))) 明示的な待機
iframe の中を操作 driver.switch_to.frame("memo-frame") 戻るときは switch_to.default_content()
スクリーンショット driver.save_screenshot("page.png") 要素単位は el.screenshot("a.png")
ヘッドレス起動 options.add_argument("--headless=new") 画面なしで動かす
JavaScript 実行 driver.execute_script("return document.title")
終了 driver.quit() ブラウザとドライバーを両方閉じる

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Selenium Pythonの使い方|要素取得の全パターンと待機処理」

動作環境と準備

この記事のコードは、次の環境で実行して確認しています。

項目 バージョン
Python 3.11
selenium 4.50.0
ブラウザ Chromium 141.0.7390.37
ChromeDriver 147.0.7727.24

インストール

python3 -m venv .venv
source .venv/bin/activate
pip install selenium
python -c "import selenium; print(selenium.__version__)"
4.50.0

ドライバーの準備は Selenium Manager におまかせできる

Selenium 4.6 以降は、Selenium Manager という仕組みが、インストール済みのブラウザに合う ChromeDriver を自動で用意します。 通常のPCなら、ドライバーを手で入れずに次の2行で起動できます。

from selenium import webdriver
driver = webdriver.Chrome()

ブラウザやドライバーの場所を自分で指定したいとき(社内ネットワークでダウンロードできない、検証用の Chromium を使いたいなど)は、Options と Service で明示します。この記事の検証環境では、Chromium 141 に対して手元の ChromeDriver が 147 だったため、そのままだと次のエラーになりました。

selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 147
Current browser version is 141.0.7390.37 with binary path /opt/pw-browsers/chromium-1194/chrome-linux/chrome

ブラウザとドライバーのメジャーバージョンはそろえるのが基本です。 通常は Selenium Manager に任せればそろいます。この記事の検証では、確認用として ChromeDriver の --disable-build-check(バージョン確認を省略するオプション)で起動しています。

共通の起動コード(common.py)

以降のサンプルは、この make_driver() を使います。ブラウザのパスは自分の環境に合わせて変えるか、binary_location と Service(...) の行を消して Selenium Manager に任せてください。

# common.py
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

def make_driver():
    options = Options()
    options.add_argument("--headless=new")        # 画面なしで起動
    options.add_argument("--no-sandbox")          # コンテナ内で動かす場合
    options.add_argument("--window-size=1280,800")
    options.binary_location = "/opt/pw-browsers/chromium-1194/chrome-linux/chrome"
    service = Service("/opt/node22/bin/chromedriver",
                      service_args=["--disable-build-check"])
    driver = webdriver.Chrome(options=options, service=service)
    driver.get(Path("sample.html").resolve().as_uri())  # ローカルHTMLを開く
    return driver

練習用のHTML(sample.html)

外部サイトに負荷をかけずに試せるよう、ローカルのHTMLを用意します。備品の検索フォーム、一覧、遅れて表示される要素、iframe を含めています。

<!DOCTYPE html>
<html lang="ja">
<head><meta charset="utf-8"><title>備品管理デモ</title></head>
<body>
  <h1 id="title">備品管理デモ</h1>
  <form id="search-form">
    <input id="keyword" name="q" class="input text" type="text" placeholder="備品名">
    <select id="category" name="category">
      <option value="">すべて</option>
      <option value="pc">パソコン</option>
      <option value="desk">机・椅子</option>
    </select>
    <button id="search-btn" type="button" class="btn primary">検索</button>
  </form>
  <ul id="items">
    <li class="item" data-id="1">ノートPC</li>
    <li class="item" data-id="2">モニター</li>
    <li class="item" data-id="3">オフィスチェア</li>
  </ul>
  <a href="#help">使い方ガイドを見る</a>
  <div id="result"></div>
  <button id="reload-btn" type="button">一覧を再描画</button>
  <button id="late-btn" type="button">2秒後に表示</button>
  <iframe id="memo-frame" srcdoc="<p id='memo'>iframeの中のメモ</p><input id='memo-input'>"></iframe>
  <script>
    document.getElementById('search-btn').addEventListener('click', () => {
      const q = document.getElementById('keyword').value;
      const c = document.getElementById('category').value;
      document.getElementById('result').textContent = `検索: ${q} / 分類: ${c}`;
    });
    document.getElementById('reload-btn').addEventListener('click', () => {
      const ul = document.getElementById('items');
      ul.innerHTML = '<li class="item" data-id="1">ノートPC</li><li class="item" data-id="2">モニター</li>';
    });
    document.getElementById('late-btn').addEventListener('click', () => {
      setTimeout(() => {
        const p = document.createElement('p');
        p.id = 'late'; p.textContent = '遅れて出た要素';
        document.body.appendChild(p);
      }, 2000);
    });
  </script>
</body>
</html>

要素を取得する8つの方法(By の全種類)

Selenium 4 の要素取得は find_element(By.〇〇, "値") の1つの形にまとまっています。 By には次の8種類があります。

By の種類 探し方 例 向いている場面
By.ID id 属性 (By.ID, "title") id があるなら最優先。速くて確実
By.NAME name 属性 (By.NAME, "q") フォーム部品
By.CLASS_NAME class 名(1つだけ) (By.CLASS_NAME, "item") 同じ種類の要素をまとめて取る
By.TAG_NAME タグ名 (By.TAG_NAME, "h1") table や li を全部取る
By.LINK_TEXT リンク文字の完全一致 (By.LINK_TEXT, "使い方ガイドを見る") a タグ
By.PARTIAL_LINK_TEXT リンク文字の部分一致 (By.PARTIAL_LINK_TEXT, "ガイド") 文言が少し変わるリンク
By.CSS_SELECTOR CSSセレクタ (By.CSS_SELECTOR, "li.item[data-id='2']") 属性・親子関係を組み合わせる
By.XPATH XPath (By.XPATH, "//li[text()='オフィスチェア']") 文字で探す、親へさかのぼる

8種類を1つずつ動かす

# by_all.py
from selenium.webdriver.common.by import By
from common import make_driver

driver = make_driver()

print("1 ID               :", driver.find_element(By.ID, "title").text)
print("2 NAME             :", driver.find_element(By.NAME, "q").get_attribute("placeholder"))
print("3 CLASS_NAME       :", len(driver.find_elements(By.CLASS_NAME, "item")), "件")
print("4 TAG_NAME         :", driver.find_element(By.TAG_NAME, "h1").text)
print("5 LINK_TEXT        :", driver.find_element(By.LINK_TEXT, "使い方ガイドを見る").get_attribute("href").split("#")[1])
print("6 PARTIAL_LINK_TEXT:", driver.find_element(By.PARTIAL_LINK_TEXT, "ガイド").text)
print("7 CSS_SELECTOR     :", driver.find_element(By.CSS_SELECTOR, "li.item[data-id='2']").text)
print("8 XPATH            :", driver.find_element(By.XPATH, "//li[text()='オフィスチェア']").get_attribute("data-id"))
print("find_elements      :", [e.text for e in driver.find_elements(By.CSS_SELECTOR, "#items > li")])
print("0件のfind_elements :", driver.find_elements(By.CLASS_NAME, "not-exist"))
try:
    driver.find_element(By.CLASS_NAME, "btn primary")
except Exception as e:
    print("複合クラス:", type(e).__name__, str(e).splitlines()[0])
driver.quit()

実行結果(selenium 4.50.0 / Chromium 141):

1 ID               : 備品管理デモ
2 NAME             : 備品名
3 CLASS_NAME       : 3 件
4 TAG_NAME         : 備品管理デモ
5 LINK_TEXT        : help
6 PARTIAL_LINK_TEXT: 使い方ガイドを見る
7 CSS_SELECTOR     : モニター
8 XPATH            : 3
find_elements      : ['ノートPC', 'モニター', 'オフィスチェア']
0件のfind_elements : []
複合クラス: InvalidSelectorException Message: Compound class names are not allowed.; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#invalidselectorexception

ポイントは3つです。

  • find_elements(複数形)は見つからなくても例外にならず、空リストを返します。 「あるかどうか」を調べたいときに便利です。
  • By.CLASS_NAME にスペース区切りの複数クラスは渡せません。 "btn primary" は InvalidSelectorException になります。By.CSS_SELECTOR, ".btn.primary" と書けば取得できます。
  • 迷ったら「ID → CSS_SELECTOR → XPATH」の順で考えると、読みやすく変更にも強いコードになります。

CSSセレクタとXPathの逆引き

CSS_SELECTOR と XPATH を使いこなすと、ほとんどの要素が取れます。

取りたいもの CSS_SELECTOR XPATH
id が title #title //*[@id='title']
class が item の li li.item //li[contains(@class,'item')]
2つのクラスを持つ .btn.primary //*[contains(@class,'btn') and contains(@class,'primary')]
属性の値で li[data-id='2'] //li[@data-id='2']
属性の前方一致 a[href^='https'] //a[starts-with(@href,'https')]
直下の子 #items > li //*[@id='items']/li
n番目 #items > li:nth-child(2) (//*[@id='items']/li)[2]
文字の完全一致 (不可) //li[text()='モニター']
文字の部分一致 (不可) //li[contains(text(),'チェア')]
親要素へ戻る (不可) //li[text()='モニター']/..

文字で探す・親へさかのぼるときだけ XPath、それ以外は CSS という使い分けがわかりやすくおすすめです。

要素の中から探す(絞り込み)

取得した要素に対しても find_element が使えます。範囲を絞ると、同じ class がページ内にいくつもあっても目的の要素だけを取れます。

items = driver.find_element(By.ID, "items")
for li in items.find_elements(By.TAG_NAME, "li"):
    print(li.get_attribute("data-id"), li.text)

旧記法 find_element_by_* を書き換える

検索で見つかる記事には find_element_by_id() のような書き方がまだ多く残っていますが、Selenium 4.3.0 でこれらのメソッドは削除されています。 現在のバージョンで実行すると次のようになります。

driver.find_element_by_id("title")

実行結果(selenium 4.50.0):

AttributeError: 'WebDriver' object has no attribute 'find_element_by_id'

AttributeError はメソッドそのものが存在しないという意味です。 次の表のとおり書き換えれば動きます。

旧記法(4.3.0で削除) Selenium 4 の書き方
find_element_by_id("x") find_element(By.ID, "x")
find_element_by_name("x") find_element(By.NAME, "x")
find_element_by_class_name("x") find_element(By.CLASS_NAME, "x")
find_element_by_tag_name("x") find_element(By.TAG_NAME, "x")
find_element_by_link_text("x") find_element(By.LINK_TEXT, "x")
find_element_by_partial_link_text("x") find_element(By.PARTIAL_LINK_TEXT, "x")
find_element_by_css_selector("x") find_element(By.CSS_SELECTOR, "x")
find_element_by_xpath("x") find_element(By.XPATH, "x")
find_elements_by_〇〇("x") find_elements(By.〇〇, "x")
webdriver.Chrome("chromedriver") webdriver.Chrome(service=Service("chromedriver"))
options.headless = True options.add_argument("--headless=new")

書き換えのコツは「_by_xxx を消して、第1引数に By.XXX を足す」だけです。 from selenium.webdriver.common.by import By の import を忘れずに追加してください。

よくあるエラーを再現して直す

Selenium のつまずきは、ほとんどが「まだ表示されていない」「取り直しが必要」「iframe の中にある」の3つです。 まとめて再現するコードを用意しました。

# errors.py
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import (
    NoSuchElementException, StaleElementReferenceException, TimeoutException)
from common import make_driver

driver = make_driver()

# 1. 遅れて表示される要素
driver.find_element(By.ID, "late-btn").click()
try:
    driver.find_element(By.ID, "late")
except NoSuchElementException as e:
    print("[待機なし]", type(e).__name__, ":", e.msg.splitlines()[0])

t = time.perf_counter()
late = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "late")))
print(f"[WebDriverWait] {late.text} ({time.perf_counter()-t:.1f}秒待った)")

try:
    WebDriverWait(driver, 1).until(EC.presence_of_element_located((By.ID, "never")))
except TimeoutException as e:
    print("[タイムアウト]", type(e).__name__)

# 2. 画面が書き換わった後の古い要素
first = driver.find_element(By.CSS_SELECTOR, "#items li")
driver.find_element(By.ID, "reload-btn").click()
try:
    print(first.text)
except StaleElementReferenceException as e:
    print("[Stale]", type(e).__name__, ":", e.msg.splitlines()[0])
first = driver.find_element(By.CSS_SELECTOR, "#items li")
print("[取り直し]", first.text)

# 3. iframe の中の要素
try:
    driver.find_element(By.ID, "memo")
except NoSuchElementException as e:
    print("[iframe 切替なし]", type(e).__name__)
WebDriverWait(driver, 5).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "memo-frame")))
print("[iframe 切替後]", driver.find_element(By.ID, "memo").text)
driver.find_element(By.ID, "memo-input").send_keys("メモ入力OK")
print("[iframe 入力]", driver.find_element(By.ID, "memo-input").get_attribute("value"))
driver.switch_to.default_content()
print("[元に戻る]", driver.find_element(By.ID, "title").text)

# 4. 暗黙の待機
driver.implicitly_wait(3)
t = time.perf_counter()
try:
    driver.find_element(By.ID, "never")
except NoSuchElementException:
    print(f"[implicitly_wait(3)] 見つからず {time.perf_counter()-t:.1f}秒で例外")
driver.quit()

実行結果:

[待機なし] NoSuchElementException : no such element: Unable to locate element: {"method":"css selector","selector":"[id="late"]"}
[WebDriverWait] 遅れて出た要素 (2.1秒待った)
[タイムアウト] TimeoutException
[Stale] StaleElementReferenceException : stale element reference: stale element not found in the current frame
[取り直し] ノートPC
[iframe 切替なし] NoSuchElementException
[iframe 切替後] iframeの中のメモ
[iframe 入力] メモ入力OK
[元に戻る] 備品管理デモ
[implicitly_wait(3)] 見つからず 3.0秒で例外

なお、エラーメッセージを見ると By.ID も内部では CSS セレクタ [id="late"] に変換されて検索されていることがわかります。

エラー別の原因と直し方

エラー 主な原因 直し方
NoSuchElementException まだ表示されていない/セレクタの書き間違い/iframe の中 WebDriverWait で待つ。DevTools でセレクタを確認。iframe なら切り替え
TimeoutException 待ったが条件を満たさなかった 条件(表示・クリック可能など)とセレクタを見直す。待ち時間を調整
StaleElementReferenceException 取得後に画面が書き換わり、要素が作り直された 操作の直前に取り直す
InvalidSelectorException By.CLASS_NAME に複数クラス、XPath の文法ミス By.CSS_SELECTOR, ".a.b" に変える
ElementClickInterceptedException 別の要素(ダイアログ・固定ヘッダー)が上に重なっている EC.element_to_be_clickable で待つ、スクロールする
ElementNotInteractableException 非表示の要素を操作しようとした EC.visibility_of_element_located で表示を待つ
AttributeError: ... find_element_by_id 旧記法 前の章の書き換え表で By を使う

待機は WebDriverWait(明示的な待機)を基本にする

Selenium の待ち方は、time.sleep()・暗黙の待機・明示的な待機の3つです。

待ち方 書き方 特徴 おすすめ度
固定時間 time.sleep(3) 必ず3秒止まる。早く表示されても待つ 調査用
暗黙の待機 driver.implicitly_wait(3) 全 find_element に最大3秒の待ちが付く。見つからないと毎回3秒かかる 小さなスクリプト向け
明示的な待機 WebDriverWait(driver, 10).until(条件) 条件を満たした瞬間に進む。条件を選べる 基本はこれ

上の実行結果でも、WebDriverWait は2秒後に表示された時点ですぐ進み(2.1秒)、暗黙の待機は見つからない要素に対して毎回3.0秒かかっています。Selenium の公式ドキュメントでも、暗黙の待機と明示的な待機を混ぜると待ち時間が読みにくくなるため、混在させないことが案内されています。

よく使う expected_conditions

from selenium.webdriver.support import expected_conditions as EC で使える主な条件です。

条件 意味 戻り値
presence_of_element_located(loc) DOM に存在する(見えなくてもよい) 要素
visibility_of_element_located(loc) 表示されている 要素
element_to_be_clickable(loc) 表示され、有効でクリックできる 要素
presence_of_all_elements_located(loc) 1つ以上存在する 要素のリスト
text_to_be_present_in_element(loc, "文字") 指定の文字が含まれる True
invisibility_of_element_located(loc) 消えた(読み込み中表示が消えるのを待つ) True など
frame_to_be_available_and_switch_to_it(loc) iframe が使えるようになったら切り替え True
title_contains("文字") タイトルに文字が含まれる True
url_contains("/done") URL に文字が含まれる True
staleness_of(el) 古い要素が DOM から外れた(画面遷移の完了確認) True
alert_is_present() アラートが出た Alert

クリックの前は element_to_be_clickable、文字を読む前は visibility_of_element_located と覚えておくと、ほとんどの場面に対応できます。

wait = WebDriverWait(driver, 10)
btn = wait.until(EC.element_to_be_clickable((By.ID, "search-btn")))
btn.click()
wait.until(EC.text_to_be_present_in_element((By.ID, "result"), "検索:"))

iframe の切り替え方

iframe(ページの中に埋め込まれた別のページ)の中の要素は、切り替えないと見つかりません。

やりたいこと 書き方
id / name で切り替え driver.switch_to.frame("memo-frame")
要素で切り替え driver.switch_to.frame(driver.find_element(By.CSS_SELECTOR, "iframe"))
番号で切り替え driver.switch_to.frame(0)
待ってから切り替え WebDriverWait(driver, 5).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "memo-frame")))
1つ外側へ driver.switch_to.parent_frame()
ページ全体へ戻る driver.switch_to.default_content()

操作が終わったら default_content() で戻すのを忘れないようにしましょう。戻さないと、外側の要素が NoSuchElementException になります。

入力・クリック・セレクトボックス・スクショの使い方

要素を取れたら、あとは操作メソッドを呼ぶだけです。 よく使う操作をまとめて動かします。

# ops.py
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from common import make_driver

driver = make_driver()
print("タイトル:", driver.title)

# 文字入力(全選択して消してから入力)
box = driver.find_element(By.ID, "keyword")
box.send_keys("モニター")
box.send_keys(Keys.CONTROL, "a")
box.send_keys(Keys.BACK_SPACE)
box.send_keys("ノートPC")
print("入力値:", box.get_attribute("value"))

# セレクトボックス
select = Select(driver.find_element(By.ID, "category"))
select.select_by_value("pc")
print("選択中:", select.first_selected_option.text)
select.select_by_visible_text("机・椅子")
print("選択中:", select.first_selected_option.text)
select.select_by_index(1)
print("選択肢:", [o.text for o in select.options])

# クリック
driver.find_element(By.ID, "search-btn").click()
print("結果:", driver.find_element(By.ID, "result").text)

# 情報の取得
item = driver.find_element(By.CSS_SELECTOR, "li.item")
print("text / data-id / tag / 表示 :", item.text, item.get_attribute("data-id"), item.tag_name, item.is_displayed())
print("dom_attribute / dom_property :", box.get_dom_attribute("placeholder"), box.get_property("value"))

# スクリーンショット
driver.save_screenshot("page.png")
driver.find_element(By.ID, "search-form").screenshot("form.png")
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
print("スクショ保存: page.png, form.png")
driver.quit()

実行結果:

タイトル: 備品管理デモ
入力値: ノートPC
選択中: パソコン
選択中: 机・椅子
選択肢: ['すべて', 'パソコン', '机・椅子']
結果: 検索: ノートPC / 分類: pc
text / data-id / tag / 表示 : ノートPC 1 li True
dom_attribute / dom_property : 備品名 ノートPC
スクショ保存: page.png, form.png

保存された画像のサイズを確認すると、page.png は 1280×661(表示領域の大きさ)、form.png はフォーム部分だけの 1264×24 でした。save_screenshot は表示中の範囲、要素.screenshot はその要素だけを撮ります。

操作メソッドの一覧

分類 メソッド 内容
入力 send_keys("文字") 文字を入力
入力 send_keys(Keys.ENTER) 特殊キー(ENTER, TAB, ESCAPE など)
入力 clear() 入力欄を空にする
入力 send_keys("/path/file.png") input type="file" へのファイル指定
クリック click() クリック
クリック submit() フォーム送信
取得 text 表示されている文字
取得 get_attribute("x") 属性(なければプロパティ)の値
取得 get_dom_attribute("x") HTML に書かれた属性の値
取得 get_property("x") 現在のプロパティの値(入力後の value など)
状態 is_displayed() / is_enabled() / is_selected() 表示・有効・選択の状態
画面 driver.title / driver.current_url / driver.page_source タイトル・URL・HTML
画面 driver.back() / forward() / refresh() 戻る・進む・再読み込み
ウィンドウ driver.window_handles / switch_to.window(h) タブの切り替え
アラート driver.switch_to.alert.accept() OK を押す

マウス操作(ホバー・ドラッグ)は ActionChains

マウスを重ねる・ドラッグするといった操作は ActionChains で組み立てます。

from selenium.webdriver.common.action_chains import ActionChains

menu = driver.find_element(By.ID, "title")
ActionChains(driver).move_to_element(menu).perform()          # ホバー
ActionChains(driver).double_click(menu).perform()              # ダブルクリック
ActionChains(driver).context_click(menu).perform()             # 右クリック
# ActionChains(driver).drag_and_drop(src, dst).perform()       # ドラッグ&ドロップ

※ この記事の検証では move_to_element(ホバー)で mouseover イベントが発生することを確認しました。ドラッグ&ドロップなどその他の操作は、公式ドキュメントで確認してください。

ヘッドレスで動かす

ヘッドレスとは、ブラウザの画面を表示せずに動かすモードです。 サーバーや CI で動かすときに使います。Chrome / Chromium では --headless=new を指定します(以前の options.headless = True は現在のバージョンでは使えません)。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--headless=new")
options.add_argument("--window-size=1280,800")   # ヘッドレスでも画面サイズを決めておく
driver = webdriver.Chrome(options=options)
オプション 用途
--headless=new 画面なしで起動
--window-size=1280,800 スクショやレイアウトのサイズを固定
--no-sandbox Docker などのコンテナ内で起動するとき
--disable-dev-shm-usage コンテナの共有メモリが小さいとき
--lang=ja-JP 表示言語を日本語に

ヘッドレスでは画面サイズが小さめになることがあるため、--window-size を付けておくとスクショや要素の表示が安定します。

完成形:検索して結果を取り出すスクリプト

ここまでの内容を1つにまとめた、コピペで動く完成形です。 with 文を使うと、途中でエラーになってもブラウザが閉じられます。

# search_items.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait, Select
from selenium.webdriver.support import expected_conditions as EC
from common import make_driver

with make_driver() as driver:
    wait = WebDriverWait(driver, 10)

    box = wait.until(EC.visibility_of_element_located((By.ID, "keyword")))
    box.clear()
    box.send_keys("ノートPC")
    Select(driver.find_element(By.ID, "category")).select_by_value("pc")

    wait.until(EC.element_to_be_clickable((By.ID, "search-btn"))).click()
    wait.until(EC.text_to_be_present_in_element((By.ID, "result"), "検索:"))

    print(driver.find_element(By.ID, "result").text)
    rows = [(li.get_attribute("data-id"), li.text)
            for li in driver.find_elements(By.CSS_SELECTOR, "#items > li")]
    print(rows)

実行結果:

検索: ノートPC / 分類: pc
[('1', 'ノートPC'), ('2', 'モニター'), ('3', 'オフィスチェア')]

Seleniumを使うときの心がけ

外部のサイトを自動操作・データ取得するときは、そのサイトの利用規約と robots.txt を確認し、アクセス間隔をあけて相手のサーバーに負担をかけないようにしましょう。 ログインが必要なページや、自動取得を禁止しているページは対象にしないのが基本です。

また、目的によって道具を選ぶと作業が楽になります。

目的 向いている道具
JavaScript で描画されるページの操作・入力 Selenium
静的なHTMLからデータを取り出すだけ requests + BeautifulSoup(別記事で解説)
E2Eテスト、自動待機を重視 Playwright(別記事で解説)
複数ブラウザ・既存の Selenium 資産を活用 Selenium(Grid で並列実行も可能)

よくある質問

Q. webdriver.Chrome() で SessionNotCreatedException が出ます。 A. ブラウザと ChromeDriver のバージョンが合っていないことが多いです。PATH に古い chromedriver が残っていると、それが使われることがあります。古い chromedriver を PATH から外し、Selenium Manager に任せるとそろったドライバーが使われます。

Q. find_element と find_elements はどう使い分けますか? A. 必ずある1つの要素は find_element、0個かもしれない・複数ある要素は find_elements です。find_elements は見つからなくても空リストを返すので、if driver.find_elements(...): で存在チェックができます。

Q. time.sleep() ではいけませんか? A. 動きはしますが、表示が早くても必ずその秒数だけ待つため、全体が遅くなりがちです。WebDriverWait なら条件を満たした瞬間に進むので、速さと安定性を両立できます。

Q. get_attribute と get_property の違いは? A. get_dom_attribute は HTML に書かれた値、get_property は現在の値です。入力欄に文字を入れたあとの value は get_property("value") で取れます。get_attribute は両方を見て値を返す便利メソッドです。

まとめ

  • Selenium 4 の要素取得は find_element(By.〇〇, "値") に統一。By は ID / NAME / CLASS_NAME / TAG_NAME / LINK_TEXT / PARTIAL_LINK_TEXT / CSS_SELECTOR / XPATH の8種類
  • 旧記法 find_element_by_* は 4.3.0 で削除済み。_by_xxx を消して By.XXX を足せば書き換えられる
  • 複数クラスは By.CSS_SELECTOR, ".a.b"、文字や親で探すときは XPath
  • 待機は WebDriverWait + expected_conditions が基本。暗黙の待機と混ぜない
  • Stale は操作の直前に取り直す、iframe は switch_to.frame で切り替えて default_content で戻る
  • ドライバーは Selenium Manager におまかせ。ヘッドレスは --headless=new
  • 外部サイトでは利用規約と robots.txt を確認し、間隔をあけてアクセスする

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Selenium Pythonの使い方|要素取得の全パターンと待機処理」

株式会社RJCでは、Seleniumによるブラウザ自動操作の知識を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?