NEW

【Python】Seleniumスクレイピング実践サンプル集|古い find_element_by_ が動かない原因と2026年の正しい書き方

pythonでスクレイピングする時によく使うSeleniumのサンプルコード集です。
2021年公開の記事でしたが、Seleniumのバージョンアップで多くの古いコードが動かなくなったため、2026年7月時点の最新Selenium(4.46系)で動く書き方に全面的に書き直しました。

結論|昔のサンプルが動かない最大の原因は find_element_by_ の削除

ネット上に残る古いSeleniumのサンプルをコピペしてAttributeErrorが出る場合、原因はほぼこれです。

find_element_by_id()find_elements_by_class_name() といった find_element(s)_by_* 系メソッドは、Selenium 4.3.0(2022年)で完全に削除されました。
現在は find_element(By.ID, "...") のように、Byを使う書き方に統一されています。

まずは最新版に更新してから読み進めてください。

pip install -U selenium

2026年7月時点の最新安定版は selenium 4.46.0(Python 3.10以上が必要)です。
参考:PyPI: seleniumSelenium Releases

古いAPI → 新APIの対応表

古いコードは、以下の対応表で機械的に置き換えれば動くようになります。Byのimportを忘れないでください。

from selenium.webdriver.common.by import By
古いAPI(削除済み・動きません)2026年版の正しいAPI
driver.find_element_by_id("x")driver.find_element(By.ID, "x")
driver.find_element_by_name("x")driver.find_element(By.NAME, "x")
driver.find_element_by_class_name("x")driver.find_element(By.CLASS_NAME, "x")
driver.find_element_by_tag_name("x")driver.find_element(By.TAG_NAME, "x")
driver.find_element_by_css_selector("x")driver.find_element(By.CSS_SELECTOR, "x")
driver.find_element_by_xpath("x")driver.find_element(By.XPATH, "x")
driver.find_elements_by_class_name("x")driver.find_elements(By.CLASS_NAME, "x")
driver.find_elements_by_tag_name("x")driver.find_elements(By.TAG_NAME, "x")

参考(削除の一次情報):PR #10712(find_element_by_ の削除)

ドライバ準備|Selenium Manager でドライバのDLは不要に

もうひとつの大きな変化がこれです。
Selenium 4.6.0以降は「Selenium Manager」が標準搭載され、ChromeDriverの手動ダウンロードやパス指定が原則不要になりました。
以前よく使われていたwebdriver-manager(サードパーティ)も、基本的には不要です。

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

# Chromeの起動オプション
options = Options()
options.add_argument("--headless=new")      # 2026年推奨の新ヘッドレスモード
options.add_argument("--window-size=1920,1080")
options.add_argument("--lang=ja-JP")
options.add_argument("--no-sandbox")

# Selenium 4.6+ は Selenium Manager がドライバを自動解決する。
# chromedriver がPATHに無ければ自動で取得してくれるため、パス指定は不要。
driver = webdriver.Chrome(options=options)

参考:Selenium Manager 公式ドキュメント

ドライバのパスやログを制御したい場合は Service を使う

閉域環境などでドライバを手動配置したい場合は、Serviceオブジェクト経由で指定します。
古いwebdriver.Chrome(executable_path=...)は削除済みなので使えません。

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

# パスを渡さなければ Selenium Manager が解決する。
# 手動配置する場合は Service(executable_path=r"C:\drivers\chromedriver.exe")
service = Service()
options = Options()
options.add_argument("--headless=new")

driver = webdriver.Chrome(service=service, options=options)
driver.implicitly_wait(10)
driver.set_page_load_timeout(25)

参考:Chromeドライバ設定 公式ドキュメント

指定したタグとクラスでテキストを取り出しpandasのSeriesにする

要素のテキストをまとめて取り出し、pandasのSeriesに変換する定番処理です。
Selenium単体でも、後述のBeautifulSoup併用でも書けます。ここではSeleniumの新APIで書きます。

from selenium.webdriver.common.by import By
import pandas as pd

def tag_get(self, css_selector):
    # 例: "p.link" のようにタグ.クラスをCSSセレクタで渡す
    elements = self.driver.find_elements(By.CSS_SELECTOR, css_selector)
    all_list = [el.text for el in elements]
    return pd.Series(all_list)

複数要素を取るfind_elements(複数形)は、要素が無くても例外を投げず空リスト[]を返すため、存在チェックにも使えます。

リンクのaタグを見つけて、指定条件でリストに追加と置換

取得したaタグのhrefを条件で振り分ける処理です。ロジック自体は昔のままで問題ありません。

links = driver.find_elements(By.TAG_NAME, "a")

all_list = []
for element in links:
    url = element.get_attribute("href")
    if not url:
        continue
    if 'なんとか' in url:
        all_list.append(url)
    elif 'かんとか' in url:
        url = url.replace('かんとか', 'なんとか')
        all_list.append(uri + url)
    elif url.startswith('http://'):
        all_list.append(url.replace('http://', 'https://'))

指定したclassの数をカウントする

この回数分の処理を繰り返す、といった用途で使います。
ここが昔のコードで一番動かなくなる箇所です。find_elements_by_class_nameは削除されたので、find_elements(By.CLASS_NAME, ...)に置き換えます。

def check_datenum(self):
    # 旧: self.driver.find_elements_by_class_name(self.key_class)  ← 動きません
    elements = self.driver.find_elements(By.CLASS_NAME, self.key_class)
    return len(elements)

指定したCSSクラスでURLを見つけてリストに格納し、pandasデータフレームに格納

elements = driver.find_elements(By.CSS_SELECTOR, 'div.heading > a')

elem_url = [el.get_attribute("href") for el in elements]
alink = pd.DataFrame(elem_url)

XPathであいまい検索、ワイルドカード

XPath自体はChromeの検証(デベロッパーツール)からコピーしています。
IDに日付など可変値が入る場合は、ワイルドカードで吸収します。

# 実際のXPath: //*[@id="IDname_20211004"]/dd/ul/li/a
# 可変IDを避けてワイルドカード化
elements = driver.find_elements(By.XPATH, '//*/dd/ul/li/a')

URLの連番の一部をループで作ってしまう手法も便利です。

## 開催日分の詳細を取りに行く
for i in range(1, num + 1):
    CD.key_URL = 'https://example.jp/a' + str(i) + '0001/nav_btn'
    CD.table_name = 'detail'
    CD.key_tag = 'a'
    CD.ifstr = "nav_btn"
    CD.dget()
    linklists = CD.check_txtnum()
    print(linklists)

明示的待機|JS描画やAjaxを確実に待つ

2021年版には無かった項目ですが、実務ではこれを入れないと安定しません
要素が出現するまで待つWebDriverWaitexpected_conditionsを使うのが定番です。

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, timeout=10)

# 要素が出現するまで最大10秒待つ
element = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div.result")))

# クリック可能になるまで待ってからクリック
button = wait.until(EC.element_to_be_clickable((By.ID, "submit")))
button.click()

公式は「暗黙的待機(implicitly_wait)と明示的待機を混在させるな」と明記しています。待ち時間が予測不能になるためです。スクレイピングでは明示的待機を主軸にするのが堅実です。
参考:Waits 公式ドキュメント

対象URLのリトライ処理

タイムアウト時に再試行する処理です。ロジックは昔のままで有効です。

from selenium.common.exceptions import TimeoutException
import time

j = 0
while j < 9:
    try:
        driver.get(key_URL)
        print("The page was loaded " + key_URL)
    except TimeoutException:
        j += 1
        print("Timeout, Retrying... (%(j)s/%(max)s)" % {'j': j, 'max': 9})
        time.sleep(15)
        continue
    else:
        break

マルチスレッド化

Windowsアプリ制作時に使用します。
そうしないとボタン動作でアプリは動いているのに、画面上はフリーズしたように見えてしまうためです。

import threading

def callback(self):
    th = threading.Thread(target=self.DF_MAKE)
    th.start()

BeautifulSoup併用|page_sourceを渡す手法は今も有効

Selenium APIの変更とは無関係で、JS描画後のDOMをpage_sourceで取り出してBeautifulSoupで解析する定番パターンは2026年でも問題なく使えます。

from bs4 import BeautifulSoup

html = driver.page_source
soup = BeautifulSoup(html, "html.parser")   # "lxml" でも可

for h2 in soup.select("h2.section-title"):
    print(h2.get_text(strip=True))

後片付け|quit() を忘れない

driver.quit()   # プロセスごと終了。close() はタブのみ閉じる

移行時のチェックリスト

  • pip install -U seleniumで最新版(2026年7月時点で4.46.0)にする
  • find_element_by_*系はすべてfind_element(By.X, ...)に置換し、from selenium.webdriver.common.by import Byを追加
  • webdriver.Chrome(executable_path=...)は削除済み。パス指定はService(executable_path=...)経由に
  • webdriver-managerは原則不要(Selenium Managerが内蔵)
  • ヘッドレスは--headless=newに統一
  • 暗黙的待機と明示的待機を混ぜない。待ちはWebDriverWait+ECを主軸に

よくある質問(FAQ)

Q. 昔のSeleniumコードをコピペしたらAttributeErrorが出ます。なぜ?

A. find_element_by_idなどのfind_element(s)_by_*系メソッドはSelenium 4.3.0で削除されたためです。find_element(By.ID, "...")の形に書き換えてください。

Q. ChromeDriverはどこからダウンロードすればいいですか?

A. Selenium 4.6以降は「Selenium Manager」が自動でドライバを解決するため、手動ダウンロードは原則不要です。webdriver.Chrome(options=options)だけで動きます。

Q. headlessは"--headless"と"--headless=new"どちらを使うべき?

A. 2026年時点では--headless=newが推奨です。旧--headlessはレンダリング差異が出ることがあります。

参考

【Python】Seleniumを利用したスクレイピングでよく使うプログラムサンプル集
【Python】Seleniumを利用したスクレイピングでよく使うスプレッドシートのプログラムサンプル集

公式ドキュメント:
Selenium WebDriver DocumentationSelenium ManagerWaits

お問い合わせはこちら

下記フォームより直接ご相談・お問い合わせいただけます。
内容を確認のうえ、担当より折り返しご連絡いたします。

10文字以上4000文字以内でご記入ください。

プライバシーポリシーを読む