Selenium

Seleniumは各ブラウザに対応しますが、ここではGoogle Chromeを操作することを前提に解説します。

導入

C:\python -m pip install selenium
Install a Selenium library | Selenium
from selenium import webdriver

driver = webdriver.Chrome()      # Chromeが起動する
driver.get("http://example.com") # example.comが開く
driver.quit()                    # Chromeが閉じられる
The Selenium Browser Automation Project | Selenium

WebDriver

Selenium 4.6.0以降はSelenium Managerにより、必要なWebDriverが自動でインストーされます。Selenium 4.6.0 Released! | Selenium

その場所は%USERPROFILE%\.cache\seleniumになります。

ドライバのパスの指定を誤ると、「Unable to locate or obtain driver for chrome; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location」としてNoSuchDriverExceptionで失敗します。

ChromeDriver

Chrome for Testing availability

ChromeDriver とは何ですか?  |  Chrome for Developers

セッションの開始

セッションを開始や停止することは、ブラウザを開いたり閉じたりすることです。Driver Sessions | Selenium

セッションの作成

driver = webdriver.Chrome(options=options)

optionsで、ブラウザの動作を指定します。Browser Options | Selenium

セッションの放棄

driver.quit()

既存のブラウザに結びつける方法

セッションを開始するたびに新しいブラウザが開かずに、既に開かれているブラウザに結びつける方法を考えます。

そのためにはChromeを、ポート番号を指定して起動します。ポート転送でローカル サーバーと Chrome インスタンスにアクセスする  |  Chrome DevTools  |  Chrome for Developers

ポート番号には、9222などの使用可能な番号を指定します。 Step 2: Launch browser with options - How to connect Selenium to an existing browser that was opened manually? – CosmoCode (Formerly TeachMeSelenium) Chromium Blog: Remote debugging with Chrome Developer Tools

chrome.exe --remote-debugging-port=9222

プロファイルを分けたいならば、それも指定します。

chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\ChromeProfile"

セッションを作成するときにそのポート番号をオプションで、chromedriverのパスをサービスで指定します。

options = webdriver.ChromeOptions()
options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")

service = Service(executable_path="path/chromedriver.exe")

driver = webdriver.Chrome(options=options, service=service)
Can Selenium interact with an existing browser session? - Stack Overflow How to connect Selenium to an existing browser that was opened manually? – CosmoCode (Formerly TeachMeSelenium)

ブラウザごとの機能

Supported Browsers | Selenium

Google Chrome

Chrome specific functionality | Selenium

バイナリの指定

Chromiumを基にしたブラウザが複数インストールされているならば、それらを指定できます。

options.binary_location = chrome_bin
Start browser in a specified location - Chrome specific functionality | Selenium

ブラウザのナビゲーション

ページを開いたり、移動させたりできます。Browser navigation | Selenium

指定のページを開く

driver.get("http://example.com/index.html")

リンク先を開く

リンク先を開くには、その要素に対してclick()を呼びます。

element = driver.find_element(By.LINK_TEXT, "TEST")
element.click()

戻る

driver.back()

進む

driver.forward()

更新

driver.refresh()

ブラウザの情報

ウィンドウ ハンドルやブラウザのサイズや位置、それにCookieなどの情報を要求できます。Browser interactions | Selenium

待機

ページの要素を取得や操作するには、それが可能になるまで待機する必要がある場合があります。Waiting Strategies | Selenium

driver.implicitly_wait(0.5)

要素の検索

要素に関連する操作をするためには、まずその要素を見つける必要があります。Finding web elements | Selenium

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("http://example.com")

sample = driver.find_element(By.CLASS_NAME, "sample")

driver.quit()

Byには、下表の種類を指定できます。

定数 対象
ID id属性
XPATH XPath
LINK_TEXT リンクとして表示されているテキスト
PARTIAL_LINK_TEXT リンクとして表示されているテキストの一部
NAME name属性
TAG_NAME HTMLタグ名
CLASS_NAME クラス名
CSS_SELECTOR CSSセレクタ
Locator strategies | Selenium

XPathやCSSセレクタを用いれば、複雑な条件で一致させられます。

elements = driver.find_elements(By.XPATH, "//a[starts-with(@href, 'http://example.com/')]")

すべての要素の検索

find_element()では最初に一致した要素だけが返されるため、これをすべての要素とするには複数形のfind_elements()を用います。All matching elements - Finding web elements | Selenium

items = driver.find_elements(By.TAG_NAME, "li")

要素の操作

要素をクリックしたり、キーを送信したりできます。Interacting with web elements | Selenium

click()

要素をクリックできます。

check_input = driver.find_element(By.NAME, "checkbox_input")
check_input.click()

要素の情報の要求

要素の可視、有効、選択状態やタグ名などを取得できます。Information about web elements | Selenium

text

描画されているテキストを取得できます。Text Content - Information about web elements | Selenium

element.text

get_attribute()

要素の属性を取得できます。Fetching Attributes or Properties - Information about web elements | Selenium

element.get_attribute("href")

ファイル

Upload

アップロード ダイアログを操作することはできないため、ダイアログを開かずにアップロードする必要があります。たとえばtypeがfileであるinput要素にファイルのパスを入力し、送信をクリックします。File Upload | Selenium

Download

リンクをクリックすることでダウンロードを開始することはできますが、その進捗や、ダウンロードされたファイルを検証することはできません。よってその必要があるならば、リンクの情報を他のライブラリに渡して処理します。File downloads | Selenium

driver.find_element(By.TAG_NAME , "a").click()

ファイル名を指定してダウンロードすることはできないため、ダウンロードの完了を待ってからファイル名を変更します。python - Selenium give file name when downloading - Stack Overflow

ダウンロードの完了を待たずにブラウザを閉じるとファイルが不完全な状態となるため、それを待つか、ブラウザを閉じないようにします。

保存先は、ブラウザのオプションを指定することで変更できます。

prefs = {"download.default_directory" : r"C:\Downloads"}

options = webdriver.ChromeOptions()
options.add_experimental_option("prefs",prefs)

driver = webdriver.Chrome(options)
changing default download location in chrome using Python selenium - Stack Overflow

動作

キーボード

Keyboard actions | Selenium

マウス

Mouse actions | Selenium
複数の技術系サイトから、まとめて検索