0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【selenium】pythonのseleniumを使いやすくするためのクラス作成

Posted at

はじめに

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コントローラー)が利用できるようであれば、ご利用ください。また、バグ、改善点などありましたら、フィードバックをお願いします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?