はじめに
selenium を使いやすくするためのクラス(Seleniumコントローラー)を作成してみました。
selenium の利用初心者です。試しに「Seleniumを使った楽天ウェブ検索での自動検索」を参考に自分のローカル環境で実行してみようと考えて、試行錯誤しました。
参考を作成された当時(2020年2月11日)と現状(2024年10月17日)にて、楽天ウェブの挙動やseleniumのAPIが変わっていたり、実はいろいろとお作法があるっぽので、以下の通り対応しました(対応中です)。
動作環境
VScode上のJuypiterNotebookで動作してます。下記の要件を満たせば、どこでも動作可能です。
- Python 3.12.1
- selenium 4.25.0
使用例:Pythonスクリプト
# seleniumコントローラー生成=ブラウザ開く
ctrller = selenimuContorller()
# 楽天ウェブ検索
ctrller.getUrl('https://websearch.rakuten.co.jp/')
ctrller.wait(5, By.LINK_TEXT, 'ログイン')
ctrller.click(By.LINK_TEXT, 'ログイン')
# ログインID入力
ctrller.wait(5, By.ID, 'user_id')
ctrller.send_keys(By.ID, 'user_id', RAKUTEN_ID) # 楽天IDで書き替えてください
ctrller.click(By.XPATH, '//div[contains(text(),"次へ")]')
# パスワード入力
ctrller.wait(5, By.ID, 'password_current')
ctrller.send_keys(By.ID, 'password_current', RAKUTEN_PASSWORD) # 楽天パスワードで書き替えてください
ctrller.click(By.XPATH, '//*[@id="cta011"]/div/div')
# 検索キーワード入力&検索
ctrller.wait(5, By.ID, 'search-input')
ctrller.send_keys(By.ID, 'search-input', '楽天')
ctrller.click(By.ID, 'search-submit')
# ブラウザ閉じる
ctrller.close()
※パスワード入力後の「次へ」の画面で許諾画面が挟まれることがあるが未対応
※ときどきハングしてだんまりになる。原因不明
使用例:実行結果
2024-10-17 11:56:00.184895 #1 [open] ブラウザを開きます。
2024-10-17 11:56:06.233262 #2 [get] [ https://websearch.rakuten.co.jp/ ]を表示します。
2024-10-17 11:56:08.783030 #3 [wait] 要素[link text,ログイン]の表示を最大[5]秒待ちます。
2024-10-17 11:56:08.842105 #4 [click] 要素[link text,ログイン]をクリックします。
2024-10-17 11:56:09.795556 #5 [wait] 要素[id,user_id]の表示を最大[5]秒待ちます。
2024-10-17 11:56:10.046632 #6 [send_keys] 要素[id,user_id]に[**********]を入力
2024-10-17 11:56:10.416637 #7 [click] 要素[xpath,//div[contains(text(),"次へ")]]をクリックします。
2024-10-17 11:56:10.536503 #8 [wait] 要素[id,password_current]の表示を最大[5]秒待ちます。
2024-10-17 11:56:11.108093 #9 [send_keys] 要素[id,password_current]に[**********]を入力
2024-10-17 11:56:11.309555 #10 [click] 要素[xpath,//*[@id="cta011"]/div/div]をクリックします。
2024-10-17 11:56:11.466136 #11 [wait] 要素[id,search-input]の表示を最大[5]秒待ちます。
2024-10-17 11:56:15.082618 #12 [send_keys] 要素[id,search-input]に[楽天]を入力
2024-10-17 11:56:15.953281 #13 [click] 要素[id,search-submit]をクリックします。
2024-10-17 11:56:18.050674 #14 [close] ブラウザを閉じます。
※「**********」は伏字にしています。
Seleniumコントローラー
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import datetime
class selenimuContorller():
driver = ""
actionCount = 0
def __init__(self):
self.log(f'[open] ブラウザを開きます。')
self.driver = webdriver.Chrome()
def getUrl(self, url):
self.log(f'[get] [ {url} ]を表示します。')
self.driver.get(url)
def close(self):
self.log(f'[close] ブラウザを閉じます。')
self.driver.close()
self.driver.quit()
def wait(self, waitTime, elementType, elementValue):
self.log(f'[wait] 要素[{elementType},{elementValue}]の表示を最大[{waitTime}]秒待ちます。')
wait = WebDriverWait(self.driver, waitTime)
element = ""
try:
element = wait.until(
EC.visibility_of_element_located(
(elementType, elementValue))
)
except TimeoutError as e:
self.errorlog(f'エラーが発生しました: {e}')
return element
def click(self, elementType, elementValue):
self.log(f'[click] 要素[{elementType},{elementValue}]をクリックします。')
if len(self.driver.find_elements(elementType, elementValue)) == 0:
self.errorlog(f'エラーが発生しました: 要素[{elementType},{elementValue}]がありません。')
return
try:
self.driver.find_element(elementType, elementValue).click()
except Exception as e:
# ToDo:このエラーを適切に表現すること←クリックできない要素のとき
self.errorlog(f'エラーが発生しました: {e}')
def send_keys(self, elementType, elementValue, sendValue):
self.log(f'[send_keys] 要素[{elementType},{elementValue}]に[{sendValue}]を入力します。')
if len(self.driver.find_elements(elementType, elementValue)) == 0:
self.errorlog(f"エラーが発生しました: 要素[{elementType},{elementValue}]がありません。")
return
self.driver.find_element(elementType, elementValue).send_keys(sendValue)
def log(self, logdata):
self.actionCount += 1
print(f'{datetime.datetime.now()} #{self.actionCount} {logdata}')
def errorlog(self, logdata):
print(f'{datetime.datetime.now()} {logdata}')
参考文献
おわりに
このクラス(Seleniumコントローラー)が利用できるようであれば、ご利用ください。また、バグ、改善点などありましたら、フィードバックをお願いします。