この記事では、Seleniumを使ってWebブラウザを自動化する方法を解説します。
Selenium
を使うことでWebブラウザでの操作を自動化することができます。例えば、Google検索して表示されたサイトのリンクやタイトルなどを抽出したりすることができます。
それでは、Selenium
の使い方を見ていきましょう!
Selenium
はpip
でインストールすることができます。
pip install selenium
最初にブラウザを開いたり閉じたりするためのセッションを作成します。セッションは、Driver
オブジェクトを初期化することによって自動的に作成されます。
from selenium import webdriver
driver = webdriver.Chrome()
上記コードではChrome()
を使ってセッションを作成しましたが、他にもSafari()
やEdge()
、Firefox()
などのドライバーが用意されています。
driver = webdriver.Safari()
driver = webdriver.Edge()
driver = webdriver.Firefox()
エラーが発生してうまくいかない場合は以下のページを参考にしてください。
LinkUnable to Locate Driver Error | Selenium
ブラウザでの処理が終わったらセッションを終了しましょう。
driver.quit()
コンテキストマネージャーとして実行することもできます。
from selenium import webdriver
# セッションの開始(ドライバーの生成)
with webdriver.Chrome() as driver:
# 何らかの処理
任意のWebサイトを開くには、driver.get()
メソッドを使います。
driver.get(url: str)
例えば、Googleを開くには以下のようにします。
from selenium import webdriver
# セッションの開始(ドライバーの生成)
driver = webdriver.Chrome()
# Webサイトを開く
driver.get("https://google.com/")
# セッションの終了
driver.quit()
ブラウザから情報を取得したり、操作したりすることができます。
開いたブラウザでは以下のような操作が可能です。
# 戻る
driver.back()
# 進む
driver.forward()
# 更新
driver.refresh()
以下のようなプロパティからブラウザの情報を取得できます。
# タイトルの取得
driver.title
# URLの取得
driver.current_url
ドライバーはウィンドウとタブを区別しません。各ウィンドウにはユニークな識別子が付けられており、そのセッション内で永続的に保持されます。
ドライバーのcurrent_window_handle
から現在のウィンドウの識別子を取得できます。
window_handle = driver.current_window_handle
switch_to.window()
の引数に表示したいウィンドウ、またはタブの識別子を指定することでその画面に切り替えることができます。
driver.switch_to.window(window_handle)
new_window()
を使うことで新しいウィンドウ、またはタブを作成し、その画面に切り替えることができます。
# 新しいウィンドウを作成し、そのウィンドウに切り替える
driver.switch_to.new_window('window')
# 新しいタブを作成し、そのタブに切り替える
driver.switch_to.new_window('tab')
ウィンドウ、タブはclose()
で閉じることができます。
driver.close()
閉じたら元のウィンドウ、またはタブに切り替える必要がある。
from selenium import webdriver
# セッションの開始(ドライバーの生成)
with webdriver.Chrome() as driver:
# Webサイトを開く
driver.get("https://google.com/")
# 元の画面の識別子を保存しておく
window_handle = driver.current_window_handle
# 新しいタブの作成し、切り替える
driver.switch_to.new_window('tab')
# タブを閉じる
driver.close()
# 元のタブに切り替える
driver.switch_to.window(window_handle)
ウィンドウのサイズや位置を管理することができます。
ブラウザウィンドウのサイズをピクセル単位で取得します。
d = driver.get_window_size()
print(d)
# {'width': 1200, 'height': 637}
辞書として返されるのでキーを指定することでそれぞれの値にアクセスできます。
width = driver.get_window_size()['width']
# dict.get() でより安全
width = driver.get_window_size().get("width")
set_window_size()
にwidth
とheight
を指定することでウィンドウのサイズを変更できます。
driver.set_window_size(640, 480)
get_window_position()
でウィンドウの位置を取得できます。
pos = driver.get_window_position()
print(pos)
# {'x': 22, 'y': 47}
辞書として返されるのでキーを指定することでそれぞれの値にアクセスできます。
x = driver.get_window_position()['x']
# dict.get() でより安全
x = driver.get_window_position().get('x')
get_window_position()
で指定した位置にウィンドウを移動させることができます。
driver.set_window_position(0, 0)
maximize_window()
でウィンドウを最大化できます。
driver.maximize_window()
minimize_window()
でウィンドウを最小化できます。
driver.minimize_window()
fullscreen_window()
でウィンドウを全画面にすることができます。
driver.fullscreen_window()
画面を Base64 形式でエンコードされたスクリーンショットでキャプチャすることができます。
driver.save_screenshot('image.png')
任意の要素を検索して取得することができます。
引数で指定した条件に一致した最初の要素を取得するにはfind_element()
を使います。
def find_element(
by: str = By.ID,
value: str | None = None
) -> WebElement
by
引数はselenium.webdriver.common.by
のBy
クラスでロケーターを指定します。例えば、以下のような感じです。
from selenium import webdriver
from selenium.webdriver.common.by import By
# by引数にはデフォルトで By.ID が渡されているので id="abc" の最初の要素
driver.find_element(value="abc")
# class="abc" の最初の要素
driver.find_element(By.CLASS_NAME, "abc")
# name="abc" の最初の要素
driver.find_element(By.NAME, "abc")
# h2タグの最初の要素
driver.find_element(By.TAG_NAME, "h2")
また、取得した要素からさらに検索することも可能です。例えば以下のコードでは、メインコンテンツ内のclass="abc"
を検索します。
main = driver.find_element("main-contents")
abc = main.find_element(By.CLASS_NAME, "abc")
上記の方法だとfind_element()
を2度実行しなければならないが、CSSやXPathを使って以下のように指定することで一度で取得することができます。
driver.find_element(By.CSS_SELECTOR,"#main-contents .abc")
指定した条件に一致した全ての要素を取得するにはfind_elements()
を使います。
def find_elements(
by: str = By.ID,
value: str | None = None
) -> List[WebElement]
例えば、body内の全てのaタグを取得するには以下のようにします。
driver.find_elements(By.CSS_SELECTOR, "body a")
Webページ上の要素はすぐに利用できるものばかりとは限りません。読み込みに時間がかかったり、JavaScriptの処理が終わらないと使えない要素もあります。
そのような要素を取得するには待機を使う必要があります。
明示的な待機を実行するにはWebDriverWait
を使います。
from selenium.webdriver.support.wait import WebDriverWait
class WebDriverWait(
driver: Any,
timeout: float,
poll_frequency: float = POLL_FREQUENCY,
ignored_exceptions: WaitExcTypes | None = None
) -> None
条件はuntil()
を繋げて指定します。
WebDriverWait(driver, timeout=10).until(条件)
指定された条件が解決するまで、プログラムの実行を停止したり、スレッドをフリーズしたりすることができます。この条件はtimeout
引数に指定した秒数が経過するまで特定の頻度(poll_frequency
引数の値、デフォルトは0.5秒)で呼び出され、条件がfalse
を返す限り、試行と待機を繰り返します。
JavaScriptを同期実行し、ある変数の値がTrue
になるまで待機するには以下のようにします。
WebDriverWait(driver, timeout=10).until(lambda d: d.execute_script("return 変数名"))
他にも任意のタグが取得できるまで待機したりできます。
p = WebDriverWait(driver, timeout=3).until(lambda d: d.find_element(By.TAG_NAME,"p"))
暗黙的な待機を実行するにはドライバーのimplicitly_wait()
を使います。
def implicitly_wait(time_to_wait: float) -> None
暗黙的な待機は一定期間DOMをポーリングします。Webページ上の特定の要素がすぐには利用できず、読み込みに時間がかかる場合に使います。
from selenium import webdriver
from selenium.webdriver.common.by import By
# セッションの開始(ドライバーの生成)
with webdriver.Chrome() as driver:
# 暗黙的な待機
driver.implicitly_wait(10)
# Webサイトを開く
driver.get("https://google.com/")
# 要素の取得
q = driver.find_element(By.NAME, "q")
要素に対して様々なアクションを実行することができます。
要素をクリックするにはclick()
を使います。
WebElement.click()
例えば、a要素をクリックして他のページを開いたりできます。
from selenium import webdriver
from selenium.webdriver.common.by import By
# セッションの開始(ドライバーの生成)
with webdriver.Chrome() as driver:
# 暗黙的な待機
driver.implicitly_wait(0.5)
# Webサイトを開く
driver.get("https://google.com/")
driver.implicitly_wait(0.5)
# 現在のURL
print(driver.current_url)
# a要素を取得し、クリックする
a = driver.find_element(By.CLASS_NAME, "MV3Tnb")
a.click()
driver.implicitly_wait(0.5)
# 現在のURL
print(driver.current_url)
send_keys()
を使うことで指定されたキーを編集可能な要素に入力することができます。テキストフィールドとコンテンツ編集可能な要素にのみ適用されます。
WebElement.send_keys(*value: Any)
例えば、適当なことをGoogleで検索してみます。
from selenium import webdriver
from selenium.webdriver.common.by import By
# セッションの開始(ドライバーの生成)
with webdriver.Chrome() as driver:
# Webサイトを開く
driver.get("https://google.com/")
driver.implicitly_wait(0.5)
# テキストエリアの取得
textarea = driver.find_element(By.NAME, "q")
driver.implicitly_wait(0.5)
# テキストエリアに入力
textarea.send_keys("調べたいこと")
driver.implicitly_wait(0.5)
# 検索ボタンを検索してクリック
button = driver.find_element(By.NAME, "btnK")
button.click()
driver.implicitly_wait(0.5)
# 検索結果のタイトルを出力
for h3 in driver.find_elements(By.TAG_NAME, "h3"):
print(h3.text)
上記では検索ボタンをクリックしましたが、Enterキーで検索することもできます。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
# セッションの開始(ドライバーの生成)
with webdriver.Chrome() as driver:
# Webサイトを開く
driver.get("https://google.com/")
driver.implicitly_wait(0.5)
# テキストエリアの取得
textarea = driver.find_element(By.NAME, "q")
driver.implicitly_wait(0.5)
# テキストエリアに入力し、Enterキーを実行
textarea.send_keys("調べたいこと", Keys.ENTER)
driver.implicitly_wait(0.5)
# 検索結果のタイトルを出力
for h3 in driver.find_elements(By.TAG_NAME, "h3"):
print(h3.text)
clear()
を使うことで編集可能でリセット可能である要素の内容をクリアできます。
# テキストエリアの取得
textarea = driver.find_element(By.NAME, "q")
driver.implicitly_wait(0.5)
# テキストエリアに入力
textarea.send_keys("調べたいこと")
driver.implicitly_wait(0.5)
# テキストエリアをクリア
textarea.clear()
要素から様々な情報を取得することができます。
from selenium import webdriver
from selenium.webdriver.common.by import By
# セッションの開始(ドライバーの生成)
with webdriver.Chrome() as driver:
# Webサイトを開く
driver.get("https://google.com/")
driver.implicitly_wait(0.5)
# イメージの取得
img = driver.find_element(By.TAG_NAME, "img")
driver.implicitly_wait(0.5)
# 表示されているかどうか
img.is_displayed() # True
# 有効かどうか
img.is_enabled() # True
# 選択されているかどうか
img.is_selected() # False
# タグ名
img.tag_name # img
# サイズと位置
img.rect # {'height': 92, 'width': 272, 'x': 464, 'y': 60}
# テキストコンテンツ
img.text #
# CSS値の取得
img.value_of_css_property('height') # 92px
# 属性またはプロパティの取得
img.get_attribute("alt") # Google
この記事では、Seleniumを使ってWebブラウザを自動化する方法を解説しました。
Seleniumを使うことでWebブラウザで行う操作をプログラムにやらせることができました。もしWebブラウザで定期的に行う処理がある場合は作業を自動化すると楽です。
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ